0

I have a DataGrid bound to a list of a simple object and a Checkbox that I want to set/unset the Selected field of those objects in the list.

The code below does not work. Clicking the Select All checkbox changes the data but the grid is not updated. However, if I change

get => this._ordersToTransmit; 

to

get => this._ordersToTransmit.ToList(); 

then the grid IS updated and it works properly.

Can anyone explain to me why I need to put the ToList() there? Maybe I should be doing something entirely different?

class ViewModel
{
     private List<OrderListItem> _ordersToTransmit;

     public List<OrderListItem> OrdersToTransmit 
     { 
          get => this._ordersToTransmit; 
          set => this.SetProperty(ref this._ordersToTransmit, value); 
     }

    public bool SelectAll
    {
        get => this._selectAll;
        set
        {
            this.SetProperty(ref this._selectAll, value);

            foreach (OrderListItem item in this._ordersToTransmit)
                item.Selected = value;

            this.RaisePropertyChanged(nameof(TransmitOrdersViewModel.OrdersToTransmit));
        }
    }
}
<CheckBox Content="Select All" IsChecked="{Binding SelectAll, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

<DataGrid ItemsSource="{Binding OrdersToTransmit}"  AutoGenerateColumns="False">
     <DataGrid.Columns>
          <DataGridCheckBoxColumn Binding="{Binding Selected}" />
     </DataGrid.Columns>
</DataGrid>
thatguy
  • 21,059
  • 6
  • 30
  • 40
  • Where do you set the `OrdersToTransmit` property? Are you trying to update the `Selected` column/property of the existing items only or what are you trying to do? – mm8 Aug 10 '20 at 15:25
  • It's in the constructor. It's a DataGrid of items, there's a checkbox above the DataGrid, when that is checked, all the items should have their Selected property checked –  Aug 10 '20 at 23:41

1 Answers1

0

You raise NotifyPropertyChanged for the list, but the list is not actually changing: the items inside the list are changing.

You can:

  • raise NotifyPropertyChanged for each item of the list.
  • replace the whole list, which is what you do when you call ToList(): a new list object is created on the fly.
  • force a refresh of your DataGrid: see How to refresh datagrid in WPF
corradolab
  • 718
  • 3
  • 16
  • In the situation without ToList(), in which the grid is not updated after clicking Select All: If I delete ItemsSource="{Binding OrdersToTransmit}" and reenter it, the grid clears and then reappears with the correct data (ie, all checked) This leads me to believe that RaisePropertyChanged should refresh this setting and show the updated data, just like when I delete and reenter the xaml. Is this incorrect? –  Aug 09 '20 at 06:22
  • You are calling RaisePropertyChanged (OrdersToTransmit). If you set OrdersToTransmit = null it is a new empty obejct and the grid become empty. If you set OrdersToTransmit = new List() it is a new object and the grid show whatever the list contains. If you modify the already existing list, it's the same object and nothing happens, until you also raise something to say things inside the list changed. See ObservableCollection https://learn.microsoft.com/en-us/dotnet/api/system.collections.objectmodel.observablecollection-1?view=netcore-3.1 – corradolab Aug 10 '20 at 08:48