【问题标题】:How can I set the background colour of part of a WPF DataGrid row, depending on column values?如何根据列值设置 WPF DataGrid 行的一部分的背景颜色?
【发布时间】:2011-04-05 18:52:05
【问题描述】:

假设我有一个包含 5 列的 DataGrid,从客户类集合中加载(使用 AutoGenerateColumns=True)。根据第一列、第三列和第四列中的值,我需要使用以下选项之一设置行的背景:

col num:    1    2    3    4    5
 Option1: gray gray gray gray gray
 Option2: gray red  red  gray gray
 Option3: gray gray gray red  red
 Option4: gray blue blue blue blue

这需要对每一行分别进行。

我已经看到了一些为行背景设置转换器的示例,但是如何设置单个单元格背景?

【问题讨论】:

  • 您知道网格的数据上下文或 ItemsSource 是什么吗?其中的 AutoGenerateColumns 部分是我认为它不适用于模板的地方。
  • 是的,我的 ItemSource 是一个带有 List(Of MyCustomPOCO) 的 ViewModel 属性

标签: wpf datagrid binding wpfdatagrid


【解决方案1】:

您可能需要使用自定义列,然后您可以将整行传递给转换器,同时使用ConverterParameter 指定当前列,这样您就可以比较所有值:

<DataGridTextColumn Binding="{Binding Column1}">
    <DataGridTextColumn.ElementStyle>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="Background"
                    Value="{Binding Converter={StaticResource ValueToBrushConverter},
                                    ConverterParameter=1}"/>
        </Style>
    </DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<DataGridTextColumn Binding="{Binding Column2}">
    <DataGridTextColumn.ElementStyle>
        <Style TargetType="{x:Type TextBlock}">
            <Setter Property="Background"
                    Value="{Binding Converter={StaticResource ValueToBrushConverter},
                                    ConverterParameter=2}"/>
        </Style>
    </DataGridTextColumn.ElementStyle>
</DataGridTextColumn>
<!-- ... -->

我不太喜欢你的那个表,但你可能可以自己弄清楚如何在转换器中返回正确的值。


转换器骨架可能是这样的:

public class ValueToBrushConverter : IValueConverter
{
    /// <summary>
    /// 1st Indexer: Columns
    /// 2nd Indexer: Options
    /// </summary>
    Brush[,] _brushMatrix = new Brush[5,4]
    {
        { Brushes.Gray, Brushes.Gray, Brushes.Gray, Brushes.Gray },
        { Brushes.Gray, Brushes.Red, Brushes.Gray, Brushes.Blue },
        { Brushes.Gray, Brushes.Red, Brushes.Gray, Brushes.Blue },
        { Brushes.Gray, Brushes.Gray, Brushes.Red, Brushes.Blue },
        { Brushes.Gray, Brushes.Gray, Brushes.Red, Brushes.Blue }
    };

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        RowDataItem item = value as RowDataItem;
        int currentColumn = int.Parse(parameter as string);
        int currentRowOption;

        #region Internal logic here, e.g
        if (item.Col1 == "I" && item.Col3 == "Love" && item.Col2 == "Converters")
        {
            currentRowOption = 1;
        }
        //...
        #endregion

        return _brushMatrix[currentColumn, currentRowOption];
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotSupportedException();
    }
}

【讨论】:

  • 谢谢,所以你同意上面评论中的 N8,我不能使用 AutoGenerateColumns?
  • 我在 DataGrids 方面做得不多,但如果您使用 AutoGenerateColumns,您对各个部分的访问会少很多,也许有一些方法可以做到这一点,但这对我来说似乎更简单。跨度>
  • H.B.,你能举个实际转换器的例子吗?我有问题。我不需要内部逻辑,只需要接口和声明部分。非常感谢您的帮助
【解决方案2】:

如果您需要后端代码解决方案,我相信您可以获取 LoadingRow 事件来检查各个行的数据上下文,并以这种方式找到生成的单元格。不过我以前没有这样做过!

【讨论】:

  • 这是个好主意,但是当 AutoGenerateColumns=true 时,该事件似乎无法正常工作。因此,如果是这种情况,我可能会选择自定义列建议。
  • 实际上,无论 AutoGenerateColumns 是真还是假,这似乎都不起作用。看这里http://forums.silverlight.net/forums/p/218179/520231.aspx#520231,版主的回答。
  • 虽然该值尚未绑定到单元格,但您仍然可以访问该行的数据上下文和有问题的单元格。您提供的链接只是假设 RowBinding 发生在数据绑定之后。但是,是的,更好的方法是使用 xaml 数据模板。如果您知道将在网格中显示的确切数据,原始答案是最好的。
猜你喜欢
  • 2011-03-30
  • 2020-06-02
  • 2023-03-17
  • 1970-01-01
  • 2017-12-31
  • 2011-04-03
  • 2021-05-02
  • 2012-12-22
  • 1970-01-01
相关资源
最近更新 更多