【问题标题】:How do I change the background color of a cell using WPF Toolkit Datagrid如何使用 WPF Toolkit Datagrid 更改单元格的背景颜色
【发布时间】:2010-12-17 05:43:01
【问题描述】:

我正在使用 WPF 工具包数据网格,我想根据单元格的内容设置单元格的背景颜色,而不是行的背景颜色。

为了简单起见,假设列名为 Foo,我希望单元格的背景在 Foo 为 1 时为蓝色,在 Foo 为 2 时为红色,在 Foo 为 3 时为黄色,当 Foo 为绿色时大于 3。

如果我能做到这一点,我很确定我可以解决我需要处理的任何更复杂的案例。

【问题讨论】:

    标签: wpf datagrid background wpftoolkit


    【解决方案1】:

    执行此操作的方法之一是为列定义 ElementStyle,然后将文本块背景绑定到数据网格行后面的数据元素的颜色属性。这是一个例子:

    DataGridTextColumn xaml:

    <DataGridTextColumn Width="SizeToCells"   
                           MinWidth="150" 
                           Binding="{Binding Name}">
    
        <DataGridTextColumn.ElementStyle>
            <Style TargetType="{x:Type TextBlock}">
                <Setter Property="TextBlock.Background" Value="{Binding Color}" />
            </Style>
        </DataGridTextColumn.ElementStyle>
    </DataGridTextColumn>
    

    数据项声明:

    public class TestItem
    {
        public TestItem(int foo)
        {
            Foo = foo;
        }
    
        public int Foo { get; set; }
        public Brush Color
        {
            get
            {
                Color color = Colors.Green;
                switch (Foo)
                {
                    case 1: color = Colors.Red; break;
                    case 2: color = Colors.Yellow; break; 
                }
                return new SolidColorBrush(color);
            }
        }
    }
    

    希望这会有所帮助,问候

    【讨论】:

    • 如果 Foo 的值在网格显示后发生变化,这将不起作用:单元格颜色不会更新。有关详细信息,请参阅我的答案。
    • 在显示网格时,如果 Foo 发生变化(例如,由于数据绑定),也不会发生变化。
    • 它已经很老了,但你需要修复它是通过类 TestItem 实现 INotifyPropertyChanged,以通知 UI 颜色变化。
    【解决方案2】:

    您可以使用样式和数据触发器来执行此操作。只需使用默认背景属性设置 ElementStyle,在本例中为绿色,并为其他情况添加 DataTriggers:

    <DataGridTextColumn Binding="{Binding WhateverIWantToDisplay}" >
      <DataGridTextColumn.ElementStyle>
        <Style TargetType="{x:Type TextBlock}">
    
          <Setter Property="Background" Value="Green" />
    
          <Style.Triggers>
            <DataTrigger Binding="{Binding Foo}" Value="1">
              <Setter Property="Background" Value="Blue" />
            </DataTrigger>
    
            <DataTrigger Binding="{Binding Foo}" Value="2">
              <Setter Property="Background" Value="Red" />
            </DataTrigger>
    
            <DataTrigger Binding="{Binding Foo}" Value="2">
              <Setter Property="Background" Value="Yellow" />
            </DataTrigger>
    
          </Style.Triggers>
        </Style>
      </DataGridTextColumn.ElementStyle>
    </DataGridTextColumn>
    

    另一种方法是使用带有转换器的绑定:

    <DataGridTextColumn Binding="{Binding WhateverIWantToDisplay}" >
      <DataGridTextColumn.ElementStyle>
        <Style TargetType="{x:Type TextBlock}">
    
          <Setter Property="Background"
            Value="{Binding Foo, Converter={x:Static my:FooToColorConverter.Instance}}" />
    
        </Style>
      </DataGridTextColumn.ElementStyle>
    </DataGridTextColumn>
    

    使用此转换器:

    public class FooToColorConverter : IValueConverter
    {
      public static readonly IValueConverter Instance = new FooToColorConverter();
      public object Convert(object value, ...
      {
        int foo = (int)value;
        return
          foo==1 ? Brushes.Blue :
          foo==2 ? Brushes.Red :
          foo==3 ? Brushes.Yellow :
          foo>3 ? Brushes.Green :
            Brushes.Transparent;  // For foo<1
      }
      public object ConvertBack(...
      {
        throw new NotImplementedException();
      }
    }
    

    请注意,serge_gubenko 给出的答案也可以,但仅当您的 Foo 属性值永远不会改变。这是因为 Color 属性 getter 只会被调用一次。他的解决方案可以通过将 Color 更改为只读的 DependencyProperty 并在分配 Foo 时对其进行更新来改进,但在数据模型中包含特定于 UI 的信息(如颜色)通常是一个坏主意,因此不建议这样做。

    【讨论】:

    • 非常感谢。我发现 WPF 使用起来非常令人沮丧,因为它往往会隐藏错误,并且当您没有正确的代码时不会做任何事情。但是当它工作时,当您知道自己在做什么时,它的闪电般快速且易于使用。老实说,在我使用过的所有技术中,WPF 的学习曲线是最陡峭的。无论如何,再次感谢。我选择了转换器,因为它给了我最大的灵活性。
    【解决方案3】:

    如果您的项目从 INotifyPropertyChanged 继承,那么 serge_gubenko 将运行良好,然后您的属性将更改调用 NotifyPropertyChanged("yourproperty")

    【讨论】:

      【解决方案4】:

      一种稍微不同的方法是,而不是将TextBlock 元素(通常在控件周围留下边框)定位到DataGridCell 本身。就我而言,我已经有了一个想要继承的样式,我只需要根据值更改背景颜色:

      <DataGridTextColumn 
          Width="*"
          Header="Status"
          Binding="{Binding EventStatus, Converter={StaticResource DescriptionAttributeConverter}}"
          HeaderStyle="{StaticResource DataGridColumnHeaderStyleCenterAligned}">
      
          <DataGridTextColumn.CellStyle>
              <Style TargetType="{x:Type DataGridCell}" BasedOn="{StaticResource DataGridCellStyleCenterAligned}">
                  <Style.Triggers>
                      <DataTrigger Binding="{Binding EventStatus}" Value="1">
                          <Setter Property="Background" Value="Green" />
                      </DataTrigger>
      
                      <DataTrigger Binding="{Binding EventStatus}" Value="2">
                          <Setter Property="Background" Value="Red" />
                      </DataTrigger>
                  </Style.Triggers>
              </Style>
          </DataGridTextColumn.CellStyle>
      </DataGridTextColumn>
      

      可能对我的情况有用。

      【讨论】:

        猜你喜欢
        • 2018-09-26
        • 2015-05-14
        • 2011-04-03
        • 2016-11-15
        • 2011-10-15
        • 2013-01-28
        • 2020-06-02
        • 2015-08-28
        • 1970-01-01
        相关资源
        最近更新 更多