У меня есть типизированный набор данных, который связан с сетью данных (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>
Я полагаю, что сейчас близок к этому (много тестов и поиск в Google, чтобы добраться сюда). Я могу найти 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). Элемент будет иметь {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;
}
}
Это из-за порядка связывания / создания? Есть ли способ обойти это?
Спасибо