WPF dataGrid查找单个单元格的X和Y并设置背景色

|| 我有一个绑定到数据网格(MVVM)的类型化数据集。我也有一个点列表(类型化数据集中的X和Y),指出哪些单元格有错误。检测到此的逻辑很复杂,并且在服务器端运行。 我的目标是在每个单元格有错误的情况下为它们涂上不同的颜色(即,点列表包含该单元格的X和Y)。 dataGrid定义为:
 <DataGrid x:Name=\"gridData\" Grid.Row=\"0\" Grid.Column=\"0\" Grid.ColumnSpan=\"3\" VerticalAlignment=\"Stretch\" HorizontalAlignment=\"Stretch\" 
              BorderThickness=\"0 0 0 0\" Margin=\"0 0 0 0\" AutoGenerateColumns=\"True\" AlternationCount=\"1\" AlternatingRowBackground=\"AliceBlue\"
              ItemsSource=\"{Binding Path=EquisDataTable}\" SelectionUnit=\"Cell\" SelectedCellsChanged=\"gridData_SelectedCellsChanged\"
              AutoGeneratedColumns=\"GridData_OnAutoGeneratedColumns\" AutoGeneratingColumn=\"gridData_AutoGeneratingColumn\" Height=\"350\">
                        <DataGrid.CellStyle>
            <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>
        </DataGrid.CellStyle>
    </DataGrid>
我相信我现在已经很接近(经过很多测试和谷歌搜索才能到达这里)。填充所有内容后,当更改单元格选择时,可以找到单元格的X和Y,即“ SelectedCellsChanged \”方法。尽管加载时,这并不能让我进入每个单元格并检查其值。
    private void gridData_SelectedCellsChanged(object sender, SelectedCellsChangedEventArgs e)
    {
        int x;
        int y;
        if (TryGetDataGridCellXandY(gridData.CurrentCell, gridData, out x, out y))               
        { }
    }      

    private bool TryGetDataGridCellXandY(DataGridCellInfo dgc, DataGrid dataGrid, out int x, out int y)
    {
        int columnIndex = dgc.Column.DisplayIndex;
        return TryGetDataGridCellXandY(columnIndex, dataGrid, out x, out y);
    }

    private bool TryGetDataGridCellXandY(int columnIndex, DataGrid dataGrid, out int x, out int y)
    {
        DataGridCellInfo currentCell = dataGrid.CurrentCell;

        int rowIndex = int.MinValue;
        DataRowView rowView = currentCell.Item as DataRowView;
        if (rowView != null)
        {
            DataRow dataRow = rowView.Row;
            FieldInfo fi = typeof(DataRow).GetField(\"_rowID\", BindingFlags.NonPublic | BindingFlags.Instance);
            try
            {
                if (fi != null)
                {
                    rowIndex = System.Convert.ToInt32(fi.GetValue(dataRow));
                }
            }
            catch (InvalidCastException) { }

        }

        x = columnIndex;
        y = rowIndex;

        return x > 0 && y > 0;
    }
因此,我创建了一个多值转换器来执行相同的操作。当使用转换器时,如果“单元格的列”为空,则会出现问题,并且currentCell.Item(DataGridCellInfo).Item也将具有{DependencyProperty.UnsetValue}。
public class DataGridCellOnErrorConversion : IMultiValueConverter
{
    private const string DefaultColour = \"White\";
    private const string ErrorColour = \"Red\";
 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;
        if (TryGetDataGridCellXandY(grid.CurrentCell, grid, out x, out y))
        {
            if (problems.Any(problem => System.Convert.ToInt32(problem.X) == x && System.Convert.ToInt32(problem.Y) == y))
            {
                return ErrorColour;
            }
        }

        return DefaultColour;
  }
 private bool TryGetDataGridCellXandY(DataGridCellInfo dgc, DataGrid dataGrid, out int x, out int y)
    {
        int columnIndex = dgc.Column.DisplayIndex;
        return TryGetDataGridCellXandY(columnIndex, dataGrid, out x, out y);
    }

    private bool TryGetDataGridCellXandY(int columnIndex, DataGrid dataGrid, out int x, out int y)
    {
        DataGridCellInfo currentCell = dataGrid.CurrentCell;

        int rowIndex = int.MinValue;
        DataRowView rowView = currentCell.Item as DataRowView;
        if (rowView != null)
        {
            DataRow dataRow = rowView.Row;
            FieldInfo fi = typeof(DataRow).GetField(\"_rowID\", BindingFlags.NonPublic | BindingFlags.Instance);
            try
            {
                if (fi != null)
                {
                    rowIndex = System.Convert.ToInt32(fi.GetValue(dataRow));
                }
            }
            catch (InvalidCastException) { }

        }

        x = columnIndex;
        y = rowIndex;

        return x > 0 && y > 0;
    }  
}
这是因为绑定/创建顺序吗?有没有解决的办法? 谢谢     
已邀请:
这就是我解决问题的方式((目前尚不确定)是否最佳,但似乎可行: 我在数据网格单元格的样式上有一个多值转换器:
      <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;
    }
}
    

要回复问题请先登录注册