如何将数据绑定到数据网格在运行时

如何将数据绑定到数据网格在运行时

问题描述:

好,我有一些测试code,它被定义为

All, I have some test code that works with some test data defined as

private ObservableCollection<TestClass> _testData = new ObservableCollection<TestClass>();
public ObservableCollection<TestClass> TestData
{
    get { return _testData; }
    set { _testData = value; }
}

并通过

<DataGrid x:Name="dataGrid" ItemsSource="{Binding TestData}".../>

我创建了一个的DataGrid 它获取在运行时通过

dataGrid.ItemsSource = BuildDataGridColumns(cultureDict).Tables[0].AsDataView();

private DataSet BuildDataGridColumns(Dictionary<string, string> cultureDict,
                                     DataTable additionalDt = null)
{
    // ...
}

伟大的工程,然而code,更新所使用的测试数据的工作不再做,由于(我相信)的ItemsSource ={结合TESTDATA}网格视觉缺席的原因。这应该是在的DataGrid 的细胞插入文本框的文本和绑定的XAML是:

Which works great, however the code that updates the grids visuals that used to work with the test data no longer does due to (I believe) ItemsSource="{Binding TestData}" being absent. The XAML that is supposed to bind the text inserted into a TextBox and that in the cells of the DataGrid is:

<DataGrid x:Name="dataGrid" 
          local:DataGridTextSearch.SearchValue="{Binding ElementName=searchBox, Path=Text, UpdateSourceTrigger=PropertyChanged}" 
          AlternatingRowBackground="Gainsboro" AlternationCount="2" HorizontalAlignment="Stretch"
          VerticalAlignment="Stretch">
   <DataGrid.Resources>
      <local:SearchValueConverter x:Key="searchValueConverter" />
      <Style TargetType="{x:Type DataGridCell}">
         <Setter Property="local:DataGridTextSearch.IsTextMatch">
            <Setter.Value>
               <MultiBinding Converter="{StaticResource searchValueConverter}">
                  <Binding RelativeSource="{RelativeSource Self}" Path="Content.Text" />
                  <Binding RelativeSource="{RelativeSource Self}" Path="(local:DataGridTextSearch.SearchValue)" />
               </MultiBinding>
            </Setter.Value>
         </Setter>
         <Style.Triggers>
            <Trigger Property="local:DataGridTextSearch.IsTextMatch" Value="True">
               <Setter Property="Background" Value="Orange" />
            </Trigger>
         </Style.Triggers>
      </Style>
   </DataGrid.Resources>
   <DataGrid.CellStyle>
      <Style TargetType="DataGridCell" >
         <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
               <Setter Property="Background" Value="#FF007ACC"/>
               <Setter Property="Foreground" Value="White"/>
            </Trigger>
         </Style.Triggers>
      </Style>
   </DataGrid.CellStyle>
</DataGrid>

我的问题是;

如何创建相同的绑定我的的DataGrid 到数据集我在运行时创建?

How can I create the same binding of my DataGrid to the data set I create at run-time?

有人建议,原因是我的数据没有实现 INotifyCollectionChanged 接口,但由于数据的变动性,我必须加载数据到的DataGrid 在运行时。

Someone has suggested that the reason is that my data does not implement INotifyCollectionChanged interface, but due to the variable nature of the data, I have to load the data into the DataGrid at run-time.

如何绑定这些数据到的DataGrid 作为一个类实现 INotifyPropertyChanged的如果结构数据可以改变?

How can I bind this data to the DataGrid as a class that implements INotifyPropertyChanged if the structure of the data can change?

非常感谢您的时间。

我觉得布拉姆是正确的。 (对不起,我没有权限添加评论。)在你的测试code,可以使用一个ObservableCollection,这确实实现INotifyPropertyChanged。数据网格将拿起修改该集合。你应该考虑使用你的真实code一个ObservableCollection和更新数据通过它被绑定的DataGrid中通过dataGrid.ItemsSource有所回升,而不是直接。

I think Blam is right. (Sorry I don't have privileges to add comments yet.) In your test code, you use an ObservableCollection, which does implement INotifyPropertyChanged. The DataGrid will pick up changes to that collection. You should consider using an ObservableCollection in your real code and updating the data through it to be picked up by the bound DataGrid, rather than directly through dataGrid.ItemsSource.

本网页上的答案方法可以帮助: http://*.com/a/1581588/1082026

The approach in the answer on this page may help: http://*.com/a/1581588/1082026

在最后,你的code可能是这个样子(注意,你必须定义一个类的的DataItem 这将反映在您的数据集的数据表中的一行,专门与性能您的的DataGrid 关心):

In the end, your code may look something like this (note, you'll have to define a class DataItem that would mirror a row in your DataSet's DataTable, specifically with the properties your DataGrid cares about):

private ObservableCollection<DataItem> dataItems= new ObservableCollection<DataItem>();
public ObservableCollection<DataItem> DataItems
{
    get { return this.dataItems; }
    set 
    { 
         this.dataItems = value; 
         base.OnPropertyChanged("DataItems");
    }
}

通过这种结合

<DataGrid x:Name="dataGrid" ItemsSource="{Binding TestData}".../>

如果你不想处理add()和删除(),这将是你如何设置系列:

And if you don't want to deal with Add() and Remove(), this would be how you set the collection:

IList<DataItem> items = BuildDataGridColumns(cultureDict).Tables[0].AsDataView();
this.DataItems = new ObservableCollection<DataItem>(items);

...

private IList<DataItem> BuildDataGridColumns(Dictionary<string, string> cultureDict,
                                     DataTable additionalDt = null)
{
    // ... here create a list of DataItems from your table, and return it.
}

希望帮助!