WPF:列表中删除命令的命令参数
在我的viewmodel中,我有一个包含项的列表(ObservableCollection)。在视图中,此列表显示在WPF:列表中删除命令的命令参数,wpf,data-binding,mvvm,command,viewmodel,Wpf,Data Binding,Mvvm,Command,Viewmodel,在我的viewmodel中,我有一个包含项的列表(ObservableCollection)。在视图中,此列表显示在ItemsControl中。每行中都有一个“删除”按钮。我想要按钮后面的命令从列表中删除该项 <ItemsControl ItemsSource="{Binding myList}"> <ItemsControl.ItemTemplate> ... <Button Command="{StaticReso
ItemsControl
中。每行中都有一个“删除”按钮。我想要按钮后面的命令从列表中删除该项
<ItemsControl ItemsSource="{Binding myList}">
<ItemsControl.ItemTemplate>
...
<Button Command="{StaticResource myDeleteCommand}" CommandParameter="???">
Remove item
</Button>
...
</ItemsControl.ItemTemplate>
</ItemsControl>
...
删除项目
...
我应该传递什么作为命令参数
- 项目本身(
)?然后,我在命令中没有对列表的引用,因此我需要更改模型,使每个列表项都包含对列表的反向引用绑定。
- 名单?那我就没有提到这个项目了
- 两者都有?然后,我需要编写一个多转换器,将列表和项目转换为一些自定义对象。对于这样一个简单的任务来说,似乎有很多开销
有什么想法吗?这对我来说似乎是一个相当常见的场景,所以我想一定有一些成熟的最佳实践解决方案…我已经以这种方式实现了这样的命令,我将该项作为参数传递。命令本身知道它应该在哪个列表上操作。通过调用my ViewModel中的Delete方法的委托,或者该命令接收其构造函数中的项列表 i、 e.有代表的命令
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;
}
...
}
公共密封类SimpleParameterCommandModel:CommandModel
{
私有只读操作执行;
私有只读功能可执行;
公共SimpleParameterCommandModel(字符串标签、字符串工具提示、操作执行、Func canExecute)
:base(appCtx、dataCtx、标签、工具提示)
{
如果(execute==null)抛出新的ArgumentNullException(“execute”);
this.execute=execute;
this.canExecute=canExecute;
}
...
}
用法:
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);
}
private ICommand _DeleteCommand=null;
公共ICommand delete命令
{
得到
{
如果(_DeleteCommand==null)
{
_DeleteCommand=new SimpleParameterCommandModel(“删除”,“从数据存储中删除所选内容”,
(items)=>items.ToList().ForEach(i=>DeleteItem(i)),
(items)=>items!=null&&items.Count()>0&&AllowDelete);
}
返回_delete命令;
}
}
公共void DeleteItem(DataObjectModel项)
{
如果(item==null){抛出新的ArgumentNullException(“item”);}
myCollection.Remove(item.Object);
}
编辑:XAML
<Button Command="{Binding DeleteCommand, ElementName=...}" CommandParameter="{Binding}">
Remove item
</Button>
删除项目
首先,我将处理ViewModel中的命令。我假设用于绑定的列表在ViewModel中,因此任何对该列表“起作用”的代码也应该在ViewModel中完成
class MyViewModel
{
// ... Clipping rest of ViewModel class ...
private ObservableCollection<MyObject> mMyList = new ObservableCollection<MyObject>();
private ICommand mMyDeleteCommand;
public MyViewModel()
{
InitializeMyListSomehow();
mMyDeleteCommand = new MyCommandClass(
(item) => DeleteItem(item),
() => mDeleteCanExecute
);
}
public ObservableCollection<MyObject> MyList
{
get { return mMyList; }
set
{
// Some function that updates the value and implements INPC
SetProperty("MyList", ref mMyList, value);
}
}
public ICommand MyDeleteCommand
{
get { return mMyDeleteCommand; }
}
void DeleteHandler(var item)
{
int index = mMyList.Remove(item);
}
}
类MyViewModel
{
//…正在剪裁ViewModel类的其余部分。。。
私有ObservableCollection mMyList=新ObservableCollection();
私有ICommand和mmydelete命令;
公共MyViewModel()
{
InitializeMyList();
mMyDeleteCommand=newmycommandclass(
(项目)=>删除项目(项目),
()=>mDeleteCanExecute
);
}
公共可观测集合MyList
{
获取{return mMyList;}
设置
{
//更新值并实现INPC的某些函数
SetProperty(“MyList”,参考mMyList,值);
}
}
公共ICommand mydelete命令
{
获取{return mMyDeleteCommand;}
}
void DeleteHandler(变量项)
{
int index=mMyList.Remove(项目);
}
}
这些物品是独一无二的吗?如果是这样,您可以传递该项,并且Delete命令处理程序可以在列表中查找该项
<ItemsControl ItemsSource="{Binding myList}">
<ItemsControl.ItemTemplate>
...
<Button Command="{StaticResource myDeleteCommand}" CommandParameter="???">
Remove item
</Button>
...
</ItemsControl.ItemTemplate>
</ItemsControl>
如果项目是非唯一的,那么您必须根据预期结果执行更多的逻辑操作
现在,在视图中,您的代码如下所示(请注意,StaticResource变成了一个绑定):
...
删除项目
...
code中没有对mMyList
的引用。视图中显示了多个这样的列表。很抱歉-我没有注意到该命令是静态资源。通常,在MVVM解决方案中[据我所知]命令是在ViewModel中处理的,而不是在视图中处理的。我将更新我的答案以反映这一点。谢谢!是的,将命令放入列表的viewmodel中确实是一种方法。我接受了亚瑟的解决方案,因为他速度快了一点,但你的解决方案也非常有用!丹克!:-)是的,为列表的每个实例创建单独的命令确实是解决方案。