如何解决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 y);
}
private bool TryGetDataGridCellXandY(int columnIndex,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 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,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;
}
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。