0

Im facing an issue with WPF DataGrid Checkboxes C#.

Im not finding a way to select all cell template checkboxes when the header template checkbox is selected. in viewmodel its working fine. it get select all but in view it no showing any selected checkbox sign/mark on checked header checkbox.The problem I'm stuck with is related to checkbox in DataGrid(WPF)

click this link I want to do same like this My XAML code :

<DataGrid x:Name="DgLines" ItemsSource="{Binding OpcUaEndpoints}"
          MouseDoubleClick="DgLines_MouseDoubleClick" SelectionMode="Extended"  
          DataContext="{Binding}"  IsReadOnly="True" Grid.ColumnSpan="5">
    <DataGrid.Columns>
        <DataGridTemplateColumn
            <DataGridTemplateColumn.HeaderTemplate>
                <DataTemplate>
                    <CheckBox Name="ckbSelectedAll"  Checked="ckbSelectedAll_Checked" Unchecked="ckbSelectedAll_Unchecked"
                              IsChecked="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged}"></CheckBox>
                </DataTemplate>
            </DataGridTemplateColumn.HeaderTemplate>
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <CheckBox Name="cbkSelect" Checked="cbkSelect_Checked" Unchecked="cbkSelect_Unchecked"
                              IsChecked="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged}"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>

        <!--<DataGridTextColumn Width="200" Header="Id" Binding="{Binding Id }" />-->

        <DataGridTextColumn Width="200" Header="Name" Binding="{Binding Name}"/>
        <DataGridTextColumn Width="500" Header="Description" Binding="{Binding Description}"/>
        <DataGridTextColumn Width="500" Header="Lines" Binding="{Binding Endpoint}"/>
    </DataGrid.Columns>
</DataGrid>

ViewModelCode:

private void ckbSelectedAll_Unchecked(object sender, RoutedEventArgs e)
{
    //  this.DgLines.UnselectAll();
    foreach (AddLinesViewModel c in DgLines.ItemsSource)
    {
        c.IsSelected = false;
    }
}

private static OpcUaEndpointsListViewModel _instance;
private static readonly object Padlock = new object();
private ICommand _addCommand;
private ICommand _uncheckCommand;
private ICommand _searchcommand;
private ObservableCollection<AddOpcUaEndpointsViewModel> _endpoint;
public string _charNameFromTB;

public OpcUaEndpointsListViewModel()
{
    BindDataGrid();
}

public static OpcUaEndpointsListViewModel Instance
{
    get
    {
        lock (Padlock)
        {
            return _instance ?? (_instance = new OpcUaEndpointsListViewModel());
        }
    }
}

/// <summary>
///     //OPC UA Endpoint List
/// </summary>
public ObservableCollection<AddOpcUaEndpointsViewModel> OpcUaEndpoints
{
    get => _endpoint;
    set
    {
        if (OpcUaEndpoints == value)
        {
            _endpoint = value;
            OnPropertyChanged("OpcUaEndpoints");
        }
    }
}

public string CharNameFromTB
{
    get { return _charNameFromTB; }
    set
    {
        _charNameFromTB = value;
        OnPropertyChanged("CharNameFromTB");
    }
}

public ICommand AddCommand
{
    get { return _addCommand ?? (_addCommand = new RelayCommand(p => ExecuteAddCommand())); }
}

public ICommand SearchCommand
{
    get { return _searchcommand ?? (_searchcommand = new RelayCommand(p => ExecuteSearchCommand())); }
}

private void ExecuteSearchCommand()
{
    BindDataGridsearch();
}

private void BindDataGrid()
{
    var opcendptsModel = opcUaEndpointsService.GetAll();
    _endpoint = new ObservableCollection<AddOpcUaEndpointsViewModel>(opcendptsModel.Select(p => new AddOpcUaEndpointsViewModel(p)));
}
Blacktempel
  • 3,935
  • 3
  • 29
  • 53
