如何取消选择 DataGrid 中的所有项目?

Posted

技术标签:

【中文标题】如何取消选择 DataGrid 中的所有项目?【英文标题】:How to unselect all Items in a DataGrid? 【发布时间】:2021-10-18 04:53:05 【问题描述】:

我有一个 WPF-App (.Net Framework 4.7.2.),里面有一个 DataGrid,其中列出了项目。我通过 MVVM-Concept 构建了应用程序,所以我有一个 MainWindowViewModel,在这一层是我的 DataGrid。然后我有一个ProjectsViewModel,里面有一个叫SelectedProject的Property,这是我当前选中的Project。在 ProjectsViewModel 里面,有 ProjectViewModel,在这个 ViewModel 里面,有所有需要的属性,用数据填充我的 DataGrid。

一切正常,但我确实有一个问题......

如果我想取消选择一个项目,我必须通过单击它来选择另一个项目。如何取消选择所有项目,例如通过单击 DataGrid 的外部,所以我的问题是,有没有可能的方法来取消选择 DataGrid 中的所有项目,是否有可能是一个事件或其他什么?

这是我的 DataGrid XAML 代码:

<DataGrid x:Name="Data" x:Uid="Data" Margin="10,41,10,123" DataContext="Binding Path=ProjectsViewModel" ItemsSource="Binding Path=Projects" SelectedItem="Binding Path=SelectedProject" AutoGenerateColumns="False" IsEnabled="Binding Path=IsEditable">
                <DataGrid.RowStyle>
                    <Style TargetType="DataGridRow">
                        <Style.Triggers>
                            <DataTrigger Binding="Binding Path=IsCheckedIn" Value="true">
                                <Setter Property="Background" Value="LightGreen"/>
                            </DataTrigger>
                            <DataTrigger Binding="Binding Path=IsCheckedIn" Value="false">
                                <Setter Property="Background" Value="Transparent"/>
                            </DataTrigger>
                        </Style.Triggers>
                    </Style>
                </DataGrid.RowStyle>
                <DataGrid.Columns>
                    <DataGridTextColumn x:Name="GridHeadProjectNumber" x:Uid="GridHeadProjectNumber" Header="Projekt" Binding="Binding Path=IssueKey" IsReadOnly="True">
                        <DataGridTextColumn.ElementStyle>
                            <Style TargetType="TextBlock">
                                <Setter Property="HorizontalAlignment" Value="Center"/>
                                <Setter Property="Margin" Value="2,0,2,0"/>
                            </Style>
                        </DataGridTextColumn.ElementStyle>
                    </DataGridTextColumn>
                    <DataGridTextColumn x:Name="GridHeadTitle" x:Uid="GridHeadTitle" Header="Titel" Binding="Binding Path=Summary" IsReadOnly="True"/>
                    <DataGridTextColumn x:Name="GridHeadStatus" x:Uid="GridHeadStatus" Header="Status" Binding="Binding Path=Status" IsReadOnly="True"/>
                    <DataGridTextColumn x:Name="GridHeadTimeSpent" x:Uid="GridHeadTimeSpent" Header="Bisher gearbeitete Zeit" Binding="Binding Path=TimeSpent" IsReadOnly="True"/>
                    <DataGridTextColumn x:Name="GridHeadDueDate" x:Uid="GridHeadDueDate" Header="Fälligkeit" Binding="Binding Path=DueDate, StringFormat=0:dd.MM.yyyy HH:mm" IsReadOnly="True"/>
                    <DataGridTextColumn x:Name="GridHeadLastCheckIn" x:Uid="GridHeadLastCheckIn" Header="Letzter Checkin" Binding="Binding Path=LastCheckIn, StringFormat=0:dd.MM.yyyy HH:mm" IsReadOnly="True"/>
                    <DataGridTemplateColumn x:Name="GridButtonCheckIn" x:Uid="GridButtonCheckIn" Header="CheckIn" >
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Button Name="btnCheckIn" Uid="btnCheckIn" Content="Binding Path=CheckInOutText" Command="Binding Path=CheckInCommand" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                    <DataGridTemplateColumn x:Name="GridButtonOpenInBrowser" x:Uid="GridButtonOpenInBrowser" Header="Öffnen" >
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <Button Name="btnOpenInBrowser" Uid="btnOpenInBrowser" Content="Öffnen" Command="Binding Path=OpenInBrowserCommand" />
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>

这是我在 ProjectsViewModel 中的 SelectedProject 属性:

public ProjectViewModel SelectedProject
        
            get => _selectedProject;
            set
            
                _selectedProject = value;
                NotifyPropertyChanged(nameof(SelectedProject));
                CheckInSelectedProjectCommand.NotifyCanExecuteChanged();
                OpenSelectedProjectCommand.NotifyCanExecuteChanged();
                // Minimize()
            
        

这是我的 ProjectViewModel 类:

