如何在 WPF 中将按钮绑定到 DataGrid 删除命令

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/24362089/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 11:59:14  来源:igfitidea点击:

How to Bind Button to DataGrid Delete Command in WPF

wpfmvvmcommandbinding

提问by THW

I'd like to delete rows from a WPF DataGrid by clicking a button above (not inside) the DataGrid, following the MVVM pattern. Although delete buttons within a row itself work, they are kind of ugly (one has to select the row first) and as there are also add and edit buttons next to the delete button, a delete button would better fit there, I think. The corresponding part in my ViewModel looks like this:

我想按照 MVVM 模式,通过单击 DataGrid 上方(不是内部)的按钮从 WPF DataGrid 中删除行。尽管一行中的删除按钮本身可以工作,但它们有点丑陋(必须先选择该行)并且因为删除按钮旁边还有添加和编辑按钮,我认为删除按钮更适合那里。我的 ViewModel 中的相应部分如下所示:

<Button Grid.Row="0" Grid.Column="0" Content="add"/>
<Button Grid.Row="0" Grid.Column="1" Content="edit"/>
<Button Grid.Row="0" Grid.Column="2" Content="delete"/>
<DataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" 
    ItemsSource="{Binding dataTableListItems}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name"/>
        <!--I don't wan't to use these "in-Row" delete buttons-->
        <DataGridTemplateColumn Header="delete">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Command="Delete" Content="X"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

Any ideas on how Command Binding for the buttons could look like? Or alternatively, I could also be satisfied if the in-rowdelete buttons would always be enabled and a click on one would delete the corresponding row withoutneeding to select the row first.

关于按钮的命令绑定看起来如何的任何想法?或者,如果行内删除按钮始终处于启用状态,并且单击一个按钮将删除相应的行无需先选择该行,我也可以感到满意。

回答by d.moncada

Assuming you're using MVVM, just bind to the SelectedItemof the DataGrid and use it whenever the Command is invoked.

假设您使用的是 MVVM,只需绑定到SelectedItemDataGrid 的 ,并在调用 Command 时使用它。

Example ViewModel:

示例视图模型:

public class MyViewModel : INotifyPropertyChanged
{
    private Item _selectedItem;
    public Item SelectedItem 
    {
        get { return _selectedItem; }
        set
        {
            _selectedItem = value;
            RaisePropertyChanged("SelectedItem");
        }
    }

    private ObservableCollection<Item> _dataTableListItems;
    public ObservableCollection<Item> DataTableListItems 
    {
        get { return _dataTableListItems; }
        set
        {
            _dataTableListItems = value;
            RaisePropertyChanged("DataTableListItems")
        }  
    }


    public ICommand DeleteCommand { get; set; }

    public MyViewModel()
    {
        DeleteCommand = new RelayCommand(DeleteSelected);
    }

    private void DeleteSelected()
    {
        if (null != SelectedItem)
        {
            DataTableListItems.Remove(SelectedItem);
        }
    }
}

Updated XAML:

更新的 XAML:

<Button Grid.Row="0" Grid.Column="0" Content="add"/>
<Button Grid.Row="0" Grid.Column="1" Content="edit"/>
<Button Grid.Row="0" Grid.Column="2" Content="delete" Command="{Binding DeleteCommand}"/>
<DataGrid Grid.Row="1" Grid.Column="0" Grid.ColumnSpan="3" 
    ItemsSource="{Binding dataTableListItems}"
    SelectedItem="{Binding SelectedItem}">
    <DataGrid.Columns>
        <DataGridTextColumn Header="Name"/>
        <!--I don't wan't to use these "in-Row" delete buttons-->
        <DataGridTemplateColumn Header="delete">
            <DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <Button Command="Delete" Content="X"/>
                </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
        </DataGridTemplateColumn>
    </DataGrid.Columns>
</DataGrid>

回答by aepot

In addition to accepted answer. The example of missing above RelayCommandclass

除了接受的答案。上面RelayCommand类缺失的例子

public class RelayCommand : ICommand
{
    private readonly Action<object> _execute;
    private readonly Func<object, bool> _canExecute;

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }
    public RelayCommand(Action<object> execute, Func<object, bool> canExecute = null)
    {
        _execute = execute;
        _canExecute = canExecute;
    }
    public bool CanExecute(object parameter) => _canExecute == null || _canExecute(parameter);

    public void Execute(object parameter) => _execute(parameter);
}

Usage in ViewModel class:

在 ViewModel 类中的用法:

public ICommand myCommand => new RelayCommand(obj =>
{
    // your _execute Action code here
},
obj =>
{
    // (optional)
    // return boolean here as Function _canExecute, it may affect Enabled property of the Control
    return true;
});

where objis bindable CommandParameterin XAML

这里obj是绑定CommandParameter在XAML