当资源文件里改变了控件的样式时,在使用的地方如果想改变资源文件里修改的内容,会造成无法达到预期目的的结果。

以DataGrid为例,我在资源文件里,改变了默认的DataGrid的样式,其中我设置了IsReadOnly为True。在使用时,这将导致DataGrid的列不能编辑;可实际情况要求编辑功能,我们就会想到针对列设置IsReadOnly为false。

如代码里的注释掉的内容所示,在简单地引用资源文件,而不做处理时,是无法达到预期的。

正确的做法是:

引入通过引入新的Style,在Style的Setter里设置,来override资源文件里的设置;这样再针对每个列单独设置IsReadOnly就会起作用。

其中的原理还没有太明白,仅仅记录下处理方法。

界面

 <Window x:Class="learnwpf.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" WindowStartupLocation="CenterScreen">
<Grid>
<DataGrid x:Name="dg" AutoGenerateColumns="False"
CanUserAddRows="False" CanUserDeleteRows="False" CanUserReorderColumns="False"
CanUserResizeColumns="False" CanUserResizeRows="False" CanUserSortColumns="False">
<!--以下这样的字典引用方式,将导致即使在DataGridTextColumn里设置IsReadOnly为false仍旧不能编辑-->
<!--<DataGrid.Resources>
<ResourceDictionary Source="newlook/DataGrid.xaml" />
</DataGrid.Resources>-->
<!--解决办法如下,注意x:key的使用-->
<DataGrid.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="newlook/DataGrid.xaml" />
<ResourceDictionary>
<Style TargetType="DataGrid">
<Setter Property="IsReadOnly" Value="False" />
</Style>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</DataGrid.Resources>
<DataGrid.Columns>
<DataGridTextColumn x:Name="text" Header="文本" Binding="{Binding Name,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" IsReadOnly="True" />
<DataGridTextColumn x:Name="combo" Header="选择" Binding="{Binding Class,UpdateSourceTrigger=PropertyChanged,Mode=TwoWay}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>

资源文件

 <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> <SolidColorBrush x:Key="GridHeaderForeground" Color="#333"/>
