问题
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; }
}
and is bound at design-time via
<DataGrid x:Name="dataGrid" ItemsSource="{Binding TestData}".../>
I have created a DataGrid
which gets populated at run-time via
dataGrid.ItemsSource = BuildDataGridColumns(cultureDict).Tables[0].AsDataView();
with
private DataSet BuildDataGridColumns(Dictionary<string, string> cultureDict,
DataTable additionalDt = null)
{
// ...
}
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>
My question is;
How can I create the same binding of my
DataGrid
to the data set I create at run-time?
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.
How can I bind this data to the
DataGrid
as a class that implementsINotifyPropertyChanged
if the structure of the data can change?
Thanks very much for your time.
回答1:
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.
The approach in the answer on this page may help: https://stackoverflow.com/a/1581588/1082026
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");
}
}
With this binding
<DataGrid x:Name="dataGrid" ItemsSource="{Binding TestData}".../>
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.
}
Hope that helps!
来源:https://stackoverflow.com/questions/16063077/how-to-bind-data-to-datagrid-at-run-time