我在视图模型中动态创建了两个数据表。 在我在我的视图中显示它们之前,我将一个DataTable中的每个单元格值与第二个DataTable中的相同单元格进行比较。 我的问题是我想为不同的细胞提供不同的背景颜色。我怎么能以程序化的方式来做呢?
这是第一个DataGrid:
<GroupBox Header="Xml 1 Details" Margin="10,10,10,10" Grid.Row="1" Grid.ColumnSpan="4" Grid.Column="0">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<GroupBox x:Name="GridGroupBox"
Grid.Column="0"
Header="{Binding TableName}">
<DataGrid x:Name="DataGrid" Margin="5,5,5,5"
ItemsSource="{Binding GenericDataTable}"
attachedBehaviors:DataGridColumnsBehavior.BindableColumns="{Binding GridColumns}"
AutoGenerateColumns="False"
EnableRowVirtualization="False">
</DataGrid>
</GroupBox>
</Grid>
</ScrollViewer>
</GroupBox>
第二个DataGrid:
<GroupBox Header="Xml 2 Details" Margin="10,20,10,10" Grid.Row="2" Grid.ColumnSpan="4" Grid.Column="0">
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<GroupBox x:Name="GridGroupBox2"
Grid.Column="0"
Header="{Binding TableName}">
<DataGrid x:Name="DataGrid2" Margin="5,5,5,5"
ItemsSource="{Binding GenericDataTable2}"
attachedBehaviors:DataGridColumnsBehavior.BindableColumns="{Binding GridColumns2}"
AutoGenerateColumns="False"
EnableRowVirtualization="False"
/>
</GroupBox>
</Grid>
</ScrollViewer>
</GroupBox>
以编程方式创建它们:
private void GenerateFirstXmlDynamicColumns(DataTable dt, List<string> cols)
{
GridColumns = new ObservableCollection<DataGridColumn>();
foreach (DataColumn col in dt.Columns)
{
GridColumns.Add(new DataGridTextColumn
{
Header = col.ColumnName,
Binding = new Binding(col.ColumnName)
});
}
RaisePropertyChanged("GridColumns");
GenericDataTable = dt;
RaisePropertyChanged("GenericDataTable");
}
private void GenerateSecondXmlDynamicColumns(DataTable dt, List<string> cols)
{
GridColumns2 = new ObservableCollection<DataGridColumn>();
foreach (DataColumn col in dt.Columns)
{
GridColumns2.Add(new DataGridTextColumn
{
Header = col.ColumnName,
Binding = new Binding(col.ColumnName)
});
}
RaisePropertyChanged("GridColumns2");
GenericDataTable2 = dt;
RaisePropertyChanged("GenericDataTable2");
}
我在这里比较细胞,我想改变不同细胞的背景颜色:
private void CompareData()
{
for (int i = 0; i < GenericDataTable.Rows.Count; i++)
{
for (int j = 0; j < GenericDataTable.Columns.Count; j++)
{
if (!GenericDataTable.Rows[i][j].Equals(GenericDataTable2.Rows[i][j]))//if cells are different
{
}
}
}
}
答案 0 :(得分:0)
从索引获取DataGrid单元格:
public DataGridCell GetCell(DataGrid dg, int row, int column)
{
DataGridRow rowContainer = GetRow(dg, row);
if (rowContainer != null)
{
DataGridCellsPresenter presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);
if (presenter == null)
{
dg.ScrollIntoView(rowContainer, dg.Columns[column]);
presenter = GetVisualChild<DataGridCellsPresenter>(rowContainer);
}
DataGridCell cell = (DataGridCell)presenter.ItemContainerGenerator.ContainerFromIndex(column);
return cell;
}
return null;
}
public static DataGridRow GetRow(DataGrid dg, int index)
{
DataGridRow row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(index);
if (row == null)
{
dg.UpdateLayout();
dg.ScrollIntoView(dg.Items[index]);
row = (DataGridRow)dg.ItemContainerGenerator.ContainerFromIndex(index);
}
return row;
}
public static T GetVisualChild<T>(Visual parent) where T : Visual
{
if (parent == null) return null;
T child = default(T);
int numVisuals = VisualTreeHelper.GetChildrenCount(parent);
for (int i = 0; i < numVisuals; i++)
{
Visual v = (Visual)VisualTreeHelper.GetChild(parent, i);
child = v as T;
if (child == null)
{
child = GetVisualChild<T>(v);
}
if (child != null)
{
break;
}
}
return child;
}
并设置背景:
var cell = GetCell(DataGrid2, i, j);
cell.Background = color;
答案 1 :(得分:0)
以下是解决方案:
Create a MultiConverter:public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) { var dataContext = values[0]; var dg = (DataGrid)values[1]; var i = (DataGridCell)values[2]; var col = i.Column.DisplayIndex; var row = dg.Items.IndexOf(i.DataContext); if (row >= 0 && col >= 0) { DataTable td1 = ((CheckXmlAppWpf.ViewModel.MainWindowViewModel) (dataContext)).GenericDataTable; DataTable td2 = ((CheckXmlAppWpf.ViewModel.MainWindowViewModel)(dataContext)).GenericDataTable2; if (!td1.Rows[row][col].Equals(td2.Rows[row][col])) { GetCell(dg, row, col).Background = Brushes.Yellow; } } return SystemColors.AppWorkspaceColor; } public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) { throw new System.NotImplementedException(); } }
Use it in the xaml:
<DataGrid x:Name="DataGrid" Margin="5,5,5,5" ItemsSource="{Binding GenericDataTable}" attachedBehaviors:DataGridColumnsBehavior.BindableColumns="{Binding GridColumns}" AutoGenerateColumns="False" EnableRowVirtualization="False"> <DataGrid.Resources> <Style TargetType="DataGridCell"> <Setter Property="Background"> <Setter.Value> <MultiBinding Converter="{StaticResource NameToBrushMultiValueConverter}" > <MultiBinding.Bindings> <Binding RelativeSource="{RelativeSource AncestorType=Window}" Path="DataContext" /> <Binding RelativeSource="{RelativeSource AncestorType=DataGrid}"></Binding> <Binding RelativeSource="{RelativeSource Self}"/> </MultiBinding.Bindings> </MultiBinding> </Setter.Value> </Setter> </Style> </DataGrid.Resources> </DataGrid>