如何在AutoGeneratingColumn事件期间根据其值设置数据网格单元格的背景?

我仍然在操纵细胞背景,所以我问了一个新问题。

用户“HB”写道我可以在AutoGeneratingColumn事件期间实际设置单元格样式 – 根据值更改DataGrid单元格颜色 。 问题是我不知道该怎么做。

我想要的:根据每个单元格的值设置不同的背景颜色 。 如果值为null我也希望它不可 点击 (我猜可以集中精力)。

我有/我想做什么:

 private void mydatagrid_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e) { foreach (Cell cell in e.Column) { if (cell.Value < 1) { cell.Background = Color.Black; cell.isFocusable = false; } else { cell.Background = Color.Pink; } } } 

这只是伪代码。 在列自动生成期间是否可以这样做,如果是这样,我如何编辑我的代码以使其有效?

我读到了有关值转换器的信息,但我想知道它是否可以通过编程方式实现,而无需编写XAML。

请理解我还是C#/ WPF / DataGrid的初学者。

解决方案part1:

我用了我接受的答案。 把它放入

                      

并为它制作了一个MultiBinding转换器,所以我也可以设置所选单元格的背景颜色。

问题:

现在我只需要解决设置空单元格焦点的问题。 任何提示?

       

这不起作用。 我在空单元格中有空字符串,但是它们充满了“空”,所以它应该可以工作,对吗? 或者我做错了什么:| ?

解决方案第2部分

因此,只要单元格值是’TextBox’,上面的代码就无法工作,所以我决定找到另一种处理它的方法,可以在我的答案中找到: https : //stackoverflow.com/a/16673602 / 2296407

谢谢你试图帮助我:)

我可以为你的问题提出两个不同的解决方案:第一个是“代码隐藏风格”(你要求但我个人认为这不是WPF中的正确方法)和更多WPF风格(更难处理但保留代码) – 清洁并利用风格,触发器和转换器)

解决方案1.用于着色的事件处理和代码隐藏逻辑

首先,您选择的方法无法直接使用 – AutoGeneratingColumn事件旨在用于更改整个列的外观,而不是逐个单元格。 因此,它可以用于,例如,根据它的显示索引或绑定属性将正确的样式附加到整个列。

一般来说,第一次引发事件时,数据网格根本就没有任何行(因此也就是单元格)。 如果您确实需要捕获事件 – 请考虑使用DataGrid.LoadingRow事件。 你将无法轻松获得细胞:)

那么,你做了什么:处理LoadingRow事件,获取行(它具有Item属性(令人惊讶:)保存你的绑定项),获取绑定项,进行所有需要的计算,获取需要更改的单元格和最后改变了目标细胞的风格。

这是代码(作为项目,我使用带有int“Value”属性的示例对象,我用它来着色)。

XAML

   

.CS

  private void DataGrid_OnLoadingRow(object sender, DataGridRowEventArgs e) { Dispatcher.BeginInvoke(DispatcherPriority.Render, new Action(() => AlterRow(e))); } private void AlterRow(DataGridRowEventArgs e) { var cell = GetCell(mygrid, e.Row, 1); if (cell == null) return; var item = e.Row.Item as SampleObject; if (item == null) return; var value = item.Value; if (value <= 1) cell.Background = Brushes.Red; else if (value <= 2) cell.Background = Brushes.Yellow; else cell.Background = Brushes.Green; } public static DataGridRow GetRow(DataGrid grid, int index) { var row = grid.ItemContainerGenerator.ContainerFromIndex(index) as DataGridRow; if (row == null) { // may be virtualized, bring into view and try again grid.ScrollIntoView(grid.Items[index]); row = (DataGridRow)grid.ItemContainerGenerator.ContainerFromIndex(index); } return row; } public static T GetVisualChild(Visual parent) where T : Visual { T child = default(T); int numVisuals = VisualTreeHelper.GetChildrenCount(parent); for (int i = 0; i < numVisuals; i++) { var v = (Visual)VisualTreeHelper.GetChild(parent, i); child = v as T ?? GetVisualChild(v); if (child != null) { break; } } return child; } public static DataGridCell GetCell(DataGrid host, DataGridRow row, int columnIndex) { if (row == null) return null; var presenter = GetVisualChild(row); if (presenter == null) return null; // try to get the cell but it may possibly be virtualized var cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex); if (cell == null) { // now try to bring into view and retreive the cell host.ScrollIntoView(row, host.Columns[columnIndex]); cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(columnIndex); } return cell; } 

解决方案2. WPF风格

此解决方案仅使用代码隐藏进行值到颜色的转换(假设着色的逻辑比相等比较更复杂 – 在这种情况下,您可以使用触发器而不会弄乱转换器)。

你做了什么:使用包含数据触发器的样式设置DataGrid.CellStyle属性,该样式检查单元格是否在所需的列内(基于它的DisplayIndex),如果是 – 通过转换器应用背景。

XAML

         

.CS

 public class ValueColorConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var str = value as string; if (str == null) return null; int intValue; if (!int.TryParse(str, out intValue)) return null; if (intValue <= 1) return Brushes.Red; else if (intValue <= 2) return Brushes.Yellow; else return Brushes.Green; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { throw new NotImplementedException(); } } 

UPD:如果需要为整个数据网格着色,XAML要容易得多(不需要使用触发器)。 使用以下CellStyle:

     

我的意思是你可以设置列的CellStyle属性,你不能直接操作单元格,因为它们在这个事件中不可用。 样式可以包含DataTriggersforms的条件逻辑(需要转换器,因为你有“小于”而不是等于)和Setters

此外,如果逻辑不是特定于列,则可以在网格本身上全局设置样式 。 使用该事件的目的是操纵您无法访问的列属性。

我不确定你的WPF Datagrid中是否有这个属性(Cell.Style)。 在您的情况下可能存在一些替代方案。 它适用于WinForms datagrid。

  cell.Style.BackColor = System.Drawing.Color.Black;