San Dy
  • 27
  • 8
  • You have not implemented MVVM at all. – KyloRen Sep 09 '18 at 12:03
  • yup not MVVM, can you post your ViewModel and its related objects? – Mac Sep 09 '18 at 13:44
  • yes sir I have implemented MVVM. i'm getting all selected value on header check box checked in View Models but not showing in – San Dy Sep 09 '18 at 13:48
  • Updated View Model and its related objects in code. Please find it above. – San Dy Sep 09 '18 at 13:55
  • If you are using MVVM, then why do you have an event handler named `ckbSelectedAll_Unchecked`. There is no separations of concerns. ie, if you were to delete `private void ckbSelectedAll_Unchecked` you would get a compile error. – KyloRen Sep 09 '18 at 22:26
  • https://stackoverflow.com/questions/10208004/datagrid-column-header-should-check-uncheck-checkbox-s-state-depending-upon-wh Check this Link... Possible Duplicate. – iYadav Sep 11 '18 at 06:00
  • @KyloRen I got your point. but then where i do write this code ? which i wrote in event handler? private void ckbSelectedAll_Unchecked(object sender, RoutedEventArgs e) { // this.DgEndpoints.UnselectAll(); foreach (AddLinesViewModel c in DgEndpoints.ItemsSource) { c.IsSelected = false; } } – San Dy Sep 11 '18 at 06:21
  • @iYadav i'm trying can you tell me when it says YourClass in dataGrid1.Items.OfType().ToList() means actually what i have to mention there in the code? – San Dy Sep 11 '18 at 06:28
  • @SanDy, what I showed was how you should be setting up your commands in MVVM. The point is that `private void ckbSelectedAll_Unchecked(object sender, RoutedEventArgs e)` is not MVVM at all. You would need to replace that handler with `public void OnUnCheckExecute(object parameter)`. See link on how `DelegateCommand` works. https://www.wpftutorial.net/DelegateCommand.html – KyloRen Sep 11 '18 at 08:20

2 Answers2

2

Please find working code. I have made some modification to your code

XAML

    <DataGrid x:Name="DgLines" ItemsSource="{Binding OpcUaEndpoints}" AutoGenerateColumns="False"
                     SelectionMode="Extended"  IsReadOnly="True" Grid.ColumnSpan="5">
                        <DataGrid.Columns>
                            <DataGridTemplateColumn>
                                <DataGridTemplateColumn.HeaderTemplate>
                                <DataTemplate>
                                    <CheckBox Name="ckbSelectedAll" 
                                          IsChecked="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged}">
                                            <i:Interaction.Triggers>
                                                <i:EventTrigger EventName="Checked" >
                                                    <i:InvokeCommandAction Command="{Binding DataContext.CheckedCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" />
                                                </i:EventTrigger>
                                                <i:EventTrigger EventName="Unchecked" >
                                                    <i:InvokeCommandAction Command="{Binding DataContext.UncheckedCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" />
                                                </i:EventTrigger>
                                            </i:Interaction.Triggers>
                                        </CheckBox>
                                </DataTemplate>
                                </DataGridTemplateColumn.HeaderTemplate>
                                <DataGridTemplateColumn.CellTemplate>
                                    <DataTemplate>
                                        <CheckBox Name="cbkSelect" 
                                          IsChecked="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged}"/>
                                    </DataTemplate>
                                </DataGridTemplateColumn.CellTemplate>
                            </DataGridTemplateColumn>
            
                            <!--<DataGridTextColumn Width="200" Header="Id" Binding="{Binding Id }" />-->
            
                            <DataGridTextColumn Width="200" Header="Name" Binding="{Binding Name}"/>
                            <DataGridTextColumn Width="500" Header="Description" Binding="{Binding Description}"/>
                            <DataGridTextColumn Width="500" Header="Lines" Binding="{Binding Endpoint}"/>
                        </DataGrid.Columns>
                    </DataGrid>
        

c#

        public class OpcUaEndpointsListViewModel : INotifyPropertyChanged
            {
                private static OpcUaEndpointsListViewModel _instance;
                private static readonly object Padlock = new object();
                private ICommand _addCommand;
                //private ICommand _uncheckCommand;
                private ICommand _searchcommand;
                private ICommand _checkedCommand { get; set; }
                private ICommand _unCheckedCommand { get; set; }
        
                private ObservableCollection<AddOpcUaEndpointsViewModel> _endpoint;
                public string _charNameFromTB;
        
                public event PropertyChangedEventHandler PropertyChanged;
        
                public OpcUaEndpointsListViewModel()
                {
                    BindDataGrid();
                }
        
                public static OpcUaEndpointsListViewModel Instance
                {
                    get
                    {
                        lock (Padlock)
                        {
                            return _instance ?? (_instance = new OpcUaEndpointsListViewModel());
                        }
                    }
                }
        
                /// <summary>
                ///     //OPC UA Endpoint List
                /// </summary>
                public ObservableCollection<AddOpcUaEndpointsViewModel> OpcUaEndpoints
                {
                    get { return _endpoint; }
                    set
                    {
                        if (OpcUaEndpoints == value)
                        {
                            _endpoint = value;
                            OnPropertyChanged("OpcUaEndpoints");
                        }
                    }
                }
        
                public string CharNameFromTB
                {
                    get { return _charNameFromTB; }
                    set
                    {
                        _charNameFromTB = value;
                        OnPropertyChanged("CharNameFromTB");
                    }
                }
        
                public ICommand AddCommand
                {
                    get { return _addCommand ?? (_addCommand = new WpfApplication1.RelayCommand<object>(p => ExecuteAddCommand())); }
                }
        
                public ICommand SearchCommand
                {
                    get { return _searchcommand ?? (_searchcommand = new RelayCommand<object>(p => ExecuteSearchCommand())); }
                }
        
        
                public ICommand CheckedCommand
                {
                    get { return _checkedCommand ?? (_checkedCommand = new WpfApplication1.RelayCommand<object>(p => ExecuteCheckedCommand())); }
                }
                public ICommand UncheckedCommand
                {
                    get { return _unCheckedCommand ?? (_unCheckedCommand = new WpfApplication1.RelayCommand<object>(p => ExecuteUnCheckedCommand())); }
                }
        
        
                private void ExecuteSearchCommand()
                {
                    ///BindDataGridsearch();
                }
        
                private void ExecuteCheckedCommand()
                {
                    foreach (var item in _endpoint)
                    {
                        item.IsSelected = true;
                    }
                }
        
                private void ExecuteUnCheckedCommand()
                {
                    foreach (var item in _endpoint)
                    {
                        item.IsSelected = false;
                    }
                }
        
                private void ExecuteAddCommand()
                {
                    ///BindDataGridsearch();
                }
        
                private void BindDataGrid()
                {
                    _endpoint = new ObservableCollection<AddOpcUaEndpointsViewModel>();
                    _endpoint.Add(new AddOpcUaEndpointsViewModel { Name = "A", Description = "A", Endpoint = 1 });
                    _endpoint.Add(new AddOpcUaEndpointsViewModel { Name = "B", Description = "B", Endpoint = 2 });
                    _endpoint.Add(new AddOpcUaEndpointsViewModel { Name = "C", Description = "C", Endpoint = 3 });
                    _endpoint.Add(new AddOpcUaEndpointsViewModel { Name = "D", Description = "D", Endpoint = 4 });
                    _endpoint.Add(new AddOpcUaEndpointsViewModel { Name = "E", Description = "E", Endpoint = 5 });
                }
        
                public void OnPropertyChanged(string propertyName)
                {
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
                }
            }

public class AddOpcUaEndpointsViewModel : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string propertyName)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        private string _name;

        public string Name
        {
            get { return _name; }
            set { _name = value; OnPropertyChanged("Name"); }
        }

        private string _description;

        public string Description
        {
            get { return _description; }
            set { _description = value; OnPropertyChanged("Description"); }
        }

        private int _endPoint;

        public int Endpoint
        {
            get { return _endPoint; }
            set { _endPoint = value; OnPropertyChanged("Endpoint"); }
        }

        private bool _isSelected;

        public bool IsSelected
        {
            get { return _isSelected; }
            set { _isSelected = value; OnPropertyChanged("IsSelected"); }
        }
    }
