Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
绑定到类型化数据集的WPF datagrid。根据列表高亮显示单个单元格的背景色<;点>;_Wpf_Datagrid - Fatal编程技术网

绑定到类型化数据集的WPF datagrid。根据列表高亮显示单个单元格的背景色<;点>;

绑定到类型化数据集的WPF datagrid。根据列表高亮显示单个单元格的背景色<;点>;,wpf,datagrid,Wpf,Datagrid,我有一个wpf应用程序,它有一个绑定(MVVM)到类型化数据集的datagrid。数据显示(自动生成的列)很好 我还有一个(在ViewModel中)列表集合,它表示其中包含“坏”数据的单元格。我想更改数据网格中与点列表相对应的单个单元格的背景颜色。我想不出如何单独访问每个单元格 我试着用一个转换器传递问题列表,但意识到当时我无法知道我在哪个单元(X和Y) 我在AutoGeneratedColumns事件上尝试了GridData_,但不知道如何引用单个单元格 我心慌意乱 谢谢看到你在同一个问题上的

我有一个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),则为坏。如果您有此逻辑并基于此创建列表,为什么不在每个单元格的转换器中使用此逻辑?如果您发布代码,这将有助于减少假设:该逻辑相当复杂,并且事先通过多个进程/处理器运行。这不是我可以或不会放在客户机/视图中的东西。这帮助我找到了一个不同的解决方案(发布在这里)。谢谢