绑定到类型化数据集的WPF datagrid。根据列表高亮显示单个单元格的背景色<;点>;
我有一个wpf应用程序,它有一个绑定(MVVM)到类型化数据集的datagrid。数据显示(自动生成的列)很好 我还有一个(在ViewModel中)列表集合,它表示其中包含“坏”数据的单元格。我想更改数据网格中与点列表相对应的单个单元格的背景颜色。我想不出如何单独访问每个单元格 我试着用一个转换器传递问题列表,但意识到当时我无法知道我在哪个单元(X和Y) 我在AutoGeneratedColumns事件上尝试了GridData_,但不知道如何引用单个单元格 我心慌意乱 谢谢看到你在同一个问题上的想法,并想再次访问这里 嗯,这应该符合您的需要: 您需要做的是:绑定到类型化数据集的WPF datagrid。根据列表高亮显示单个单元格的背景色<;点>;,wpf,datagrid,Wpf,Datagrid,我有一个wpf应用程序,它有一个绑定(MVVM)到类型化数据集的datagrid。数据显示(自动生成的列)很好 我还有一个(在ViewModel中)列表集合,它表示其中包含“坏”数据的单元格。我想更改数据网格中与点列表相对应的单个单元格的背景颜色。我想不出如何单独访问每个单元格 我试着用一个转换器传递问题列表,但意识到当时我无法知道我在哪个单元(X和Y) 我在AutoGeneratedColumns事件上尝试了GridData_,但不知道如何引用单个单元格 我心慌意乱 谢谢看到你在同一个问题上的
1.查找运行以下逻辑的特定时间。理想情况下,这应该在绑定datagrid之后进行。
2.迭代您的
列表
。
3.对于
列表中的每个项目
,调用引用链接中的GetCell helper函数并访问DataGridCell。
4.更改DataGridCell的颜色或对其执行任何操作 请注意:
1.您需要计算出运行逻辑的适当时间(步骤1)。
2.这个解决方案有点不利于MVVM。然而,既然你有特殊的需要,它应该足够了。
3.该链接中的问题基本上是想获得DataGridCell的值。但是,您应该对该助手函数返回的DataGridCell感到满意,因为您只想更改背景颜色,而不想更改值。
4.该链接中没有提到GetRow函数代码。但是,它引用了一篇文章,您可以在其中下载代码并查看GetRow方法。
5.默认情况下,datagrid的虚拟化处于启用状态。因此,不会创建屏幕上未显示的DataGridCell。如果您按原样使用helper函数,并且您的数据网格很大,那么它的加载速度可能会非常慢,因为helper函数试图通过滚动到所有请求的单元格来查看它们。您可能希望查看datagrid的LoadingRow和UnloadingGrow事件。这就是我解决问题的方法,(不确定是否是最佳的,但似乎有效,(到目前为止): 我在datagrid单元格的样式上有一个多值转换器:
<Style TargetType="{x:Type DataGridCell}">
<Style.Setters>
<Setter Property="Background">
<Setter.Value>
<MultiBinding Converter="{StaticResource onErrorConverter}">
<Binding RelativeSource="{RelativeSource Self}" />
<Binding RelativeSource="{RelativeSource AncestorType=SampleTests:SampleTestUserControlBase}" Path="DataContext.Problems" />
<Binding RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}" />
</MultiBinding>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
和转换器:
public class DataGridCellOnErrorConversion : IMultiValueConverter
{
private readonly SolidColorBrush DefaultColour = new SolidColorBrush(Colors.White);
private readonly SolidColorBrush ErrorColour = new SolidColorBrush(Colors.Red);
private readonly SolidColorBrush AlternatingColour = new SolidColorBrush(Colors.AliceBlue);
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
if (values.Length < 3)
return DefaultColour;
DataGridCell dgc = values[0] as DataGridCell;
if(dgc == null)
return DefaultColour;
IList<Point> problems = values[1] as IList<Point>;
if(problems == null)
return DefaultColour;
DataGrid grid = values[2] as DataGrid;
if (grid == null)
return DefaultColour;
int x;
int y = -1;
ItemCollection itemCollection = grid.Items;
for (int i = 0; i < itemCollection.Count; i++)
{
if (itemCollection.CurrentItem == itemCollection[i])
y = i;
}
x = dgc.Column.DisplayIndex;
DataRowView currentRowView = null;
FieldInfo fi = dgc.GetType().GetField("_owner", BindingFlags.NonPublic | BindingFlags.Instance);
try
{
if (fi != null)
{
DataGridRow dataGridRow = fi.GetValue(dgc) as DataGridRow;
if(dataGridRow != null)
currentRowView = dataGridRow.Item as DataRowView;
}
}
catch (InvalidCastException) { }
if(currentRowView != null)
{
for (int i = 0; i < itemCollection.Count; i++)
{
if (currentRowView == itemCollection[i])
y = i;
}
}
if (problems.Any(problem => System.Convert.ToInt32(problem.X) == x && System.Convert.ToInt32(problem.Y) == y))
{
return ErrorColour;
}
return y % 2 == 0 ? AlternatingColour : DefaultColour;
}
}
公共类DataGridCellErrorConversion:IMultiValueConverter
{
private readonly SolidColorBrush DefaultColor=新的SolidColorBrush(Colors.White);
private readonly SolidColorBrush ErrorColor=新的SolidColorBrush(Colors.Red);
私有只读SolidColorBrush AlternatingColor=新的SolidColorBrush(Colors.AliceBlue);
公共对象转换(对象[]值,类型targetType,对象参数,CultureInfo区域性)
{
如果(值。长度<3)
返回默认颜色;
DataGridCell dgc=值[0]为DataGridCell;
如果(dgc==null)
返回默认颜色;
IList问题=值[1]为IList;
if(problems==null)
返回默认颜色;
DataGrid grid=值[2]为DataGrid;
if(grid==null)
返回默认颜色;
int x;
int y=-1;
ItemCollection ItemCollection=grid.Items;
for(int i=0;iSystem.Convert.ToInt32(problem.X)==X&&System.Convert.ToInt32(problem.Y)==Y))
{
返回颜色;
}
返回y%2==0?AlternatingColor:DefaultColor;
}
}
此“点”(在列表中)是否可以成为类型化数据集的一部分(即,数据集的每一行是否都有一个名为“IsBad”的列,该列具有布尔值)?在这种情况下,您可能可以将背景与布尔值绑定(使用转换器)@publicgk遗憾的是,它需要特定于单元格,因此标记整行不是一个选项。那么,您点的X,Y是否代表数据网格中的X,Y单元格号?还有一件事,您如何确定单元格是否有坏值?每列必须有单独的逻辑。例如,如果有两列,则为revenue和profit。revenue c的逻辑列可能是:如果(收入<50000),则为坏;如果利润列可能是(如果利润<0),则为坏。如果您有此逻辑并基于此创建列表,为什么不在每个单元格的转换器中使用此逻辑?如果您发布代码,这将有助于减少假设:该逻辑相当复杂,并且事先通过多个进程/处理器运行。这不是我可以或不会放在客户机/视图中的东西。这帮助我找到了一个不同的解决方案(发布在这里)。谢谢