public partial class ProjectViewModel : ViewModelBase
    
        private readonly IJiraManager _jiraManager;
        private readonly IProjectWorkflow _projectWorkflow;
        private readonly IBroker _broker;
        private Action _checkOutAllProjects;
        private readonly IWindow _window;
        private readonly SettingsViewModel _settingsViewModel;
        private readonly TaskbarViewModel _taskbarViewModel;
        private Project _project;
        private bool _isCheckedIn = false;
        private DateTime? _currentCheckIn;

        public ProjectViewModel(IJiraManager jiraManager, IProjectWorkflow projectWorkflow, Project project, Action checkOutAllProjects, IWindow window, SettingsViewModel settingsViewModel, IBroker broker, TaskbarViewModel taskbarViewModel, IDateTimeProvider dateTimeProvider)
        
            this.InitializeCommands();
            _jiraManager = jiraManager ?? throw new ArgumentNullException(nameof(jiraManager));
            _project = project ?? throw new ArgumentNullException(nameof(project));
            _checkOutAllProjects = checkOutAllProjects ?? throw new ArgumentNullException(nameof(checkOutAllProjects));
            _window = window ?? throw new ArgumentNullException(nameof(window));
            _settingsViewModel = settingsViewModel ?? throw new ArgumentNullException(nameof(settingsViewModel));
            _broker = broker ?? throw new ArgumentNullException(nameof(broker));
            _taskbarViewModel = taskbarViewModel ?? throw new ArgumentNullException(nameof(taskbarViewModel));
            _projectWorkflow = projectWorkflow ?? throw new ArgumentNullException(nameof(projectWorkflow));
            _dateTimeProvider = dateTimeProvider ?? throw new ArgumentNullException(nameof(dateTimeProvider));
        
 
        public bool IsCheckedIn
        
            get => _isCheckedIn;
            set
            
                _isCheckedIn = value;
                NotifyPropertyChanged(nameof(IsCheckedIn));
                NotifyPropertyChanged(nameof(CheckInOutText));
                if (value)
                
                    _broker.Publish(this, new ProjectCheckInMessage(this));
                
                if (_settingsViewModel.MinimizeAfterCheckIn)
                
                    _window.Minimize();
                
            
        
        public DateTime? CurrentCheckIn  get  return _currentCheckIn;  set  _currentCheckIn = value;  
        public string Summary  get => _project.Summary; 
        public string Status  get => _project.Status; 
        public string IssueKey  get => _project.IssueKey; 
        public string TimeSpent  get => _project.TimeSpent; 
        public DateTime? DueDate  get => _project.DueDate; 
        public DateTime? LastCheckIn  get => _project.LastCheckIn; 
        public string CheckInOutText  get => IsCheckedIn ? "Check Out" : "Check In"; 
    

我希望你能帮助我:)

【问题讨论】:

SelectedProject 设置为null 会发生什么?它应该取消选择选定的项目。您可以查看数据网格的 LostFocus 事件以在数据网格焦点移出时放置代码。 如果您的问题是用户必须如何取消选择项目,那么它是在列表控件中按住 ctrl 单击(不确定DataGrid,试试吧)。但请确保您可以采用自己的方式:取消全选按钮、处理控件客户区域之外的点击等。 【参考方案1】:

更新:我使用了 LostFocus 事件并将其绑定到名为 IsProjectSelected 的 porperty,如果该事件被触发,我检查是否为 ProjectIsSelected,如果选择了一个项目,我取消选择它。这是我的代码:

事件处理程序:

LostFocus += MainWindowViewModel.ProjectsViewModel.DataGrid_LostFocus;

事件方法:

public void DataGrid_LostFocus(object sender, RoutedEventArgs e)
        
            if(IsProjectSelected)
            
                IsProjectSelected = false;
            
        

在 SelectedProject 属性的设置器中,我设置了 IsSelectedProject 的值;:

public ProjectViewModel SelectedProject
        
            get => _selectedProject;
            set
            
                _selectedProject = value;
                NotifyPropertyChanged(nameof(SelectedProject));
                CheckInSelectedProjectCommand.NotifyCanExecuteChanged();
                OpenSelectedProjectCommand.NotifyCanExecuteChanged();
                IsProjectSelected = true;
                // Minimize()
            
        

【讨论】:

为什么需要IsProjectSelected 属性?只需从失去焦点事件中设置SelectedProject = null。顺便说一句,订阅视图模型来查看事件不是纯 MVVM,请参阅this topic 如何正确执行此操作,例如带有事件命令抽象。 因为,我的 MainViewModel 中需要 SelectedProject,所以如果我在触发事件时将其设置为零,则无法在 MainWindowViewModel 中使用按钮签入项目

以上是关于如何取消选择 DataGrid 中的所有项目?的主要内容,如果未能解决你的问题,请参考以下文章

c# wpf datagrid中选择所有复选框的代码

从MVVM WPF项目中的DataGrid中选择多个项目

EasyUI datagrid 如何默认选择多行

如何以编程方式选择匹配条件的所有DataGrid行

DataGrid中的事件和方法

WPF Toolkit Datagrid - 如何关闭选择?