当资源文件里改变了控件的样式时,在使用的地方如果想改变资源文件里修改的内容,会造成无法达到预期目的的结果。
以DataGrid为例,我在资源文件里,改变了默认的DataGrid的样式,其中我设置了IsReadOnly为True。在使用时,这将导致DataGrid的列不能编辑;可实际情况要求编辑功能,我们就会想到针对列设置IsReadOnly为false。
如代码里的注释掉的内容所示,在简单地引用资源文件,而不做处理时,是无法达到预期的。
正确的做法是:
引入通过引入新的Style,在Style的Setter里设置,来override资源文件里的设置;这样再针对每个列单独设置IsReadOnly就会起作用。
其中的原理还没有太明白,仅仅记录下处理方法。
界面
1 <Window x:Class="learnwpf.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 Title="MainWindow" Height="350" Width="525" WindowStartupLocation="CenterScreen"> 5 <Grid> 6 <DataGrid x:Name="dg" AutoGenerateColumns="False" 7 CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False" 8 CanUserResizeColumns="False" CanUserResizeRows="False" CanUserSortColumns="False"> 9 <!--以下这样的字典引用方式,将导致即使在DataGridTextColumn里设置IsReadOnly为false仍旧不能编辑--> 10 <!--<DataGrid.Resources> 11 <ResourceDictionary Source="newlook/DataGrid.xaml" /> 12 </DataGrid.Resources>--> 13 <!--解决办法如下,注意x:key的使用--> 14 <DataGrid.Resources> 15 <ResourceDictionary> 16 <ResourceDictionary.MergedDictionaries> 17 <ResourceDictionary Source="newlook/DataGrid.xaml" /> 18 <ResourceDictionary> 19 <Style TargetType="DataGrid"> 20 <Setter Property="IsReadOnly" Value="False" /> 21 </Style> 22 </ResourceDictionary> 23 </ResourceDictionary.MergedDictionaries> 24 </ResourceDictionary> 25 </DataGrid.Resources> 26 <DataGrid.Columns> 27 <DataGridTextColumn x:Name="text" Header="文本" Binding="{Binding Name,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" IsReadOnly="True" /> 28 <DataGridTextColumn x:Name="combo" Header="选择" Binding="{Binding Class,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" /> 29 </DataGrid.Columns> 30 </DataGrid> 31 </Grid> 32 </Window>
资源文件
1 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 2 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 3 4 <SolidColorBrush x:Key="GridHeaderForeground" Color="#333"/> 5 <SolidColorBrush x:Key="GridHeaderLineBrush" Color="#FFCCCEDB"/> 6 <SolidColorBrush x:Key="GridHeaderBackgroudBrush" Color="#FFE3E3E3"/> 7 <SolidColorBrush x:Key="GridLineBrush" Color="#FFEFEFF2"/> 8 <SolidColorBrush x:Key="GridDrakRow" Color="#FFF9F9F9"/> 9 <SolidColorBrush x:Key="GridBorderBrush" Color="#FFCCCEDB"/> 10 11 <Style x:Key="ColumnHeaderGripperStyle" TargetType="{x:Type Thumb}"> 12 <Setter Property="Width" Value="3" /> 13 <Setter Property="Background" Value="Transparent" /> 14 <Setter Property="Cursor" Value="SizeWE" /> 15 <Setter Property="Opacity" Value="0" /> 16 </Style> 17 18 <Style TargetType="DataGrid"> 19 <Setter Property="Margin" Value="0"/> 20 <Setter Property="CanUserResizeColumns" Value="True"/> 21 <Setter Property="CanUserSortColumns" Value="False"/> 22 <Setter Property="AutoGenerateColumns" Value="False"/> 23 <Setter Property="CanUserResizeRows" Value="False"/> 24 <Setter Property="SelectionMode" Value="Single"/> 25 <Setter Property="RowHeaderWidth" Value="0"/> 26 <Setter Property="CanUserAddRows" Value="False"/> 27 <Setter Property="CanUserDeleteRows" Value="False"/> 28 <Setter Property="IsReadOnly" Value="True"/> 29 <Setter Property="Background" Value="AliceBlue" /> 30 <Setter Property="AlternationCount" Value="2" /> 31 <Setter Property="ClipToBounds" Value="True" /> 32 <Setter Property="BorderBrush" Value="{DynamicResource GridBorderBrush}" /> 33 <Setter Property="HorizontalGridLinesBrush" Value="{DynamicResource GridLineBrush}"/> 34 <Setter Property="VerticalGridLinesBrush" Value="{DynamicResource GridLineBrush}"/> 35 </Style> 36 37 <Style TargetType="DataGridColumnHeader"> 38 <Setter Property="SnapsToDevicePixels" Value="True" /> 39 <Setter Property="Foreground" Value="{DynamicResource GridHeaderForeground}" /> 40 <Setter Property="Template"> 41 <Setter.Value> 42 <ControlTemplate TargetType="DataGridColumnHeader"> 43 <Border x:Name="BackgroundBorder" BorderThickness="1,0,1,1" 44 Margin="-1,0,0,0" 45 Background="{DynamicResource GridHeaderBackgroudBrush}" 46 BorderBrush="{DynamicResource GridHeaderLineBrush}" Width="Auto"> 47 <Grid> 48 <Grid.ColumnDefinitions> 49 <ColumnDefinition Width="*" /> 50 </Grid.ColumnDefinitions> 51 <ContentPresenter Margin="0,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Center"/> 52 <Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ColumnHeaderGripperStyle}" /> 53 <Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" Style="{StaticResource ColumnHeaderGripperStyle}" /> 54 </Grid> 55 </Border> 56 </ControlTemplate> 57 </Setter.Value> 58 </Setter> 59 <Setter Property="Height" Value="25"/> 60 </Style> 61 62 <Style TargetType="{x:Type DataGridRow}"> 63 <Setter Property="Background" Value="Beige" /> 64 <Setter Property="SnapsToDevicePixels" Value="true" /> 65 <Setter Property="Height" Value="24" /> 66 <Setter Property="Template"> 67 <Setter.Value> 68 <ControlTemplate TargetType="{x:Type DataGridRow}"> 69 <Border x:Name="DGR_Border" SnapsToDevicePixels="True"> 70 <VisualStateManager.VisualStateGroups> 71 <VisualStateGroup x:Name="CommonStates"> 72 <VisualState x:Name="Normal" /> 73 <VisualState x:Name="Unfocused_Selected"> 74 <Storyboard> 75 <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border" Storyboard.TargetProperty="Background"> 76 <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{DynamicResource CtrlSelectedUnFocusBG}" /> 77 </ObjectAnimationUsingKeyFrames> 78 </Storyboard> 79 </VisualState> 80 <VisualState x:Name="Normal_AlternatingRow"> 81 <Storyboard> 82 <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border" Storyboard.TargetProperty="Background"> 83 <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{StaticResource GridDrakRow}" /> 84 </ObjectAnimationUsingKeyFrames> 85 </Storyboard> 86 </VisualState> 87 <VisualState x:Name="MouseOver"> 88 <Storyboard> 89 <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border" Storyboard.TargetProperty="Background"> 90 <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{DynamicResource CtrlMouseOverBG}" /> 91 </ObjectAnimationUsingKeyFrames> 92 </Storyboard> 93 </VisualState> 94 <VisualState x:Name="Normal_Selected"> 95 <Storyboard> 96 <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border" Storyboard.TargetProperty="Background"> 97 <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{DynamicResource CtrlSelectedBG}" /> 98 </ObjectAnimationUsingKeyFrames> 99 </Storyboard> 100 </VisualState> 101 </VisualStateGroup> 102 </VisualStateManager.VisualStateGroups> 103 <SelectiveScrollingGrid> 104 <SelectiveScrollingGrid.ColumnDefinitions> 105 <ColumnDefinition Width="Auto" /> 106 <ColumnDefinition Width="*" /> 107 </SelectiveScrollingGrid.ColumnDefinitions> 108 <SelectiveScrollingGrid.RowDefinitions> 109 <RowDefinition Height="*" /> 110 <RowDefinition Height="Auto" /> 111 </SelectiveScrollingGrid.RowDefinitions> 112 <DataGridCellsPresenter Grid.Column="1" 113 ItemsPanel="{TemplateBinding ItemsPanel}" 114 SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> 115 <DataGridDetailsPresenter Grid.Column="1" 116 Grid.Row="1" 117 Visibility="{TemplateBinding DetailsVisibility}" 118 SelectiveScrollingGrid.SelectiveScrollingOrientation= 119 "{Binding AreRowDetailsFrozen, 120 ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical}, 121 Converter={x:Static DataGrid.RowDetailsScrollingConverter}, 122 RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/> 123 <DataGridRowHeader Grid.RowSpan="2" 124 SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical" 125 Visibility="{Binding HeadersVisibility, 126 ConverterParameter={x:Static DataGridHeadersVisibility.Row}, 127 Converter={x:Static DataGrid.HeadersVisibilityConverter}, 128 RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" /> 129 </SelectiveScrollingGrid> 130 </Border> 131 <ControlTemplate.Triggers> 132 <Trigger Property="IsSelected" Value="True"> 133 <Setter Property="Foreground" Value="Black" /> 134 </Trigger> 135 </ControlTemplate.Triggers> 136 </ControlTemplate> 137 </Setter.Value> 138 </Setter> 139 </Style> 140 141 </ResourceDictionary>
逻辑
1 using System.Collections.Generic; 2 using System.Windows; 3 4 namespace learnwpf 5 { 6 /// <summary> 7 /// Interaction logic for MainWindow.xaml 8 /// </summary> 9 public partial class MainWindow : Window 10 { 11 public MainWindow() 12 { 13 InitializeComponent(); 14 init(); 15 } 16 17 private class TestData 18 { 19 public string Name { get; set; } 20 public string Class { get; set; } 21 } 22 23 private void init() 24 { 25 List<TestData> data = new List<TestData>() 26 { 27 new TestData(){Name="first",Class="10"}, 28 new TestData(){Name="secon",Class="15"}, 29 }; 30 dg.ItemsSource = data; 31 } 32 } 33 }