【发布时间】:2023-03-28 15:02:02
【问题描述】:
我有一个 WPF 数据网格,其列数可变,并在运行时使用 String[][] 的二维数组填充。
String[] data = .....;
datagrid.ItemsSource = data;
我需要根据单元格的值来判断单元格的颜色。但是这些值是由用户在执行期间定义的。我发现的大多数关于更改单元格颜色的示例都使用 XAML 上的触发器,并且该值在设计时是已知的。
所以我正在像这样更改单元格的背景:
DataGridCell cell = DataGridUtils.GetCell(datagrid, i, j);
cell.Background = new SolidColorBrush(Colors.DarkGreen);
还有GetCell函数:
private DataGridCell GetCell(int rowIndex, int colIndex, DataGrid dg)
{
DataGridRow row = dg.ItemContainerGenerator.ContainerFromIndex(rowIndex) as DataGridRow;
DataGridCellsPresenter p = GetVisualChild<DataGridCellsPresenter>(row);
DataGridCell cell = p.ItemContainerGenerator.ContainerFromIndex(colIndex) as DataGridCell;
return cell;
}
乍一看似乎还不错,我可以看到具有绿色值的单元格。但是,如果我一直向下滚动数据网格,然后返回绿色变化的单元格,则另一个随机单元格会变成绿色。如果我继续上下移动,绿色的单元格会随机变化。
我知道这听起来很奇怪,但是代码中只有一个地方可以更改单元格颜色,那就是单击按钮。我不知道滚动数据网格时会发生这种情况。
我在某处读到 ItemContainerGenerator 这不是一个优雅的解决方案,应该避免。但这是我成功完成这项工作的唯一方法。
有没有更好的方法来改变单元格的背景颜色?我可以在不知道设计时值的情况下使用触发器执行此操作吗?如果有,怎么做?
【问题讨论】:
-
您无需放弃通过将
VirtualizingMode设置为Standard的虚拟化功能。您可以处理事件LoadingRow以更新那里的背景,还可以处理UnloadingRow以将背景恢复为某个默认值。我刚刚在DataGridRow(不是DataGridCell)上对其进行了测试,但事实证明这种方式非常有前景。虚拟化有自己的方式来解决这个问题。 -
@KingKing 当您快速滚动网格并注意到背景滞后时,您会遇到问题。
-
@lll 这在某种意义上是可以接受的。不过优点是节省内存(因为还在使用虚拟化),转虚拟化的缺点是消耗大量内存。因此,根据某些标准遵循这个或那个。尝试快速滚动网格是不正常的。如果您总是尝试像那样快速做一些事情,您会觉得 WPF 实际上表现不佳(就像宣传的那样)。
-
一个简单的fast例子让我们不满意:尝试尽可能快地调整窗口大小,它有多闪烁?至少在 Windows 7 和几乎所有 Windows 中都会发生这种情况。
-
@KingKing 我同意。但是,如果
DataCell依赖于序列化并且您需要DataCell' 颜色来应用正确的背景怎么办。Loading/Unloadedevents 在这里对您没有帮助。这始终是一种权衡,取决于他的用例,如果收益和损失是什么。