繁体   English   中英

删除 WPF DataGrid 中的选定项目(多选)

[英]Delete selected items in WPF DataGrid (multiselect)

我有一个带有DataGrid 、菜单和按钮的 WPF 应用程序。 DataGrid中的行被选中时,按钮和菜单项被激活,以允许从数据库中删除数据。

此主 window 的部分 XAML:

<Button ToolTip="Delete Record" Command="{Binding DeleteCommand}" Name="button_delete" IsEnabled="False"/>
<MenuItem>
    <MenuItem Header="Delete" IsEnabled="False" Name="menuItem_delete" Command="{Binding DeleteCommand}"/>
</MenuItem>

<DataGrid Name="BooksDataGrid" ItemsSource="{Binding BooksList}" SelectionChanged="dataGrid_selectionChanged">
    <DataGrid.Columns>
         <DataGridTextColumn Header="Title" Binding="{Binding title_long}"/>
         <DataGridTextColumn Header="ISBN" Binding="{Binding isbn}"/>
    </DataGrid.Columns>
</DataGrid>

DeleteCommand 将在 class 中定义,这是上面主要 window 的DataContext 此 class 的部分代码如下:

sealed class BookViewModel
{
    public ObservableCollection<IBook> Books { get; private set; }

    // load data command code

    // delete record command code
    // ...
    public void deleteAction(IEnumerable<string> isbnList)
    {
        // delete data from database
        // this already works
    }
}

已经实现了一个从数据库加载数据的命令。 这以与以下问题的答案非常相似的方式实现: 如何将 WPF 按钮绑定到 ViewModelBase 中的命令?

要达到的目标:

  1. 选择DataGrid中的项目时,如果选择了一个或多个项目,则删除命令的 UI 元素将被激活。 这已经通过以下事件处理程序实现,在主 window 的代码隐藏中:
private void dataGrid_selectionChanged(object sender, SelectionChangedEventArgs args)
{
    // this works

    // if nothing is selected, disable delete button and menu item
    if (BooksDataGrid.SelectedItems.Count == 0)
    {
         button_deleteBook.IsEnabled = false;
         menuItem_deleteBook.IsEnabled = false;
    }
    else
    {
        // delete command can now be executed, as shown in the binding in XAML
        button_deleteBook.IsEnabled = true;
        menuItem_deleteBook.IsEnabled = true;
    }
}
  1. 要执行的删除命令。 目前尚不清楚的是如何将参数传递给在 ViewModel 中实现的命令(视图的DataContext )。 我是 WPF 的新手,并试图了解命令的工作原理。 具体来说,此命令应采用IEnumerable<string>的参数,或者可能是string的集合。 我已经完成并测试了deleteAction方法。 string对象将是DataGrid选定行的“ISBN”列中的值。

您已经进入了 wpf / mvvm 的棘手部分之一,因为您理想地想要使用的东西不能被绑定。 或者至少不是直接开箱即用。

如果您只想要一个项目 select 并删除,那么您可以将 selecteditem 绑定到 window 视图模型中的属性。 该命令可以使用 IBook object 进行删除。

由于您想要多项选择和删除,这是一个复杂的问题,因为您无法绑定整个选定项目列表。 这不是可绑定的依赖属性。

有很多方法可以解决这个问题。

您可以子 class 数据网格并扩展。

或者

你可以使用一种行为。 这些允许您做的是封装一大块面向事件的代码并添加附加的依赖属性来存储数据。 这本身就是可绑定的。 我建议您阅读有关行为的一般性内容并在 Google 上搜索一下示例。 绑定 selecteditems 是一个相当普遍的要求,您应该会获得一些命中。 这是一个。

Select MVVM WPF 项目中 DataGrid 的多个项目

如果您可以在视图模型中使用 IBook,您最终会得到一个 observablecollection 列表。

我推荐 observablecollection,你可以订阅 viewmodel 中的 collectionchanged 事件,这样你就可以检查计数。 使用 0 为您的命令的 CanExecute 返回 false,使用 1+ true。

https://docs.microsoft.com/en-us/dotnet/api/system.windows.input.icommand.canexecute?view=netcore-3.1#System_Windows_Input_ICommand_CanExecute_System_Object_

您的 iBook 听起来不像是视图模型。 它应该是。 您绑定的几乎所有未明确标记为 OneTime 的东西都应该是实现 inotifypropertychanged 的视图模型。 这是因为存在一个长期存在的错误,否则可能导致 memory 泄漏。 不要担心您的视图模型是否会泄漏。 只需始终使用视图模型并构建一个基本视图模型实现 inpc,这样您就可以轻松地从中继承所有内容。

最简单的解决方案是使用内置DataGrid.DeleteCommand

默认情况下, DataGrid已经支持行/单元格删除。 通常不需要自己创建复杂的东西。 我会认为这是浪费时间。

DataGrid公开了一个static DataGrid.DeleteCommand ,这是一个路由命令。 DataGrid使用CommandManager.RegisterClassCommandBinding侦听此命令。
除了DataGrid.DeleteCommand之外,还支持DataGrid.BeginEditCommand ( Key.F2 )、 DataGrid.CommitEditCommandDataGrid.CancelEditCommand ( Key.Escape )、 DataGrid.SelectAllCommandApplicationCommands.Copy

您可以随时按CRTL + A到 select 所有行,然后按DEL删除选定的行。

如果要添加鼠标输入控制的删除,则应在每一行添加一个删除按钮。 这是最直观、最成熟的表格设计。
这样做,删除单行用户不需要执行四个操作:首先导航到目标行,然后在行上执行 select 行命令,然后第三导航到删除按钮,最后按下删除按钮。 用户现在可以直接按下行的删除按钮。
这删除了两个操作以完成目标(删除一行)。 在用户体验 (UX) 方面,必须使用尽可能少的用户操作和尽可能少的鼠标移动来实现目标。
多选删除仍然是可能的。 用户必须 select 目标行,然后只需按随机删除按钮。 DataGrid执行 rest 例如启用/禁用删除按钮。

下面的示例使用DataGridTemplateColumn向每一行添加一个删除Button 该示例假定一个包含两列的表,它们是自动生成的。 通过将第三个删除按钮列的DataGridTemplateColumn.DisplayIndex设置为2 ,将此列放置在最右侧。
您可以使用DataGrid.FrozenColumnCount属性来防止删除列滚动,即固定列,这需要 position 最左边的删除列。

<DataGrid AutoGenerateColumns="True">
  <DataGrid.Columns>
    <DataGridTemplateColumn DisplayIndex="2">
      <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
          <Button Content="X" 
                  Command="{x:Static DataGrid.DeleteCommand}" />
        </DataTemplate>
      </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
  </DataGrid.Columns>
</DataGrid>

暂无
暂无

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

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