Borja López
Borja López

Reputation: 2393

WPF DataGrid binding confusion

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

Answers (2)

Ahmad Alloush
Ahmad Alloush

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

har07
har07

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

Related Questions