I have an ItemsControl and want each item to set its color theme based on data it contains. I have 2 resource dictionaries for 2 possible themes (Red and Blue) and a DataTemplate that defines how to apply those colors. How do I assign current resource dictionary for each row?
<Window x:Class="WpfApplication1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApplication1"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<ResourceDictionary>
<!-- 2 dictionaries with style colors -->
<ResourceDictionary x:Key="RedStyle">
<SolidColorBrush x:Key="BorderBrush" Color="Red" />
<SolidColorBrush x:Key="TextBrush" Color="Red" />
</ResourceDictionary>
<ResourceDictionary x:Key="BlueStyle">
<SolidColorBrush x:Key="BorderBrush" Color="Blue" />
<SolidColorBrush x:Key="TextBrush" Color="Blue" />
</ResourceDictionary>
</ResourceDictionary>
</Window.Resources>
<Grid>
<ItemsControl ItemsSource="{Binding list}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Border BorderBrush="{StaticResource BorderBrush}">
<TextBlock Text="{Binding}" Foreground="TextBrush" />
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Grid>
</Window>
Update: The DataTemplate and brush sets are much larger in my real project. What I'm trying to do is to avoid duplicating DataTemplate layout code while still being able to have 2 different color styles on it.
Pertinent to your task, you can apply DataTriggers
like shown in the following example:
<ItemsControl.Style>
<Style>
<Style.Triggers>
<DataTrigger Binding="{Binding Items.TheAttribute}" Value="AttributeValue1">
<Setter Property="BorderBrush" Value="Red"/>
<Setter Property="TextBrush" Value="Red"/>
</DataTrigger>
<DataTrigger Binding="{Binding Items.TheAttribute}" Value="AttributeValue2">
<Setter Property="BorderBrush" Value="Blue"/>
<Setter Property="TextBrush" Value="Blue"/>
</DataTrigger>
</Style.Triggers>
</Style>
</ItemsControl.Style>
In this example, you do not need the Styles
specified in your ResourceDictionary
.
Alternatively, you can use <Style.Triggers>
to set the Style
per your ResourceDictionary
rather than setting the values of individual properties.
Hope this may help.
Note : You cannot apply ResourceDictionary conditionally, using Triggers.
You have four options at your disposable.
Put your DataTemplate
in single resource dictionary, or corresponding DataTemplate
s in separate dictionaries.
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:sys="clr-namespace:System;assembly=mscorlib"> <DataTemplate DataType="{x:Type sys:String}"> <TextBlock Text="{Binding .}"> <TextBlock.Style> <Style TargetType="TextBlock"> <Style.Triggers> <Trigger Property="Text" Value="Name1"> <Setter Property="Background" Value="Red"/> </Trigger> </Style.Triggers> </Style> </TextBlock.Style> </TextBlock> </DataTemplate> </ResourceDictionary>
Usage :
<ItemsControl.Resources> <ResourceDictionary Source="RedStyle.xaml"/> </ItemsControl.Resources>
Use DataTemplateSelector
to apply some complicated logic and assign DataTemplates
accordingly. There are good tutorials on net on this.
Use Blend Behaviors to do this using pure XAML.
Use Loaded
event of the control present in DataTemplate
to load Res Dictionary using code. Simplest approach !
<DataTemplate> <TextBlock Loaded="TextBlock_Loaded" Text="{Binding .}"/> </DataTemplate>
Code :
private void TextBlock_Loaded(object sender, RoutedEventArgs e) { TextBlock tb = sender as TextBlock; if (tb.Text == "Name123") tb.Resources.MergedDictionaries.Add(new ResourceDictionary() { Source = new Uri("RedStyle.xaml", UriKind.Relative) }); }
There is an AlternationCount:
<ItemsControl ItemsSource="{Binding List}"
AlternationCount="2"
HorizontalContentAlignment="Stretch">
plus:
<DataTemplate.Triggers>
<Trigger Property="ItemsControl.AlternationIndex" Value="0">
<Setter Property="Background" Value="White" TargetName="Grid" />
</Trigger>
<Trigger Property="ItemsControl.AlternationIndex" Value="1">
<Setter Property="Background" Value="#FFF1F1F1" TargetName="Grid" />
</Trigger>
</DataTemplate.Triggers>
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.