2016-02-03 72 views
0

我在我的视图模型中动态创建两个数据表。 在我将它们显示在视图中之前,我将一个DataTable中的每个单元格值与第二个DataTable中的同一个单元格进行比较。 我的问题是我想提供不同的单元格不同的背景颜色。我怎样才能做到这一点?MVVM WPF动态数据网格

这里是第一个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

获得帮助这里的方法是尝试第一,显示你的代码,然后人都乐于帮助。 – kenny

回答

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

用它在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>

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; 
+0

谢谢,问题是我没有直接访问我的数据网格。我正在动态构建它:public ObservableCollection GridColumns {get;私人设置; } public DataTable GenericDataTable {get;私人设置; } public ObservableCollection GridColumns2 {get;私人设置; } public DataTable GenericDataTable2 {get;私人设置; } – Rom

+0

好的,你可以在你的DataGridColumn中使用CellTemplate。但是需要为绑定创建新的字段(bool不同的{get; set;}) –

+0

你有没有一个例子可以改变一个特定的单元格? – Rom