Search code examples
c#wpfxamldatagridpropertychanged

DataGridColumn not updating on PropertyChanged


My DataGrid is not updating the values in my ObservableCollection when a property is changed (it does show the initial values). I've looked over many other SO articles and did not find my problem so far. I'm using the following XAML

<DataGrid Name="downloadingGrid" IsReadOnly="True" AutoGenerateColumns="False" CanUserResizeRows="False">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding Path=Title}" Header="Title" />
        <DataGridTextColumn Binding="{Binding Path=Size}" Header="Size" />
        <DataGridTextColumn Binding="{Binding Path=Done, Mode=OneWay, UpdateSourceTrigger=PropertyChanged,NotifyOnTargetUpdated=True}" Header="Done" />
        <DataGridTextColumn Binding="{Binding Path=Progress}" Header="Progress" />
    </DataGrid.Columns>
</DataGrid>

In my code I have the SongDownloading class, that implements the INotifyPropertyChanged interface like this:

 private long done;
 public long done;
 public event PropertyChangedEventHandler PropertyChanged;

 public SongDownloading()
 {
     done = 0;
 }

 public long Done
 {
     get { return done; }
     set
     {
         done = value;
         OnPropertyChanged("Property Change");
     }
 }

 protected void OnPropertyChanged(String e)
 {
     PropertyChangedEventHandler handler = PropertyChanged;
     if (handler != null)
         handler(this, new PropertyChangedEventArgs(e));
 }

Then there's my main class:

public ObservableCollection<SongDownloading> downloading = new ObservableCollection<SongDownloading>();
private SongDownloading songToBeDownloaded;

public MainWindow() {
    InitializeComponent();
    downloadingGrid.ItemsSource = downloading;
}

public void test() {
    downloading.Add(new SongDownloading());
    songToBeDownloaded = downloading[0]; 
    System.Timers.Timer t = new System.Timers.Timer();
    t.Interval = 1000;
    t.Elapsed += new System.Timers.ElapsedEventHandler(changeValue);
    t.Start();
}

private void changeValue(object sender, ElapsedEventArgs e)
{
    songToBeDownloaded.Done += 1;
}

Of course there is a lot more code, but that's beyond the scope of the question, and thus removed to improve readability.

The PropertyChanged event does fire, and the songToBeDownloaded's Done value does change. I've checked and double checked. So there's something wrong with the binding to the DataGridColumn. I've gone over nearly every SO article that's related and tried everything, but it does not work. Likely it's a stupid mistake somewhere, but I cannot figure it out for the life of me.


Solution

  • You should pass the name of the property, i.e "Done", to the OnPropertyChanged method instead of the string "Property Change" for the value in the view to get refreshed as expected:

    public long Done
    {
        get { return done; }
        set
        {
            done = value;
            OnPropertyChanged("Done"); //<--
        }
    }
    

    If you are susing C#6 / Visual Studio 2015 you could use the nameof operator:

    OnPropertyChanged(nameof(Done));