Reputation: 701
I am having difficulty binding a DataGridCheckBoxColumn in a DataGrid in WPF.
What I am trying to do is have a "Select All" button to check all the items in the grid.
<Button Grid.Row="1" Grid.Column="0" Content="Select All In List" HorizontalAlignment="Stretch" Command="{Binding SelectAll}"></Button>
In my ViewModel I have a Command that is called from the button.
public ICommand SelectAll { get; set; }
private void OnSelectAll(object obj)
{
foreach (var item in EducationLeaflets)
{
item.Selected = true;
}
OnPropertyChanged("EducationLeaflets");
}
This is my property from my ViewModel that I bind my DataGrid to:
public ObservableCollection<LeafletListModel> EducationLeaflets { get; private set; }
My DataGrid with a DataGridCheckBoxColumn as the first column.
<DataGrid Grid.Row="0" Grid.Column="0"
AutoGenerateColumns="False"
EnableRowVirtualization="True"
ItemsSource="{Binding EducationLeaflets}"
RowDetailsVisibilityMode="VisibleWhenSelected"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Grid.ColumnSpan="3" Background="White" HorizontalGridLinesBrush="#FFF0F0F0" VerticalGridLinesBrush="#FFF0F0F0">
<DataGrid.Columns>
<DataGridCheckBoxColumn
Binding="{Binding Path=Selected, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
</DataGridCheckBoxColumn>
<DataGridTextColumn
Binding="{Binding Id}"
Header="RecordId"
Width="SizeToHeader" />
<DataGridTextColumn
Binding="{Binding Name}"
Header="Name"
Width="*" />
</DataGrid.Columns>
</DataGrid>
Also the model that is displayed in each grid row.
public class LeafletListModel: ListModel
{
public LeafletListModel(int id, string name, DateTime bpsDrugsUpdated):base(id, name)
{
BpsDrugsUpdated = bpsDrugsUpdated;
}
public bool Selected { get; set; }
public DateTime BpsDrugsUpdated { get;private set; }
}
When I click the button the items in the DataGrid are not checked as I would like. Thank you for your help.
Upvotes: 0
Views: 1706
Reputation: 690
It is not EducationLeaflets
that changes - it stays the same ObservableCollection as before clicking SelectAll
. Even its content does not change (this would be reflected in the CollectionChanged
event from the ObservableCollection.
What actually changes are the individual items in the ObservableCollection. And since these do not implement INotifyPropertyChanged, the update will not be reflected in the Views.
So, if you make LeafletListModel
implement INotifyPropertyChanged
, it should
work as expected.
public class LeafletListModel: ListModel, INotifyPropertyChanged
{
private bool _selected;
public LeafletListModel(int id, string name, DateTime bpsDrugsUpdated):base(id, name)
{
BpsDrugsUpdated = bpsDrugsUpdated;
}
public bool Selected
{
get { return _selected; }
set
{
if (_selected != value)
{
_selected = value;
OnPropertyChanged();
}
}
}
public DateTime BpsDrugsUpdated { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
Upvotes: 2