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.dlldoes not directly referenceTestPresentable.dll.
TestPresentable.dll assembly
TestPresentable: UserControl, has a styledTextBlock.TestPresentable.dlldoes not directly referencePresenter.dll.
MainApp.exe
- references both previous assemblies,
- instantiates
MainWindowfromPresenter.dllassembly, - instantiates
TestPresentablefromTestPresentableassembly, - 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}"/>
...
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