You might as well as I would suppose that if we just set the foreground of a window to something different from its original color, then the whole controls from the window might change as well?
well this is not true, consider this example.
<Window Foreground="Red"> <Label Content="Test"/> <Label Content="Test"/> <CheckBox Content="Checkbox"/> </Window>
the reason as pointed by Pavlo Glazkov is as such ...
Below is an example a typical logical tree of elements that shows how the value specified on the Window
level travels down the tree:
Window (Red [Local])
-> Grid (Red [Inherited])
-> ListBox (Red [Inherited])
-> ListBoxItem (Red [Inherited])
-> StackPanel (Red [Inherited])
-> Label (Black [Style])
-> TextBlock (Black [Inherited])
-> TextBlock (Red [Inherited])
In square brackets the source of the value is shown.
As you can see the inheritance breaks on theLabel
itself because it has theForeground
property set in its default style:
<Style x:Key="{x:Type Label}"
TargetType="{x:Type Label}">
<Setter Property="Foreground"
Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
...
</Style>
As a workaround for this we can use the following trick. Define the default style for such controls (as Label
) in the application (in App.xaml or in the Window
inself). And in that default style override the Foreground
property to set a relative source binding to the nearest ancestor of the control that still has the desired value:
<StyleTargetType="{x:Type Label}"><SetterProperty="Foreground"Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(TextElement.Foreground)}"/></Style><StyleTargetType="{x:Type CheckBox}"><SetterProperty="Foreground"Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(TextElement.Foreground)}"/></Style>
After that our tree will look like this:
Window(Red[Local])->Grid(Red[Inherited])->ListBox(Red[Inherited])->ListBoxItem(Red[Inherited])->StackPanel(Red[Inherited])->Label(Red[Binding to StackPanel.(TextElement.Foreground)])->TextBlock(Red[Inherited])->TextBlock(Red[Inherited])
As you can see, our binding restores the inheritance.
Such styles need to be defined for each element that overrides the Foreground
property in its style. As @Duane suggested, to not duplicate the binding in each style the BasedOn
capability can be used:
<Style x:Key="ForegroundInheritanceFixStyle"TargetType="Control"><SetterProperty="Foreground"Value="{Binding RelativeSource={RelativeSource AncestorType={x:Type FrameworkElement}}, Path=(TextElement.Foreground)}"/></Style><StyleTargetType="{x:Type Label}"BasedOn="{StaticResource ForegroundInheritanceFixStyle}"></Style><StyleTargetType="{x:Type CheckBox}"BasedOn="{StaticResource ForegroundInheritanceFixStyle}"></Style>
And because of this inheritance relationship, I found there is a problem when I tried to change the default settings for some data control, the change is not affected, it was because the container element is no modified for its fore/ground, background color.
so, e.g.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:dx="clr-namespace:DevExpress.Xpf.Core;assembly=DevExpress.Xpf.Core.v12.1" xmlns:vm="clr-namespace:RiskLayoutExample.ViewModels" xmlns:dxg="clr-namespace:DevExpress.Xpf.Grid;assembly=DevExpress.Xpf.Grid.v12.1" xmlns:dxdo="http://schemas.devexpress.com/winfx/2008/xaml/docking" > <DataTemplate DataType="{x:Type vm:RiskDataViewModel}"> <dx:BackgroundPanel> <DataGrid HorizontalAlignment="Stretch" VerticalAlignment="Stretch" ItemsSource="{Binding RiskData}" > <DataGrid.Resources> <Style TargetType="TextBlock" x:Key="{x:Type TextBlock}" > </Style> <Style TargetType="TextBoxBase" x:Key="{x:Type TextBoxBase}" > </Style> <Style TargetType="TextBox" x:Key="{x:Type TextBox}" /> <Style TargetType="DataGridCell" x:Key="{x:Type DataGridCell}"> </Style> <!-- .. --> </DataGrid.Resources> <DataGrid.Columns> <DataGridTextColumn Header="Book" Binding="{Binding Book}" IsReadOnly="True" > </DataGridTextColumn> <!-- ... --> </DataGrid.Columns> </DataGrid> </dx:BackgroundPanel> </DataTemplate> </ResourceDictionary>
the text color of the DataGridCell does not change, so I hvae to change the foreground and background of the dxd:BackgroundPanel
So I have to supply the color of the containing element.
<dx:BackgroundPanel Foreground="White" Background="Black"> </dx:BackgroundPanel>
相关推荐
gong-wpf-dragdrop, GongSolutions.WPF.DragDrop 库是WPF的拖动'n'拖放框架 简介GongSolutions.WPF.DragDrop 库是一个易于使用的拖拉'n'拖放框架。特性使用 MVVM: 拖放逻辑可以放在ViewModel中。 代码不需要放在in中...
c#-的WPF---MVVM例子,大家共同学习
一个简单的WPF程序
bootstrap-wpf-style-master 样式代码 。。。。。。。。
C#开发WPF-Silverlight动画及游戏系列教程-深蓝色右手 C#开发WPF-Silverlight动画及游戏系列教程-深蓝色右手 C#开发WPF-Silverlight动画及游戏系列教程-深蓝色右手
Prism-Samples-Wpf-master06-10的VS2017版本实现,下载手动重新安装一下nuget包即可,方便大家学习
wpf--ListBox分组-排序 wpf--ListBox分组-排序
我最近打算学习WPF ,在寻找MVVM框架的时候发现了PRISM,在此之前还从一些博客上了解了其它的MVVM框架,比如浅谈WPF中的MVVM框架--MVVMFoundation 中提到的MVVMFoundation,再比如 ViewModel从未如此清爽 - 轻量级...
wpf-wcf-wf整合开发实例--有利于理解wpf-wcf-wf的整合
WPF收集程序
WPF的基本空间历程,使用.net core3.0.1版本
WPF--Effect特效 对Effect的进行使用的小例子
wpf-datagrid-access DB,可以更新数据到Access数据库
wpf-资源的使用-resource
Wpf-图片放大缩小移动操作 Wpf-图片放大缩小移动操作
wpf charts源码,D源码,图书:practical-wpf-charts-graphics-master
WPF-MVVM WPF MVVM模式开发的例子程序
C#开发WPF-Silverlight动画及游戏系列教程-深蓝色右手 C#开发WPF-Silverlight动画及游戏系列教程-深蓝色右手 C#开发WPF-Silverlight动画及游戏系列教程-深蓝色右手
超酷WPF数据可视化,全套源程序,非常适合做数据可视化的程序员使用,WPF,XAML。 找了好久的资源,附有很多很详细的插图,是大数据时代不可缺少的可视化学习数据,仅供大家学习使用请勿用做商业用途。与大家一起...
WPF-MVVM实现CRUD操作