WPF dataGrid単一セルのXおよびYを検索し、背景色を設定します

wpf wpfdatagrid
WPF dataGrid単一セルのXおよびYを検索し、背景色を設定します

データグリッド(MVVM)にバインドされている型指定されたデータセットがあります。 また、どのセルにエラーがあるかを示すポイントのリスト(入力したデータセットのXとY)があります。 これを検出するロジックは複雑で、サーバー側で実行されます。

私の目標は、エラーが発生した場合に各セルの背景を異なる色でペイントすることです(つまり、 点のリストには、そのセルのXとYが含まれます。

dataGridは次のように定義されます:

今、私はそれに近づいていると信じています(ここに到達するには、多くのテストとグーグルが必要です)。 すべてが読み込まれた後にセルの選択が変更されると、「SelectedCellsChanged」メソッドでセルのXとYを見つけることができます。 これにより、ロード中にすべてのセルにアクセスしてその値をチェックすることはできません。

    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;
    }

そこで、同じことを行うために複数値コンバーターを作成しました。 この問題は、コンバーターの使用時にCellの列がnullの場合に発生します。また、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 problems = values[1] as IList;
        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;
    }
}

これは、バインディング/作成の順序によるものですか? これを回避する方法はありますか?

ありがとう

  2  0


ベストアンサー

これは私が私の問題を解決した方法です(それが最適であるかどうかはわかりませんが、うまくいくようです(これまで):

データグリッドセルのスタイルに複数値コンバーターがあります:

そしてコンバータ:

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 problems = values[1] as IList;
        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;
    }
}

2


タイトルとURLをコピーしました