Reputation: 2393
I'm a bit confused with the WPF data binding. I've tried a lot of examples, but I think I'm not understanding the basics of this topic.
I have the following datagrid, binded to an ObservableCollection(Of T), where T class has a Name attribute which is shown in the datagrid column. My T class also implements the INotifyPropertyChanged and fires the event properly when the Name property changes.
<DataGrid Grid.Row="1" Name="MyDataGrid" AutoGenerateColumns="False" ItemsSource="{Binding}" >
<DataGrid.Columns>
<DataGridTextColumn x:Name="NameColumn" Header="Name" Binding="{Binding Name}" />
</DataGrid.Columns>
</DataGrid>
Then, in the code-behind class, I have the underlying collection which is feeding the datagrid.
public ObservableCollection<T> MyCollection
{
get;
set;
}
Finally, when my application starts, I load the "MyCollection" property and tell the datagrid to use that collection.
public void InitApp()
{
MyCollection = [... taking data from somewhere ...];
MyDataGrid.ItemsSource = MyCollection;
}
This is all working fine (the data is shown properly). But then, if I reload the collection (taking again completely different data from somewhere), if I do not execute again the MyDataGrid.ItemsSource = MyCollection; instruction, the datagrid is not updated.
I think it's not a good practise using the XXX.ItemsSource = YYY every time I reload data, so that I guess I'm doing something wrong. In some examples I saw that the XAML DataGrid is binded like:
<DataGrid ItemsSource="{Binding CollectionName}">
...
</DataGrid>
that I guess is aimed at using that collection, so that there's no need to do .ItemsSource programmatically... but I could not make it run.
Can anyone show me the light at the end of the tunnel?
Upvotes: 2
Views: 408
Reputation: 151
You didn't explain the most important part which is how do you implement the filling? if you do it by assigning new collection reference to the old variable then it won't work because the collection is a reference type any way to solve your problem you can do one of two things (beside your solution) : the first is to define the ObservableCollection as a Dependency property in your window and then you can use it. the second and the easiest is to clear the collection and then add the new items using foreach loop from the source collection here is an example for the first case :
public static readonly DependencyProperty MyCollectionProperty = DependencyProperty.Register("MyCollection", typeof(ObservableCollection<T>), typeof(MainWindow));
public ObservableCollection<T> MyCollection
{
get
{
return this.GetValue(MyCollectionProperty) as string;
}
set
{
this.SetValue(MyCollectionProperty, value);
}
}
//assign the collection value at any time
MyCollection = ......
//you can bind it as the past
Upvotes: 0
Reputation: 89285
You can data-bind DataGrid's ItemsSource
instead of assigning it manually. Simply declare MyCollection
as public property, raise PropertyChanged
notification properly, and set DataContext
for your DataGrid
(or set DataContext
for Window where the DataGrid resides) :
private ObservableCollection<MyClass> _myCollection
public ObservableCollection<MyClass> MyCollection
{
get { return _myCollection; }
set
{
_myCollection = value;
NotifyPropertyChanged("MyCollection");
}
}
public void InitApp() {
MyCollection = [... taking data from somewhere ...];
MyDataGrid.DataContext = this;
}
<DataGrid ItemsSource="{Binding MyCollection}">
...
</DataGrid>
UPDATE :
Your approach also declare binding in XAML :
<DataGrid Grid.Row="1" Name="MyDataGrid"
AutoGenerateColumns="False"
ItemsSource="{Binding}" >
and that should work without setting ItemsSource
but setting it's DataContext to the collection :
public void InitApp() {
MyCollection = [... taking data from somewhere ...];
MyDataGrid.DataContext = MyCollection;
}
In theory (because I haven't specifically tried scenario in this question), with ItemsSource
binding your DataGrid will automatically updated whenever collection reloaded, when setting ItemsSource
manually can't bring the same effect.
Upvotes: 1