将DataGrid列条目作为参数传递给WPF中的命令

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

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

此主窗口的部分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将在上面主窗口的DataContext类中定义。该类的部分代码如下:

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

已经实现了从数据库加载数据的命令。该实现方式与以下问题的答案非常相似:How to bind WPF button to a command in ViewModelBase?

要实现的目标:

  1. [当选择DataGrid中的项目时,如果选择一项或多项,则激活用于删除命令的UI元素。这已经通过下面的事件处理程序实现了,该事件处理程序位于主窗口的代码背后:
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中实现的命令(对于View是DataContext)。我是WPF的新手,试图了解命令的工作原理。具体来说,此命令应采用IEnumerable<string>的参数,或string的集合。我已经完成并测试了deleteAction方法。 string对象将是DataGrid所选行的“ ISBN”列中的值。
c# .net wpf datagrid command
1个回答
0
投票
的部分XAML

您已经进入了wpf / mvvm的棘手问题之一,因为您理想中想要使用的内容无法绑定。或至少不能直截了当。

如果只想选择和删除一个项目,则可以将selecteditem绑定到窗口视图模型中的属性。该命令可以使用提供删除操作的IBook对象。

由于您要进行多次选择和删除,所以很麻烦,因为您无法绑定整个选定项目列表。这不是可绑定的依赖项属性。

有多种解决方法。

您可以细分数据网格并进行扩展。

您可以使用某种行为。这些操作使您可以封装大量面向事件的代码,并添加一个附加的依赖项属性来存储数据。然后,它本身可以绑定。我建议您通读一些一般的行为,然后用Google搜索一下示例。绑定selecteditems是一个相当普遍的要求,您应该获得许多成功。这是一个。

Select multiple items from a DataGrid in an MVVM WPF project

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

我建议使用observablecollection,您可以在视图模型中订阅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听起来好像不是ViewModel。它应该是。您要绑定的几乎所有未明确标记为OneTime的东西都应该是实现inotifypropertychanged的viewmodel。这是因为存在一个长期存在的错误,否则可能会导致内存泄漏。不必担心您的视图模型是否会泄漏。只需始终使用一个viewmodel并构建一​​个实现inpc的基本viewmodel,以便您可以轻松地继承其中的所有内容。

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