WPF:列表中删除命令的命令参数

Hei*_*nzi 5 data-binding wpf command mvvm viewmodel

在我的视图模型中,我有一个包含项的列表(ObservableCollection)。在视图中,此列表显示在中ItemsControl。每行中都有一个“删除”按钮。我希望按钮后面的命令从列表中删除该项目。

<ItemsControl ItemsSource="{Binding myList}">
    <ItemsControl.ItemTemplate>
        ...
            <Button Command="{StaticResource myDeleteCommand}" CommandParameter="???">
                Remove item
            </Button>
        ...
    </ItemsControl.ItemTemplate>
</ItemsControl>
Run Code Online (Sandbox Code Playgroud)

我要通过什么作为命令参数?

  • 项目本身(Binding .)?然后,我在命令中没有对该列表的引用,因此我需要更改模型,以便每个列表项都包含对该列表的反向引用。
  • 列表?然后,我没有对该项目的引用。
  • 都?然后,我需要编写一个MultiConverter,它将列表和项目转换为一些自定义对象。如此简单的任务似乎有很多开销。

有任何想法吗?对我来说,这似乎是一个相当普遍的情况,因此我想必须有一些公认的最佳实践解决方案...

Art*_*hur 4

我已经以这种方式实现了这样的命令,我将项目作为参数传递。命令 self 知道它应该在哪个列表上操作。通过在我的 ViewModel 中调用删除方法的委托,或者该命令在其构造函数中接收项目列表。

即带有代表的命令

public sealed class SimpleParameterCommandModel<T> : CommandModel
{
    private readonly Action<T> execute;
    private readonly Func<T, bool> canExecute;

    public SimpleParameterCommandModel(string label, string tooltip, Action<T> execute, Func<T, bool> canExecute)
        : base(appCtx, dataCtx, label, tooltip)
    {
        if (execute == null) throw new ArgumentNullException("execute");
        this.execute = execute;
        this.canExecute = canExecute;
    }
    ...
}
Run Code Online (Sandbox Code Playgroud)

用法:

private ICommand _DeleteCommand = null;
public ICommand DeleteCommand
{
    get
    {
        if (_DeleteCommand == null)
        {
            _DeleteCommand = new SimpleParameterCommandModel<IEnumerable<DataObjectModel>>                      ("Delete", "Delete selection from data store", 
                (items) => items.ToList().ForEach(i => DeleteItem(i)),
                (items) => items != null && items.Count() > 0 && AllowDelete);
        }
        return _DeleteCommand;
    }
}
public void DeleteItem(DataObjectModel item)
{
        if (item == null) { throw new ArgumentNullException("item"); }

    myCollection.Remove(item.Object);
}
Run Code Online (Sandbox Code Playgroud)

编辑:忘记XAML

<Button Command="{Binding DeleteCommand, ElementName=...}" CommandParameter="{Binding}">
        Remove item
</Button>
Run Code Online (Sandbox Code Playgroud)