Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/wpf/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从ListItem内部触发外部ICommands/函数_C#_Wpf_Mvvm_Data Binding_Icommand - Fatal编程技术网

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>