为什么我在Generic.xaml中的样式不起作用?

时间:2012-02-23 04:04:17

标签: wpf styles app.xaml

我正在清理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>

这是我的Themes / 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不工作。

2 个答案:

答案 0 :(得分:3)

您需要将其合并到App.xaml中,如下所示:

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

如果您已经这样做,则需要发布代码以提供更多信息。

编辑: 请按照here的说明进行操作。特别是关于必须将您的词典设置为Resource并使用Source中的完整路径的部分。

答案 1 :(得分:0)

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

<ControlTemplate TargetType="{x:Type Button}">