In my WPF application, I have to keep on updating TextBlock background based on user conditions. TextBlock style is defined in App.xaml. If the background is too dark (Green/Blue) I want to set the foreground to white else black. How can I achieve this? I explored following two options:
Via DataTriggers: In App.xaml:
<Style TargetType="TextBlock"> <Setter Property="FontSize" Value="14"/> <Setter Property="FontStyle" Value="Normal"/> <Style.Triggers> <DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},Path=Background,PresentationTraceSources.TraceLevel=High}" Value="White"> <Setter Property="Foreground" Value="Maroon"/> </DataTrigger> </Style.Triggers> </Style>
This doesn't seem to work. I never see an update in textblock's foreground property. While debugging, I see the following for the binding: <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
System.Windows.Data Warning: 72 : RelativeSource.Self found TextBlock (hash=61003640) System.Windows.Data Warning: 78 : BindingExpression (hash=6398298): Activate with root item TextBlock (hash=61003640) System.Windows.Data Warning: 107 : BindingExpression (hash=6398298): At level 0 using cached accessor for TextBlock.Background: DependencyProperty(Background) System.Windows.Data Warning: 104 : BindingExpression (hash=6398298): Replace item at level 0 with TextBlock (hash=61003640), using accessor DependencyProperty(Background) System.Windows.Data Warning: 101 : BindingExpression (hash=6398298): GetValue at level 0 from TextBlock (hash=61003640) using DependencyProperty(Background): SolidColorBrush (hash=58614288) System.Windows.Data Warning: 80 : BindingExpression (hash=6398298): TransferValue - got raw value SolidColorBrush (hash=58614288) System.Windows.Data Warning: 89 : BindingExpression (hash=6398298): TransferValue - using final value SolidColorBrush (hash=58614288) <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
What is "SolidColorBrush (hash=58614288)"? Is it the Hex color code or hascode for the object of type SolidColorBrush?
- Using IValueConverter: Have not tried it since I don't want to convert one value to another but change a UIElement's property based on some other property change. Also, wouldn't converters will give a performance hit since almost all UIElements use TextBlock internally to display data?
I have already looked at the following thread: Change TextBlock foreground color based on the background. It didnt help my case. Any help is highly appreciated.
Thanks,
RDV
A little more about my application:
When my application starts, my TextBlocks have default background color. All the Textblock styling is stored in a ResourceDictionary which is stored in a different solution. I have only one ResourceDictionary in App.xaml of my application:
<Application x:Class="MySolution"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="pack://application:,,,/ResourcesSolution;component/Resources/GenericStyles.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
FontWeight, FontStyle, even Foreground etc. are correctly picked up from here. But these are static properties. On certain user action, I change the TextBlock's background color at runtime but sometimes that makes text unreadable like Black text on Green background. I can definitely bind the foreground color as well when background color is changing, but in that case I would have to do that binding in all the views. Instead I want to have a global style take care of this job so that even if I forget to bind the foreground color, correct color is automatically picked.
I have a big application and performance is a major concern. That's why I am hesitant to use converters and was looking for some xaml based solutions as this is just a condition based issue.