Krzaku
Krzaku

Reputation: 196

WPF DataGrid binding doesn't update

Here's my DataGrid:

<DataGrid x:Name="MoonMining" 
          ItemsSource="{Binding MarketData.MoonMinerals, ElementName=window}">
    <DataGrid.DataContext>
        <local:MoonMineral/>
    </DataGrid.DataContext>
    <DataGrid.Columns>
        .. Yes i have columns and they are irrelevant to my question .
    </DataGrid.Columns>
</DataGrid>

MarketData is a class which contains most of my programs logic. MoonMinerals is defined in that class:

public class MarketData
{
   private ObservableCollection<MoonMineral> _moonMinerals = new ObservableCollection<MoonMineral>();

   public ObservableCollection<MoonMineral> MoonMinerals
   {
       get { return _moonMinerals; }
       set { _moonMinerals = value; }
   }
 }

And here's my MoonMineral class:

[NotifyPropertyChanged]
public class MoonMineral
{
    public MoonMineral()
        : this("Def", "Def")
    {
    }

    public MoonMineral(string name, string rarity)
    {
        Name = name;
        Rarity = rarity;
    }

    public string Name { get; set; }
    public double Price { get; set; }
    public double Volume { get; set; }
    public string Rarity { get; set; }
    public double TransportVolume { get; set; }
    public double TransportCosts { get; set; }
    public double GrossProfit { get; set; }
    public double NetProfit { get; set; }
}

As you can see, I'm using PostSharp to clear up my code, but when I manually implement INotifyPropertyChanged I have the same problem.

Now the problem is that my DataGrid doesn't update by itself, I have to manually call this in a method which modifies MoonMinerals:

var bindingExpression = MoonMining.GetBindingExpression(ItemsControl.ItemsSourceProperty);
if (bindingExpression != null)
    bindingExpression.UpdateTarget();

I know this isn't big of a deal, but I wanted to finally manage to bind data to ui entirely using xaml. All my previous attempts involved setting DataGrids ItemsSource property every time I updated the data.

Upvotes: 1

Views: 4573

Answers (1)

dkozl
dkozl

Reputation: 33364

To sum up comments you're implementing INotifyPropertyChanged interface for MoonMineral class and use ObservableCollection which will handle changes to the collection but there seems to be nothing in place to handle changes to MoonMinerals property

private ObservableCollection<MoonMineral> _moonMinerals = new ObservableCollection<MoonMineral>();

public ObservableCollection<MoonMineral> MoonMinerals
{
    get { return _moonMinerals; }
    set { _moonMinerals = value; }
}

You can either implement INotifyPropertyChanged interface in the class that exposes MoonMinerals property or change it to read-only and use only one instance of _moonMinerals and simply clear it and add/remove items

private readonly ObservableCollection<MoonMineral> _moonMinerals = new ObservableCollection<MoonMineral>();

public ObservableCollection<MoonMineral> MoonMinerals
{
    get { return _moonMinerals; }
}

Also, as a side note, you don't need

<DataGrid.DataContext>
    <local:MoonMineral/>
</DataGrid.DataContext>

as this will set DataContext of the DataGrid to new instance of MoonMineral. It works in your case as you change binding context of ItemsSource using ElementName so DataContext is not used in your case.

Upvotes: 4

Related Questions