1

I have been looking for two days and I have tried different things but without success

441/5000 I have a datagrid with a checkbox column with a checkbox header.

When I check the header checkbox, I have all my checkboxes checked and the reverse works too.

My problem:

If I check the header checkbox, all my column checkboxes are checked but if I uncheck one my header checkbox does not go off.

Can you help me ? How do I dynamically change the isChecked property of my header checkbox?

Candidate.cs

 public class Candidate : INotifyPropertyChanged
{
    public int CandidateID { get; set; }
    public int RegisterNo { get; set; }
    public string CandidateName { get; set; }
    private bool _IsSelected = false;
    private bool _IsChecked = false;
    public bool IsSelected { get { return _IsSelected; } set { _IsSelected = value; OnChanged("IsSelected"); } }


    #region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;
    private void OnChanged(string prop)
    {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(prop));
    }

    #endregion
}

MainWindows.xaml.cs

    public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        List<Candidate> tmp = new List<Candidate>();
        tmp.Add(new Candidate()
        {
            CandidateID = 1,
            CandidateName = "One",
            RegisterNo = 1
        });
        tmp.Add(new Candidate()
        {
            CandidateID = 2,
            CandidateName = "Two",
            RegisterNo = 2
        });
        tmp.Add(new Candidate()
        {
            CandidateID = 3,
            CandidateName = "Three",
            RegisterNo = 3
        });
        dgCandidate.ItemsSource = tmp;


    }
    private void chkSelectAll_Checked(object sender, RoutedEventArgs e)
    {
        foreach (Candidate c in dgCandidate.ItemsSource)
        {
            c.IsSelected = true;
        }
    }

    private void chkSelectAll_Unchecked(object sender, RoutedEventArgs e)
    {
        foreach (Candidate c in dgCandidate.ItemsSource)
        {
            c.IsSelected = false;
        }
    }
}

XAML

        <DataGrid AutoGenerateColumns="False" CanUserAddRows="False" Height="130" HorizontalAlignment="Left" IsReadOnly="False" Margin="62,164,0,0" Name="dgCandidate" TabIndex="7" VerticalAlignment="Top" Width="466" >
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="colCandidateID" Binding="{Binding CandidateID}" Header="SlNo" MinWidth="20" IsReadOnly="True" />
                <DataGridTextColumn x:Name="colRegistraion" Binding="{Binding RegisterNo}" Header="Reg. No." IsReadOnly="True"  />
                <DataGridTextColumn x:Name="colCandidate" Binding="{Binding CandidateName}" Header="Name" MinWidth="250" IsReadOnly="True"  />
                <DataGridCheckBoxColumn Binding="{Binding IsSelected}">
                    <DataGridCheckBoxColumn.Header>
                        <CheckBox Name="chkSelectAll" IsChecked="True"  Checked="chkSelectAll_Checked" Unchecked="chkSelectAll_Unchecked"></CheckBox>
                    </DataGridCheckBoxColumn.Header>
                </DataGridCheckBoxColumn>
            </DataGrid.Columns>
        </DataGrid>

I'm curious to see how we can do this?

Sorry for my english and thank you in advance

Neotof Tof
  • 53
  • 1
  • 9
  • 1
    Does this answer your question? [How to Select All CheckBox of a Column by DataGrid Header CheckBox in WPF DataGrid](https://stackoverflow.com/questions/13081725/how-to-select-all-checkbox-of-a-column-by-datagrid-header-checkbox-in-wpf-datagr) – pete the pagan-gerbil Jan 12 '20 at 17:28
  • @PavelAnikhouski The code is in my post: MainWindows.xaml.cs – Neotof Tof Jan 12 '20 at 18:47
  • @petethepagan-gerbil I read the other similar post but I don't understand How to create the view model? – Neotof Tof Jan 12 '20 at 19:42
  • The Candidate view models are created in MainWindow.xaml.cs - is that what you mean? Or a different view model? – pete the pagan-gerbil Jan 13 '20 at 07:49

1 Answers1

0

You need to determine whether to check or uncheck chkSelectAll whenever an individual item is checked. You can to this by handling the PropertyChanged for all Candidate objects:

public MainWindow()
{
    InitializeComponent();
    List<Candidate> tmp = new List<Candidate>();
    tmp.Add(new Candidate()
    {
        CandidateID = 1,
        CandidateName = "One",
        RegisterNo = 1
    });
    tmp.Add(new Candidate()
    {
        CandidateID = 2,
        CandidateName = "Two",
        RegisterNo = 2
    });
    tmp.Add(new Candidate()
    {
        CandidateID = 3,
        CandidateName = "Three",
        RegisterNo = 3
    });
    dgCandidate.ItemsSource = tmp;

    foreach (Candidate candidate in tmp)
    {
        candidate.PropertyChanged += Candidate_PropertyChanged;
    }
}

private void Candidate_PropertyChanged(object sender, PropertyChangedEventArgs e)
{
    _handle = false;
    chkSelectAll.IsChecked = (dgCandidate.ItemsSource as IEnumerable<Candidate>)?
        .All(x => x.IsSelected) == true;
    _handle = true;
}

private bool _handle;
private void chkSelectAll_Checked(object sender, RoutedEventArgs e)
{
    if (_handle && dgCandidate.IsLoaded)
    {
        foreach (Candidate c in dgCandidate.ItemsSource)
        {
            c.IsSelected = true;
        }
    }
}

private void chkSelectAll_Unchecked(object sender, RoutedEventArgs e)
{
    if (_handle)
    {
        foreach (Candidate c in dgCandidate.ItemsSource)
        {
            c.IsSelected = false;
        }
    }
}

You probably also want to set the UpdateSourceTrigger of the binding to PropertyChanged for the source property to get set immediately:

<DataGridCheckBoxColumn Binding="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged}">
    <DataGridCheckBoxColumn.Header>
        <CheckBox Name="chkSelectAll" Checked="chkSelectAll_Checked" Unchecked="chkSelectAll_Unchecked"></CheckBox>
    </DataGridCheckBoxColumn.Header>
</DataGridCheckBoxColumn>
mm8
  • 163,881
  • 10
  • 57
  • 88