2

我正在清理 App.xaml 并将一些样式移到 Generic.xaml 中。但是,这些样式没有任何效果。为什么?这是使 App.xaml 整洁的正确做法吗?

编辑(包括一些源代码):

目标是重新设置 WPF DataGrid 的样式以使滚动条从上到下和从左到右运行(默认样式不包括行和列标题)。

当我把它放在 App.xaml 中时,这种风格就起作用了。因为它是一大块代码,我想将它从 App.xaml 移到 /Themes/DataGridEx.xaml 中。顺便说一句,DataGridEx 是我从 WPF DataGrid 派生的扩展类。

这是我的 DataGrid.xaml:

<ControlTemplate x:Key="SelectAllButtonTemplate" TargetType="{x:Type Button}">
    <Grid>
        <Rectangle x:Name="Border"
             Fill="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" 
             SnapsToDevicePixels="True" />
        <Polygon x:Name="Arrow"
           HorizontalAlignment="Right"
           VerticalAlignment="Bottom"
           Margin="8,8,3,3"
           Opacity="0.15"
           Fill="Black"
           Stretch="Uniform"
           Points="0,10 10,10 10,0" />
    </Grid>
    <ControlTemplate.Triggers>
        <Trigger Property="IsMouseOver" Value="True">
            <Setter TargetName="Border" Property="Stroke" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" />
        </Trigger>
        <Trigger Property="IsPressed" Value="True">
            <Setter TargetName="Border" Property="Fill" Value="{DynamicResource {x:Static SystemColors.ControlDarkBrushKey}}" />
        </Trigger>
        <Trigger Property="IsEnabled" Value="False">
            <Setter TargetName="Arrow" Property="Visibility" Value="Collapsed" />
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

<Style TargetType="{x:Type local:DataGridEx}" x:Key="{x:Type local:DataGridEx}">
    <Setter Property="Background"
            Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"/>
    <Setter Property="Foreground"
            Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
    <Setter Property="BorderBrush" Value="#FF688CAF" />
    <Setter Property="BorderThickness" Value="1" />
    <Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected" />
    <Setter Property="ScrollViewer.CanContentScroll"
            Value="true"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:DataGridEx}">
                <Border Background="{TemplateBinding Background}"
              BorderBrush="{TemplateBinding BorderBrush}"
              BorderThickness="{TemplateBinding BorderThickness}"
              SnapsToDevicePixels="True"
              Padding="{TemplateBinding Padding}">
                    <ScrollViewer   Focusable="false"
                        Name="DG_ScrollViewer">
                        <ScrollViewer.Template>
                            <ControlTemplate TargetType="{x:Type ScrollViewer}">
                                <Grid>
                                    <Grid.RowDefinitions>
                                        <RowDefinition Height="Auto"/>
                                        <RowDefinition Height="*"/>
                                        <RowDefinition Height="Auto"/>
                                    </Grid.RowDefinitions>

                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="*"/>
                                        <ColumnDefinition Width="Auto"/>
                                    </Grid.ColumnDefinitions>

                                    <!--Left Column Header Corner -->
                                    <Button Command="{x:Static local:DataGridEx.SelectAllCommand}"
                        Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:DataGridEx}}, Path=CellsPanelHorizontalOffset}"
                        Template="{StaticResource SelectAllButtonTemplate}"
                        Focusable="false"
                        Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:DataGridEx}}, Path=HeadersVisibility, Converter={x:Static local:DataGridEx.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.All}}" />
                                    <!--Column Headers-->
                                    <DataGridColumnHeadersPresenter Grid.Column="1" 
                                                   x:Name="PART_ColumnHeadersPresenter"
                                                   Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:DataGridEx}}, Path=HeadersVisibility, Converter={x:Static DataGrid.HeadersVisibilityConverter}, ConverterParameter={x:Static DataGridHeadersVisibility.Column}}"/>

                                    <!--DataGrid content-->
                                    <ScrollContentPresenter x:Name="PART_ScrollContentPresenter" Grid.Row="1" Grid.ColumnSpan="2" CanContentScroll="{TemplateBinding CanContentScroll}" />

                                    <!-- Changed Grid.Row="1" to Grid.Row="0" Grid.RowSpan="2" to make the scrollbar start from top -->
                                    <ScrollBar Grid.Row="0" Grid.RowSpan="2" Grid.Column="2" Name="PART_VerticalScrollBar"
                                         Orientation="Vertical"
                                         Maximum="{TemplateBinding ScrollableHeight}"
                                         ViewportSize="{TemplateBinding ViewportHeight}"
                                         Value="{Binding Path=VerticalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
                                         Visibility="{TemplateBinding ComputedVerticalScrollBarVisibility}"/>

                                    <!--Grid Grid.Row="2" Grid.Column="1">
                  <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="{Binding RelativeSource={RelativeSource AncestorType={x:Type dg:DataGrid}}, Path=NonFrozenColumnsViewportHorizontalOffset}"/>
                    <ColumnDefinition Width="*"/>
                  </Grid.ColumnDefinitions>
                  <ScrollBar Grid.Column="1"
                             Name="PART_HorizontalScrollBar"
                             Orientation="Horizontal"
                             Maximum="{TemplateBinding ScrollableWidth}"
                             ViewportSize="{TemplateBinding ViewportWidth}"
                             Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
                             Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>

                </Grid-->
                                    <!-- Make the scrollbar to start from left edge -->
                                    <ScrollBar Grid.Column="0" Grid.Row="2" Grid.ColumnSpan="2"
                                            Name="PART_HorizontalScrollBar"
                                            Orientation="Horizontal"
                                            Maximum="{TemplateBinding ScrollableWidth}"
                                            ViewportSize="{TemplateBinding ViewportWidth}"
                                            Value="{Binding Path=HorizontalOffset, RelativeSource={RelativeSource TemplatedParent}, Mode=OneWay}"
                                            Visibility="{TemplateBinding ComputedHorizontalScrollBarVisibility}"/>
                                </Grid>
                            </ControlTemplate>
                        </ScrollViewer.Template>
                        <ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                    </ScrollViewer>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsGrouping" Value="true">
            <Setter Property="ScrollViewer.CanContentScroll" Value="false"/>
        </Trigger>
    </Style.Triggers>
