如何取消选择 DataGrid 中的所有项目?
How to unselect all Items in a DataGrid?
我有一个 WPF-App (.Net Framework 4.7.2.),里面有一个 DataGrid,其中列出了项目。我通过 MVVM 概念构建应用程序,所以我有一个 MainWindowViewModel,在这一层上是我的 DataGrid。然后我有一个 ProjectsViewModel,里面有一个名为 SelectedProject 的 属性,这是我当前 selected 的项目。在 ProjectsViewModel 内部,有 ProjectViewModel,在这个 ViewModel 内部,有所有需要的属性,用数据填充我的 DataGrid。
一切正常,但我确实有一个问题...
如果我想取消select 一个项目,我必须select 另一个项目,方法是单击它。我怎样才能取消select所有项目,例如通过单击 DataGrid 的外部,所以我的问题是,是否有任何可能的方法取消selectDataGrid 中的所有项目,是否有也许是一个事件,或者别的什么?
这是我的 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 Class:
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"; }
}
希望你能帮助我:)
更新:我使用了 LostFocus 事件并将其绑定到名为 IsProjectSelected 的属性,如果事件被触发,我检查是否有 ProjectIsSelected,如果项目被选中,我将取消选择它。这是我的代码:
事件处理程序:
LostFocus += MainWindowViewModel.ProjectsViewModel.DataGrid_LostFocus;
事件方法:
public void DataGrid_LostFocus(object sender, RoutedEventArgs e)
{
if(IsProjectSelected)
{
IsProjectSelected = false;
}
}
在SelectedProject的setter中属性我设置了IsSelectedProject的值;:
public ProjectViewModel SelectedProject
{
get => _selectedProject;
set
{
_selectedProject = value;
NotifyPropertyChanged(nameof(SelectedProject));
CheckInSelectedProjectCommand.NotifyCanExecuteChanged();
OpenSelectedProjectCommand.NotifyCanExecuteChanged();
IsProjectSelected = true;
// Minimize()
}
}
我有一个 WPF-App (.Net Framework 4.7.2.),里面有一个 DataGrid,其中列出了项目。我通过 MVVM 概念构建应用程序,所以我有一个 MainWindowViewModel,在这一层上是我的 DataGrid。然后我有一个 ProjectsViewModel,里面有一个名为 SelectedProject 的 属性,这是我当前 selected 的项目。在 ProjectsViewModel 内部,有 ProjectViewModel,在这个 ViewModel 内部,有所有需要的属性,用数据填充我的 DataGrid。
一切正常,但我确实有一个问题...
如果我想取消select 一个项目,我必须select 另一个项目,方法是单击它。我怎样才能取消select所有项目,例如通过单击 DataGrid 的外部,所以我的问题是,是否有任何可能的方法取消selectDataGrid 中的所有项目,是否有也许是一个事件,或者别的什么?
这是我的 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 Class:
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"; }
}
希望你能帮助我:)
更新:我使用了 LostFocus 事件并将其绑定到名为 IsProjectSelected 的属性,如果事件被触发,我检查是否有 ProjectIsSelected,如果项目被选中,我将取消选择它。这是我的代码:
事件处理程序:
LostFocus += MainWindowViewModel.ProjectsViewModel.DataGrid_LostFocus;
事件方法:
public void DataGrid_LostFocus(object sender, RoutedEventArgs e)
{
if(IsProjectSelected)
{
IsProjectSelected = false;
}
}
在SelectedProject的setter中属性我设置了IsSelectedProject的值;:
public ProjectViewModel SelectedProject
{
get => _selectedProject;
set
{
_selectedProject = value;
NotifyPropertyChanged(nameof(SelectedProject));
CheckInSelectedProjectCommand.NotifyCanExecuteChanged();
OpenSelectedProjectCommand.NotifyCanExecuteChanged();
IsProjectSelected = true;
// Minimize()
}
}