如何将不同的颜色集应用于ItemsControl中的每个项目?

时间:2016-03-04 22:26:26

标签: c# wpf colors itemscontrol

我有一个ItemsControl,希望每个项目根据它包含的数据设置颜色主题。我有两个可能的主题(红色和蓝色)的2个资源字典和一个定义如何应用这些颜色的DataTemplate。如何为每一行分配当前资源字典?

<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>

更新:在我的真实项目中,DataTemplate和画笔集要大得多。我想要做的是避免重复DataTemplate布局代码,同时仍然可以有2种不同的颜色样式。

3 个答案:

答案 0 :(得分:0)

与您的任务相关,您可以应用DataTriggers,如以下示例所示:

<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>

在此示例中,您不需要Styles中指定的ResourceDictionary

或者,您可以使用<Style.Triggers>Style设置ResourceDictionary,而不是设置各个属性的值。

希望这可能会有所帮助。

答案 1 :(得分:0)

注意:您无法使用触发器有条件地应用ResourceDictionary。

您的一次性用品有四种选择。

  1. 将您的DataTemplate放入单个资源字典中,或将相应的DataTemplate放入单独的字典中。

    <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>
    

    用法:

       <ItemsControl.Resources>            
                <ResourceDictionary Source="RedStyle.xaml"/>
       </ItemsControl.Resources>            
    
  2. 使用DataTemplateSelector应用一些复杂的逻辑并相应地指定DataTemplates。网上有很好的tutorials

  3. 使用混合行为使用纯XAML执行此操作。

  4. 使用Loaded中存在的控件的DataTemplate事件来使用代码加载Res Dictionary。最简单的方法!

            <DataTemplate>
                <TextBlock Loaded="TextBlock_Loaded" Text="{Binding .}"/>
            </DataTemplate>
    

    代码:

        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) });
        }
    

答案 2 :(得分:0)

有一个AlternateCount:

<ItemsControl  ItemsSource="{Binding List}"
                  AlternationCount="2"
                  HorizontalContentAlignment="Stretch">

加号:

<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>