<SolidColorBrush x:Key="GridHeaderLineBrush" Color="#FFCCCEDB"/>
<SolidColorBrush x:Key="GridHeaderBackgroudBrush" Color="#FFE3E3E3"/>
<SolidColorBrush x:Key="GridLineBrush" Color="#FFEFEFF2"/>
<SolidColorBrush x:Key="GridDrakRow" Color="#FFF9F9F9"/>
<SolidColorBrush x:Key="GridBorderBrush" Color="#FFCCCEDB"/> <Style x:Key="ColumnHeaderGripperStyle" TargetType="{x:Type Thumb}">
<Setter Property="Width" Value="3" />
<Setter Property="Background" Value="Transparent" />
<Setter Property="Cursor" Value="SizeWE" />
<Setter Property="Opacity" Value="0" />
</Style> <Style TargetType="DataGrid">
<Setter Property="Margin" Value="0"/>
<Setter Property="CanUserResizeColumns" Value="True"/>
<Setter Property="CanUserSortColumns" Value="False"/>
<Setter Property="AutoGenerateColumns" Value="False"/>
<Setter Property="CanUserResizeRows" Value="False"/>
<Setter Property="SelectionMode" Value="Single"/>
<Setter Property="RowHeaderWidth" Value="0"/>
<Setter Property="CanUserAddRows" Value="False"/>
<Setter Property="CanUserDeleteRows" Value="False"/>
<Setter Property="IsReadOnly" Value="True"/>
<Setter Property="Background" Value="AliceBlue" />
<Setter Property="AlternationCount" Value="2" />
<Setter Property="ClipToBounds" Value="True" />
<Setter Property="BorderBrush" Value="{DynamicResource GridBorderBrush}" />
<Setter Property="HorizontalGridLinesBrush" Value="{DynamicResource GridLineBrush}"/>
<Setter Property="VerticalGridLinesBrush" Value="{DynamicResource GridLineBrush}"/>
</Style> <Style TargetType="DataGridColumnHeader">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Foreground" Value="{DynamicResource GridHeaderForeground}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGridColumnHeader">
<Border x:Name="BackgroundBorder" BorderThickness="1,0,1,1"
Margin="-1,0,0,0"
Background="{DynamicResource GridHeaderBackgroudBrush}"
BorderBrush="{DynamicResource GridHeaderLineBrush}" Width="Auto">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<ContentPresenter Margin="0,0,0,0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Thumb x:Name="PART_LeftHeaderGripper" HorizontalAlignment="Left" Style="{StaticResource ColumnHeaderGripperStyle}" />
<Thumb x:Name="PART_RightHeaderGripper" HorizontalAlignment="Right" Style="{StaticResource ColumnHeaderGripperStyle}" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Setter Property="Height" Value="25"/>
</Style> <Style TargetType="{x:Type DataGridRow}">
<Setter Property="Background" Value="Beige" />
<Setter Property="SnapsToDevicePixels" Value="true" />
<Setter Property="Height" Value="24" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type DataGridRow}">
<Border x:Name="DGR_Border" SnapsToDevicePixels="True">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Unfocused_Selected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{DynamicResource CtrlSelectedUnFocusBG}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Normal_AlternatingRow">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{StaticResource GridDrakRow}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="MouseOver">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{DynamicResource CtrlMouseOverBG}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Normal_Selected">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="DGR_Border" Storyboard.TargetProperty="Background">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{DynamicResource CtrlSelectedBG}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<SelectiveScrollingGrid>
<SelectiveScrollingGrid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</SelectiveScrollingGrid.ColumnDefinitions>
<SelectiveScrollingGrid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</SelectiveScrollingGrid.RowDefinitions>
<DataGridCellsPresenter Grid.Column="1"
ItemsPanel="{TemplateBinding ItemsPanel}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
<DataGridDetailsPresenter Grid.Column="1"
Grid.Row="1"
Visibility="{TemplateBinding DetailsVisibility}"
SelectiveScrollingGrid.SelectiveScrollingOrientation=
"{Binding AreRowDetailsFrozen,
ConverterParameter={x:Static SelectiveScrollingOrientation.Vertical},
Converter={x:Static DataGrid.RowDetailsScrollingConverter},
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}"/>
<DataGridRowHeader Grid.RowSpan="2"
SelectiveScrollingGrid.SelectiveScrollingOrientation="Vertical"
Visibility="{Binding HeadersVisibility,
ConverterParameter={x:Static DataGridHeadersVisibility.Row},
Converter={x:Static DataGrid.HeadersVisibilityConverter},
RelativeSource={RelativeSource AncestorType={x:Type DataGrid}}}" />
</SelectiveScrollingGrid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Foreground" Value="Black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style> </ResourceDictionary>

逻辑

 using System.Collections.Generic;
using System.Windows; namespace learnwpf
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
init();
} private class TestData
{
public string Name { get; set; }
public string Class { get; set; }
} private void init()
{
List<TestData> data = new List<TestData>()
{
new TestData(){Name="first",Class=""},
new TestData(){Name="secon",Class=""},
};
dg.ItemsSource = data;
}
}
}

