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

时间:2013-04-17 14:41:08

标签: c# wpf binding datagrid inotifycollectionchanged

所有,我有一些测试代码适用于定义为

的一些测试数据
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)
{
    // ...
}

哪个效果很好,但更新过去用于测试数据的网格视觉效果的代码不再由于(我相信)ItemsSource="{Binding TestData}"缺席而导致。应该绑定插入TextBox的文本和DataGrid单元格中的文本的XAML是:

<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的相同绑定?

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

  

如果数据结构可以更改,如何将此数据绑定到DataGrid作为实现INotifyPropertyChanged的类?

非常感谢你的时间。

1 个答案:

答案 0 :(得分:1)

我认为Blam是对的。 (抱歉,我还没有权限添加注释。)在测试代码中,使用ObservableCollection,它实现了INotifyPropertyChanged。 DataGrid将获取对该集合的更改。您应该考虑在实际代码中使用ObservableCollection并通过它更新数据以由绑定的DataGrid拾取,而不是直接通过dataGrid.ItemsSource。

本页答案中的方法可能有所帮助: https://stackoverflow.com/a/1581588/1082026

最后,您的代码可能看起来像这样(注意,您必须定义一个类 DataItem ,它将镜像DataSet的DataTable中的一行,特别是您的 DataGrid 关心):

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()和Remove(),这就是你设置集合的方式:

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.
}

希望有所帮助!