繁体   English   中英

如何选择WPF DataGrid中DataGrid Header CheckBox上列的所有CheckBox

[英]How to Select All CheckBox of a Column on DataGrid Header CheckBox in WPF DataGrid

我面临 WPF DataGrid Checkboxes C# 的问题。

Im not finding a way to select all cell template checkboxes when the header template checkbox is selected. 在视图模型中它工作正常。 它得到全选,但在视图中它没有在选中的标题复选框上显示任何选定的复选框符号/标记。我遇到的问题与 DataGrid(WPF) 中的复选框有关

单击此链接我想做同样的我的 XAML 代码:

<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>

视图模型代码:

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)));
}

请找到工作代码。 我对你的代码做了一些修改

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"); }
        }
    }

DataGrid列定义不继承DataContext因为它们不是可视化树的一部分。

您将不得不使用BindingProxy ¹ 来解决此问题。

<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
}

还要记住,您的 VM 中没有 UI 控件,也没有XXX_Clicked处理程序或类似的。 如有必要,它们属于代码隐藏文件 (*.xaml.cs)。


¹您也可以检查这个问题。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM