0

First two ways are working for me, the third and fourth points mentioned below by me are not working

  1. if i check the header check box ,all the child checkbox will be checked
  2. if uncheck, all will be unchecked
  3. if everything is checked..if i uncheck one child checkbox...header checkbox will be unchecked
  4. if i check one by one all the child checkbox....header checkbox will be checked.

Here is my code

<DataGridTemplateColumn>
    <DataGridTemplateColumn.Header>
        <CheckBox Content="Included" x:Name="headerCheckBox" />
    </DataGridTemplateColumn.Header>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <CheckBox Name="chkselectAll" IsChecked="{Binding IsChecked,ElementName=headerCheckBox,Mode=OneWay}"></CheckBox>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn> 

could I get some help here. How do I achieve it in xaml?

select all checkbox

I want the select all checkbox behaviour like this

https://www.codeproject.com/Articles/42437/Toggling-the-States-of-all-CheckBoxes-Inside-a-Dat#

  • 1
    Possible duplicate of [Datagrid Column header should check / uncheck CheckBox’s state depending upon whether all CheckBoxes of a DataGridView column are checked or unchecked](https://stackoverflow.com/questions/10208004/datagrid-column-header-should-check-uncheck-checkbox-s-state-depending-upon-wh) – Chris Aug 07 '17 at 07:19
  • @Chris It is not a duplicate as I want the answer/suggestions in the mvvm pattern. My question/requirement is the same as you said. Kindly suggest. – Padmaja Vudatha Aug 07 '17 at 16:20

1 Answers1

2

You should bind the CheckBox in the CellTemplate to a source property of your data object:

<DataGridTemplateColumn.CellTemplate>
    <DataTemplate>
        <CheckBox Name="chkselectAll" IsChecked="{Binding IsChecked, UpdateSourceTrigger=PropertyChanged}"></CheckBox>
    </DataTemplate>
</DataGridTemplateColumn.CellTemplate>

Make sure that the data object implements the INotifyPropertyChanged interface:

public class Item : INotifyPropertyChanged
{
    private bool _isChecked;
    public bool IsChecked
    {
        get { return _isChecked; }
        set { _isChecked = value; OnPropertyChanged(); }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}

You could then bind bind the property of the header CheckBox to a property of your view model, that you set whenever an item in the source collection of the DataGrid is changed, e.g.:

<DataGridTemplateColumn.Header>
    <CheckBox Content="Included"
                x:Name="headerCheckBox"
                IsChecked="{Binding DataContext.AllChecked, RelativeSource={RelativeSource AncestorType=DataGrid}}"/>
</DataGridTemplateColumn.Header>

public class ViewModel : INotifyPropertyChanged
{
    public ViewModel()
    {
        Items = new ObservableCollection<Item>();
        Items.CollectionChanged += Items_CollectionChanged;

        //add the items..:
        Items.Add(new Item());
        Items.Add(new Item() { IsChecked = true });
        Items.Add(new Item());
    }

    private void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        if (e.NewItems != null)
        {
            foreach (object item in e.NewItems)
            {
                (item as INotifyPropertyChanged).PropertyChanged += new PropertyChangedEventHandler(item_PropertyChanged);
            }
        }

        if (e.OldItems != null)
        {
            foreach (object country in e.OldItems)
            {
                (country as INotifyPropertyChanged).PropertyChanged -= new PropertyChangedEventHandler(item_PropertyChanged);
            }
        }
    }

    private void item_PropertyChanged(object sender, PropertyChangedEventArgs e)
    {
        OnPropertyChanged("AllChecked");
    }

    public ObservableCollection<Item> Items { get; private set; }

    public bool AllChecked
    {
        get { return Items.All(x => x.IsChecked); }
        set
        {
            foreach (var item in Items)
                item.IsChecked = value;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnPropertyChanged([CallerMemberName] string propertyName = "")
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }
}
mm8
  • 163,881
  • 10
  • 57
  • 88
  • public ProgramViewModel(SFProgram program, bool hasBeenCreated) : base(null, true) { Items = new ObservableCollection(); Items.CollectionChanged += Items_CollectionChanged; //add the items..: Items.Add(new Item()); Items.Add(new Item() { IsChecked = true }); Items.Add(new Item()); _program = program; – Padmaja Vudatha Aug 07 '17 at 10:36
  • could you tell me how to add the items and also my constructor is parameterized ,is that fine? could you provide me any simpler solution in xaml or viewmodel.cs as we use mvvm pattern – Padmaja Vudatha Aug 07 '17 at 10:38
  • My sample is clearly MVVM...don't you know how to add items to a collection or what are you asking? – mm8 Aug 07 '17 at 11:41
  • this line i didnt understand Items.Add(new Item() { IsChecked = true }); – Padmaja Vudatha Aug 07 '17 at 16:22
  • It adds a new item that is checked by default to the source collection. – mm8 Aug 08 '17 at 08:50