</Style>

这是我的主题/Generic.xaml:

<ResourceDictionary.MergedDictionaries>
    <ResourceDictionary Source="/Themes/DataGridEx.xaml"/>
    <ResourceDictionary Source="/Themes/GridComboBox.xaml"/>
</ResourceDictionary.MergedDictionaries>

这是我的 App.xaml:

    <Application x:Class="MyApp.App"
                 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                 xmlns:local="clr-namespace:MyApp.Common"
                 DispatcherUnhandledException="Application_DispatcherUnhandledException">
                 <!--StartupUri="MainWindow.xaml"-->
        <Application.Resources>
            <ResourceDictionary x:Key="rd">
                <ResourceDictionary.MergedDictionaries>
                    <ResourceDictionary Source="Themes/Generic.xaml"/>
                </ResourceDictionary.MergedDictionaries>
            </ResourceDictionary>
....
        </Application.Resources>
    </Application>

使用此代码,我得到了运行时 XamlParseException:“无法从文本 'local:DataGridEx' 创建 'Type'”。但是,如果我注释掉 App.xaml 中的 MergedDictionaries,它不会抱怨,但样式也不会生效。

另一个有趣的事情是,在这个 generic.xaml 中我有两个字典。如果我从 App.xaml 中删除 ResourceDictionary,GridComboBox.xaml 工作正常,但 DataGridEx.xaml 不是。

4

2 回答 2

3

You need to merge it into App.xaml like this:

<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="Generic.xaml"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

If you are already doing that, you need to post your code to give more info.

EDIT: Try following the instructions here. Particularly, the parts about having to set your dictionaries to Resource and using the full path in Source.

于 2012-02-23T04:15:28.650 回答
0

我遇到了这个问题,最简单的解决方法是删除要在 ResourceDictionary 中使用的样式的 x:Key 属性。

<ControlTemplate TargetType="{x:Type Button}">
于 2016-12-01T03:26:51.113 回答