WPF中override ResourceDictionary中的设置的方法的更多相关文章

  1. WPF中,如何将绑定源设置到单件实例

    原文:WPF中,如何将绑定源设置到单件实例  WPF中,如何将绑定源设置到单件实例                                       周银辉 大概两个月前,曾有位朋友问我:如 ...

  2. WPF 3D中多个模型如何设置某一个在最前?

    原文:WPF 3D中多个模型如何设置某一个在最前? 问题:我们的模型包括导入的3D solid模型和axis坐标轴模型,当模型旋转的时候,3D会将axis挡住. 期望:axis一直在最前面,不会被3D ...

  3. MyBatis中关于别名typeAliases的设置

    第一种:通过在配置文件中typeAlias节点设置type的方式 <?xml version="1.0" encoding="UTF-8" ?> & ...

  4. listview当选中某一个item时设置背景色其他的不变

    listview当选中某一个item时设置背景色其他的不变: 可以使用listview.setOnFoucsChangeListener(listener) ; /** * listview获得焦点和 ...

  5. WPF Event 在 Command 中的应用初级篇,支持所有Event 展示松耦合设计的全部代码 - 解决TextBoxBase.TextChanged或者TextBox.TextChanged等类似事件绑定问题。

    做过WPF开发的人,都知道做MVVM架构,最麻烦的是Event的绑定,因为Event是不能被绑定的,同时现有的条件下,命令是无法替代Event.而在开发过程中无法避免Event事件,这样MVVM的架构 ...

  6. WPF: 在 MVVM 设计中实现对 ListViewItem 双击事件的响应

    ListView 控件最常用的事件是 SelectionChanged:如果采用 MVVM 模式来设计 WPF 应用,通常,我们可以使用行为(如 InvokeCommandAction)并结合命令来实 ...

  7. WPF编程,TextBlock中的文字修饰线(上划线,中划线,基线与下划线)的使用方法。

    原文:WPF编程,TextBlock中的文字修饰线(上划线,中划线,基线与下划线)的使用方法. 版权声明:我不生产代码,我只是代码的搬运工. https://blog.csdn.net/qq_4330 ...

  8. WPF实用指南一:在WPF窗体的边框中添加搜索框和按钮

    原文:WPF实用指南一:在WPF窗体的边框中添加搜索框和按钮 在边框中加入一些元素,在应用程序的界面设计中,已经开始流行起来.特别是在浏览器(Crome,IE,Firefox,Opera)中都有应用. ...

  9. WPF控件TextBlock中文字自动换行

    原文:WPF控件TextBlock中文字自动换行 在很多的WPF项目中,往往为了追求界面的美观,需要控制控件中文字的换行显示,现对TextBlock控件换行的实现方式进行总结,希望大家多多拍砖!!! ...

随机推荐

  1. 使用MVC4,Ninject,EF,Moq,构建一个真实的应用电子商务SportsStore

    05 2013 档案 使用MVC4,Ninject,EF,Moq,构建一个真实的应用电子商务SportsStore(一) 摘要: 完成SportsStore电子商务平台,你将学会: 1.使用MVC4开 ...

  2. C#socket通信1

    .net平台下C#socket通信(上) 完全是基础,新手可以随意看看,大牛可以关闭浏览页了,哈哈. 在开始介绍socket前先补充补充基础知识,在此基础上理解网络通信才会顺理成章,当然有基础的可以跳 ...

  3. Area 使用

    [ASP.NET MVC 小牛之路]08 - Area 使用 ASP.NET MVC允许使用 Area(区域)来组织Web应用程序,每个Area代表应用程序的不同功能模块.这对于大的工程非常有用,Ar ...

  4. C#:.net/方法/字符串/数组

    C#:.net/方法/字符串/数组,那点事 首先还是先说下(几个概念的东西)c#下的.net平台的构造快及其功能作用和程序集: .net: .net平台是由:a:运行库+b:全面基础类库(这个是从程序 ...

  5. 关于在Java EE 下开发web,出现项目中的外部包没有tomcat的包的原因

    在新建的项目的时候,要设置目标服务器运行环境,把那个设置成tomcat,这样,项目中就会有tomca的api

  6. Rustlang语言逐行处理文件的基本方法

    文件操作 需求: 将文件中的内容按行读取出来,然后对改行的数据进行处理,最后将处理后的行数据存放到新的文件中. 使用RUST来处理的方法如下. 首先引入需要的标准库: use std::io::pre ...

  7. Linux操作系统学习_用户态与内核态之切换过程

    因为操作系统的很多操作会消耗系统的物理资源,例如创建一个新进程时,要做很多底层的细致工作,如分配物理内存,从父进程拷贝相关信息,拷贝设置页目录.页表等,这些操作显然不能随便让任何程序都可以做,于是就产 ...

  8. 一步一步深入spring(5)--使用基于注解的spring实现 AOP

    1.要利用spring aop,至少需要添加以下jar包 使用spring需要的jarspring.jar .commons-logging.jar 使用切面编程(AOP)需要的jar aspectj ...

  9. C#实现eval

    C#实现eval 进行四则运算(有码)   在JavaScript中实现四则运算很简单,只需要调用eval函数就行了,但是不知道什么原因万能的.NET却没有封装这个函数~ 在这里为大家封装了一个C#版 ...

  10. activity的android:name所指的Activity实现类的简写问题

    <manifest xmlns:android="http://schemas.android.com/apk/res/android"     package=" ...