【问题标题】:WPF Datagrid row color based on a value基于值的 WPF Datagrid 行颜色
【发布时间】:2017-06-16 05:38:57
【问题描述】:

我有以下代码在运行时填充数据网格的资源。

DataTable dt = new DataTable();
dt.Columns.Add("Date");
dt.Columns.Add("User");
dt.Columns.Add("Type");
foreach (var x in query)
{
    var row = dt.NewRow();
    decimal total_REC = 0;
    decimal total_RET = 0;

    row["Date"] = x.CurrentDate.ToString();
    row["User"] = x.User;
    row["Type"] = x.TranscationType;
    dt.Rows.Add(row);
}

最后我将我的数据网格引用到这个数据表

dgv_Transations.DataContext = dt;

在第一个函数中,我可以从 x.TransactionType 中找出需要突出显示的行。所有等于值“A”的类型都将其相应的行以黄色突出显示,因为在背景中将是黄色的。

有没有办法在运行时(来自 c# 代码)以编程方式将整行的背景颜色设置为我想要的。我可以使用 dt.rows.count 作为我的索引,但我想不出一种方法来设置数据网格行背景颜色(总是得到空引用异常)。

在 winforms 中我会转到 datagridview.rows 并继续,但在 WPF 中我没有选项。我尝试了以下方法,但它一直返回 null。

if (dt.Rows.Count > 0)
{
    DataGridRow r = dgv_Transations.ItemContainerGenerator.ContainerFromIndex(dt.Rows.Count - 1) as DataGridRow;
    r.Background = Brushes.Red;
}

【问题讨论】:

  • This 链接可能对你有用

标签: c# wpf datagrid


【解决方案1】:

我正在根据我使用的稍微不同的解决方案修改此答案。

您可以为拥有 DataGrid 的窗口创建 XAML 样式。

<Window.Resources>
   <Style TargetType="{x:Type DataGridRow}">
      <Style.Setters>
            <Setter Property="Background" Value="{Binding Path=Code}"></Setter>
      </Style.Setters>
   </Style>
</Window.Resources>

“代码”是字符串类型的类变量的名称,其中包含颜色名称(“红色”、“蓝色”等)。因此,在您的情况下,“代码”将是您的 dt 中的一列。

然后,您需要将“代码”的值设置为黄色,只要您想突出显示该行。

如果你不是很清楚,请参考我在这里使用的原始代码示例:

Original Code Sample

【讨论】:

    【解决方案2】:

    您可以创建一个将交易类型转换为画笔的 IValueConverter 并在 Window.Resources 中添加一个条目来注册它。

    public class TransactionTypeConverter: IValueConverter
        {
            public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
            {
                var trxnType = value as int;
                if (value == null || trxnType==null) return Brushes.Transparent;
    
                if(trxnType==1) return Brushes.Red;            
    
                return Brushes.Transparent;
            }
    
            public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
            {        
    }               
    

    那么你可以尝试两件事:

    1. 您可以将 DataGrid 的 RowBackground 绑定到 Type 并将 Converter 绑定到 TransactionTypeConverter:

    2. 在单元格模板中做同样的事情。

    【讨论】:

      【解决方案3】:

      按照@Sach 的建议,常用且推荐的方法是在 XAML 中使用数据触发器,但如果您仍想以编程方式执行此操作,您实际上可以使用 ItemContainerGenerator 获取对可视化容器的引用。

      您必须等到容器创建完成。您可以通过在 Loaded 事件处理程序中调用 ContainerFromIndex 方法来做到这一点:

      public MainWindow()
      {
          InitializeComponent();
          DataTable dt = new DataTable();
          dt.Columns.Add("Date");
          dt.Columns.Add("User");
          dt.Columns.Add("Type");
          for (int i = 1; i < 10; ++i)
          {
              var row = dt.NewRow();
              row["Date"] = 1;
              row["User"] = 2;
              row["Type"] = 3;
              dt.Rows.Add(row);
          }
      
          dgv_Transations.ItemsSource = dt.DefaultView;
      
          dgv_Transations.Loaded += (s, e) =>
          {
              if (dt.Rows.Count > 0)
              {
                  DataGridRow r = dgv_Transations.ItemContainerGenerator.ContainerFromIndex(dt.Rows.Count - 1) as DataGridRow;
                  r.Background = Brushes.Red;
              }
          };
      }
      

      第二个问题是 DataGrid 使用 UI 虚拟化。这意味着只生成您在屏幕上实际看到的数据行的容器。因此,如果最后一行被滚开,它就不再有任何 DataGridRow 容器。

      您可以通过禁用虚拟化来解决此问题:

      <DataGrid x:Name="dgv_Transations" VirtualizingPanel.IsVirtualizing="False" />
      

      当然,这可能会对性能产生负面影响。

      另一种选择是滚动到该项目,然后以编程方式生成容器:

      dgv_Transations.Loaded += (s, e) => 
      {
          if (dt.Rows.Count > 0)
          {
              var lastItem = dt.DefaultView[dt.Rows.Count - 1];
              DataGridRow r = dgv_Transations.ItemContainerGenerator.ContainerFromItem(lastItem) as DataGridRow;
              if (r == null)
              {
                  dgv_Transations.ScrollIntoView(lastItem);
                  r = dgv_Transations.ItemContainerGenerator.ContainerFromItem(lastItem) as DataGridRow;
              }
              r.Background = Brushes.Red;
          }
      };
      

      【讨论】:

        猜你喜欢
        • 2016-05-03
        • 2015-10-18
        • 2012-06-04
        • 1970-01-01
        • 2013-09-05
        • 1970-01-01
        • 2017-12-01
        • 2011-06-20
        • 2023-01-13
        相关资源
        最近更新 更多