.NET4 WPF - 前台样式设置器仅在控件隐藏/显示后工作
我对名为 HeadText
且 TargetType = "TextBlock"
的某种 WPF 样式有问题。该样式定义了Foreground
、FontSize
和Effect
。第一次显示 TextBlock 时,仅不会触发 Foreground setter(文本颜色保持黑色),正常应用 FontSize 和 Effect。当我从父级中删除 TextBlock 并将其返回时,前景也会按应有的方式更改。
情况:
Presenter.dll 程序集
- 类
Presenter:Window
加载并显示我的用户控件。 Generic.xaml
- 包含样式的资源字典。Presenter.dll
不直接引用TestPresentable.dll
。
TestPresentable.dll 程序集
TestPresentable: UserControl
具有样式化的TextBlock
。TestPresentable.dll
不直接引用Presenter.dll
。
MainApp.exe
- 引用之前的两个程序集,
- 从
Presenter.dll
程序集实例化MainWindow
, - 从
TestPresentable
程序集实例化TestPresentable
, - 设置
MainWindow.ContentHost.Content = testPresentable
相关代码:
Presenter.dll
// Themes/Generic.xaml
...
<Style TargetType="{x:Type TextBlock}" x:Key="HeadText">
<Setter Property="Foreground" Value="#FFFFFFFF" />
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" Color="#79000000" BlurRadius="3" Opacity="1" />
</Setter.Value>
</Setter>
<Setter Property="FontSize" Value="24"/>
</Style>
...
// MainWindow.xaml
...
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Presenter.dll;component/Themes/Generic.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<ContentPresenter Name="ContentHost"/>
</Grid>
...
TestPresentable.dll
// TestPresentable.xaml
...
<TextBlock Text="{Binding SomeData}" Style="{DynamicResource HeadText}"/>
...
I have a problem with a certain WPF style called HeadText
with TargetType = "TextBlock"
. The style defines Foreground
, FontSize
and Effect
. The first time a TextBlock is shown only the Foreground setter is not fired (text color stays black), FontSize and Effect are applied normally. When I remove the TextBlock from parent and return it back, then the foreground is also changed as it should.
Situation:
Presenter.dll assembly
- class
Presenter: Window
, loads and displays my usercontrols. Generic.xaml
- Resource dictionary that contains styles.Presenter.dll
does not directly referenceTestPresentable.dll
.
TestPresentable.dll assembly
TestPresentable: UserControl
, has a styledTextBlock
.TestPresentable.dll
does not directly referencePresenter.dll
.
MainApp.exe
- references both previous assemblies,
- instantiates
MainWindow
fromPresenter.dll
assembly, - instantiates
TestPresentable
fromTestPresentable
assembly, - sets
MainWindow.ContentHost.Content = testPresentable
Relevant code:
Presenter.dll
// Themes/Generic.xaml
...
<Style TargetType="{x:Type TextBlock}" x:Key="HeadText">
<Setter Property="Foreground" Value="#FFFFFFFF" />
<Setter Property="Effect">
<Setter.Value>
<DropShadowEffect ShadowDepth="0" Color="#79000000" BlurRadius="3" Opacity="1" />
</Setter.Value>
</Setter>
<Setter Property="FontSize" Value="24"/>
</Style>
...
// MainWindow.xaml
...
<Window.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/Presenter.dll;component/Themes/Generic.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
<Grid>
<ContentPresenter Name="ContentHost"/>
</Grid>
...
TestPresentable.dll
// TestPresentable.xaml
...
<TextBlock Text="{Binding SomeData}" Style="{DynamicResource HeadText}"/>
...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
从 3.5 开始,WPF 中的 TextBlock.Foreground 似乎有些奇怪,请参阅:
我想出了一种使用 EventSetters 和一些方法的解决方法ResourceDictionary 的代码隐藏。它并不漂亮,但如果我想让我的样式独立于主应用程序,就必须这样做。我将其发布在这里,因为它可能对某人有用,如果有人发布正确(或更好)的答案,我将保持问题开放。
解决方法
在 ResorceDictionary XAML(例如 Generic.xaml)中添加一个 Class 属性,如下所示:
然后添加一个代码隐藏 cs 文件(例如 Generic.xaml.cs),其中包含您在 Class 属性中指定的部分类ResourceDictionary:
在ResourceDictionary的相关样式中为Loaded事件添加一个EventSetter:
在Generic.xaml.cs中为Loaded事件添加一个处理程序并设置所需的前景
It seems that there is something strange with TextBlock.Foreground in WPF since 3.5, see:
I've came up with a workaround using EventSetters and some codebehind for a ResourceDictionary. It's not pretty but will have to do if I want to have my styles independant of the main app. I'll post it here since it might be useful to someone and I'll keep the question open if someone post the right (or better) answer.
Workaround
In the ResorceDictionary XAML (e.g. Generic.xaml) add a Class property like so:
Then add a codebehind cs file (e.g. Generic.xaml.cs) with the partial class you specified in the Class property of the ResourceDictionary:
In the relevant style of the ResourceDictionary add an EventSetter for the Loaded event:
In the Generic.xaml.cs add a handler for the Loaded event and set the desired Foreground
我有一个类似的问题,第一次加载页面时前景色没有拉出来。我发现,在我的例子中,如果您在
TextBlock
所在的 xaml 文件中硬编码FontFamily
属性,那么前景色第一次就会正确地显示出来。但是,如果您只是将
FontFamily
属性放置在样式表中,那么TextBlock
第一次将再次显示为黑色。例如
I have a similar problem with the foreground colour not pulling through the first time the page loads. I've found that in my case if you hard code the
FontFamily
property in the xaml file where theTextBlock
is located, then the foreground colour pulls through correctly the first time.If you however just place the
FontFamily
property in the stylesheet, then theTextBlock
will again just be black first time.e.g.