C# 从ListItem内部触发外部ICommands/函数
我想知道从内部列表项触发外部函数(或命令)的最佳方法是什么 例如,我有一个C# 从ListItem内部触发外部ICommands/函数,c#,wpf,mvvm,data-binding,icommand,C#,Wpf,Mvvm,Data Binding,Icommand,我想知道从内部列表项触发外部函数(或命令)的最佳方法是什么 例如,我有一个FooManager对象,它包含一个名为MyFoos的Foo对象的可观察集合。FooManager还有一个名为ProcessFoo(Foo-Foo)的函数 我使用Prism的DelegateCommand,我认为这是绑定到命令的最简单方法。它有很多其他命令选项,用途相当广泛。如果您有visual studio,请转到工具>NuGet软件包管理器>管理软件包,在浏览搜索Prism并安装Prism.Core中。或者,您可以创
FooManager
对象,它包含一个名为MyFoos
的Foo
对象的可观察集合。FooManager还有一个名为ProcessFoo(Foo-Foo)
的函数
我使用Prism的DelegateCommand,我认为这是绑定到命令的最简单方法。它有很多其他命令选项,用途相当广泛。如果您有visual studio,请转到工具>NuGet软件包管理器>管理软件包,在浏览搜索Prism并安装Prism.Core中。或者,您可以创建自己的DelegateCommand来实现ICommand接口。delegatecommand的另一个选项位于本文底部:,它使用wpf mvvm工具包。以下是prism的一个实现:
view.xaml:
<Button Command="{Binding FooCommand}" />
您可能希望将“FooCommand=new…”移动到ViewModel构造函数。多亏了@Clemens。在FooManager类中,添加一个以FooVM为参数的命令。然后,DataTemplate中的按钮可以通过在绑定中使用相对资源
,并将自身(一个空的{binding}
)作为参数来触发此操作
<StackPanel DataContext="FooManager">
<ListView ItemsSource="{Binding MyFoos}" >
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<Button Content="Do Something"
Command="{Binding Path=DataContext.ProcessFoo, RelativeSource={RelativeSource AncenstorType=ListView}}
CommandParameter={Binding} />
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>
绑定到ListView的DataContext:Command=“{Binding Path=DataContext.SomeFooCommand,RelativeSource={RelativeSource AncestorType=ListView}}”
在这种情况下,将Foo本身作为CommandParameter传递是否正确?在何种意义上正确?如果命令需要访问当前项,您肯定会将当前的Foo实例作为命令参数传递。抱歉-“最佳实践”中的“正确”。谢谢你的帮助@Clemens!这看起来确实是MVVM的一个很好的实现。然而,这并不能解决我绑定到控件数据上下文之外的命令的问题,我在你的问题中并没有看到这一点。您要求使用最干净的MVVM方法,这就是问题所在。我不确定对命令的无限制访问是否是一种“干净”的MVVM方法。我更新了我的答案,将Start()更改为ProcessFoo()方法,您可以向列表控件添加一个名称并传入SelectedItems。
public DelegateCommand FooCommand { get; private set; }
FooCommand = new DelegateCommand(OnFoo, CanFoo);
private void OnFoo()
{
ProcessFoo(ListViewName.SelectedItems);
}
private bool CanFoo()
{
return someBooleanFunc();
}
<StackPanel DataContext="FooManager">
<ListView ItemsSource="{Binding MyFoos}" >
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<Button Content="Do Something"
Command="{Binding Path=DataContext.ProcessFoo, RelativeSource={RelativeSource AncenstorType=ListView}}
CommandParameter={Binding} />
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackPanel>