更新数据网格中选定行的复选框

问题描述 投票:0回答:1

WPF 初学者可能会遇到一个非常简单的问题。是否可以选择多行并选中所有选定的复选框?

我想在选中 S501 时选中选定的 S601 和 S701 框

代码:

        public string drawingNumber { get; set; }

        bool isChecked;

        bool isSelected;

        public bool IsSelected
        {
            
            get { return this.isSelected; }
            set { this.Set(() => IsSelected, ref isSelected, value); }
        } 
     
        public bool IsChecked
        {
            get { return this.isChecked; }
            set {
                    this.Set(() => IsChecked, ref isChecked, value);
            }
        }

绑定:

        <DataGrid  ItemsSource="{Binding MyListCollection}" SelectionMode="Extended" AutoGenerateColumns="False" HorizontalAlignment="Stretch" CanUserSortColumns="False" FrozenColumnCount="0" CanUserResizeRows="False" CanUserDeleteRows="False" HeadersVisibility="Column" Padding="0" GridLinesVisibility="Horizontal">
            <DataGrid.ColumnHeaderStyle >
                <Style TargetType="DataGridColumnHeader">
                    <Setter Property="Background" Value="#abf299"></Setter>
                    <Setter Property="Typography.Capitals" Value="AllSmallCaps"></Setter>
                    <Setter Property="FontFamily" Value="ArialNarrow"></Setter>
                </Style>
            </DataGrid.ColumnHeaderStyle>
            <DataGrid.Columns>
                <DataGridTextColumn x:Name="dataGridTextColumn" Header="Number" Binding="{Binding drawingNumber}"  IsReadOnly="True" Width="*" MinWidth="100" />
                <DataGridTemplateColumn Header="Selection">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <CheckBox IsChecked="{Binding IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
            <DataGrid.RowStyle>
                <Style TargetType="{x:Type DataGridRow}">
                    <Setter Property="IsSelected" Value="{Binding Path=IsSelected, UpdateSourceTrigger=PropertyChanged}"/>
                </Style>
            </DataGrid.RowStyle>
        </DataGrid>
c# wpf mvvm checkbox datagrid
1个回答
0
投票

我尝试使用 RelayCommand 并提出了这个解决方案:

  1. 您错过了属性 DrawingNumber 的属性更改。我认为 this.Set 就是为此而设计的,所以:
private string drawingNumber;
public string DrawingNumber { get => drawingNumber; set { drawingNumber = value; this.Set(() => DrawingNumber, ref drawingNumber, value); } }
  1. 您需要在 XAML 代码中进行一些小调整:
    ...
<Window.DataContext>
    <viewModel:MainWindowViewModel />
</Window.DataContext>
<StackPanel>
    <DataGrid  ...
            <DataGridTemplateColumn Header="Selection">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <CheckBox IsChecked="{Binding Path=IsChecked, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                  Command="{Binding Path=DataContext.UpdateCommand, RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
                                  />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>

            </DataGridTemplateColumn>
        </DataGrid.Columns>
        <DataGrid.RowStyle>
            <Style TargetType="{x:Type DataGridRow}">
                <Setter Property="IsSelected" Value="{Binding Path=IsSelected,  UpdateSourceTrigger=PropertyChanged}"/>
            </Style>
        </DataGrid.RowStyle>
    </DataGrid>

    <Button Content="Reset checkboxes" Command="{Binding Path=ResetCommand}" />
</StackPanel>
  1. 这里您需要实现 ICommand 以使用 RelayCommand 来检查复选框是否被按下(或者您可以使用例如 nuget 包:CommunityToolkit.Mvvm 它已经实现了 RelayCommand 以及更多...)
  • 这是一个简单的 RelayCommand 的代码:
    public class RelayCommand : ICommand
    {
        private readonly Action<object> _execute;
        private readonly Predicate<object> _canExecute;
        public RelayCommand(Action<object> execute) : this(execute, param => true) { }
        public RelayCommand(Action<object> execute, Predicate<object> canExecute)
        {
            if (execute == null)
                throw new ArgumentNullException("Invalid action");
            this._execute = execute;
            this._canExecute = canExecute;
        }
        public event EventHandler? CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }
        public bool CanExecute(object parameter)
        {
            return this._canExecute == null ? true : _canExecute(parameter);
        }
        public void Execute(object parameter)
        {
            this._execute(parameter);
        }
    }
  • 这是主要代码:
public class MainWindowViewModel
{
    public ObservableCollection<Item> MyListCollection { get; private set; }

    public MainWindowViewModel()
    {
        UpdateCommand = new RelayCommand(x => UpdateCheckBoxes());
        ResetCommand = new RelayCommand(x => ResetCheckBoxes());

        MyListCollection = new();
        MyListCollection.Add(new() { DrawingNumber = "S201", IsChecked = false });
        MyListCollection.Add(new() { DrawingNumber = "S501", IsChecked = true });
        MyListCollection.Add(new() { DrawingNumber = "S601", IsChecked = false });
        MyListCollection.Add(new() { DrawingNumber = "S701", IsChecked = false });
        MyListCollection.Add(new() { DrawingNumber = "S801", IsChecked = false });
        MyListCollection.Add(new() { DrawingNumber = "S901", IsChecked = true });
    }

    public ICommand UpdateCommand { get; private set; }
    public ICommand ResetCommand { get; private set; }

    public void UpdateCheckBoxes()
    {
        foreach (var item in MyListCollection)
        {
            if (item.IsSelected)
                item.IsChecked = true;
            //else
                //item.IsChecked = false;
        }
    }

    public void ResetCheckBoxes()
    {
        foreach (var item in MyListCollection)
        {
            item.IsChecked = false;
        }
    }
}
  1. 如果您想取消选中该复选框,请在该复选框上按 ctrl+鼠标左键

希望能为您提供有用的代码

© www.soinside.com 2019 - 2024. All rights reserved.