Antikhippe
  • 6,316
  • 2
  • 28
  • 43
0

The DataGrid column definitions do not inherit the DataContext as they're not part of the visual tree.

You will have to use a BindingProxy¹ to get around this.

<DataGrid.Resources>
    <attached:BindingProxy x:Key="proxy" Data="{Binding}"/>
</DataGrid.Resources>
<DataGridTemplateColumn>
    <DataGridTemplateColumn.Header>
        <CheckBox IsChecked="{Binding Data.IsHeaderCheckBoxChecked, Source={StaticResource proxy}}"/>
    </DataGridTemplateColumn.Header>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <CheckBox IsChecked="{Binding IsSelected, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"/>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

BindingProxy

public class BindingProxy : Freezable
{
    #region XAML Properties

    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register(nameof(Data), typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));

    public object Data
    {
        get { return GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    #endregion

    #region Freezable

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    #endregion
}

Also remember that there are no UI-controls in your VM and no XXX_Clicked handler or smiliar. These belong in the code-behind file (*.xaml.cs), if necessary.


¹ You may also check this question.

Blacktempel
  • 3,935
  • 3
  • 29
  • 53
  • I added BindingProxy file and Datagrid.Resource.. but it showing error: Items collection must be empty before using ItemsSource. am I defining the ItemsSource twice? – San Dy Sep 11 '18 at 06:12
  • Data="{Binding}" /> what i need to bind here in data ? – San Dy Sep 11 '18 at 06:46
  • @SanDy `Data="{Binding}"` is already correct. Unfortunately I cannot see your current code. You can post another question with your mentioned error if you're unable to solve it by yourself. But you did put the `DataGridTemplateColumn` inside of `DataGrid.Columns` correct ? This could trigger the error. – Blacktempel Sep 11 '18 at 10:25