3

在 MVVM/WPF 环境中,我想在引发 ListView 事件ComputeCommand时在 ViewModel 上调用命令 () 。SelectionChanged在 XAML 或 C# 中如何做到这一点?

这是我的命令类。我已经MainViewModel.Instance.MyCommand.Execute();在代码隐藏中尝试过,但它不接受这一点。

public class ComputeCommand : ICommand
{
    public ComputeCommand(Action updateReport)
    {
        _executeMethod = updateReport;
    }

    Action _executeMethod;

    public bool CanExecute(object parameter)
    {
        return true;
    }

    public event EventHandler CanExecuteChanged;

    public void Execute(object parameter)
    {
        _executeMethod.Invoke();
    }
}       
4

4 回答 4

2

我真的推荐使用像MVVM Light这样的 Mvvm 框架,所以你可以这样做:

XAML:

xmlns:MvvmLight_Command="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras"
xmlns:Custom="clr-namespace:System.Windows.Interactivity;  assembly=System.Windows.Interactivity"

 <ListBox>
 ...
     <Custom:Interaction.Triggers>
          <Custom:EventTrigger EventName="SelectionChanged ">
             <MvvmLight_Command:EventToCommand PassEventArgsToCommand="False" Command="{Binding Path=ComputeCommand}"/>
          </Custom:EventTrigger>
     </Custom:Interaction.Triggers>

</Listbox>

视图模型:

public RelayCommand ComputeCommand{ get; private set; }

这是 IMO 一种优雅的方式,可以让您的活动线路保持整洁。

于 2013-03-07T10:03:26.543 回答
2

要回答您的问题 - 您缺少一个参数。这个电话应该有效:

MainViewModel.Instance.MyCommand.Execute(null);

但是,您不需要 ICommand,这个接口有不同的用途。

您需要的是在视图侧处理 SelectionChanged

var vm = DataContext as YourViewModelType;
if (vm != null)
{
    vm.Compute(); //some public method, declared in your viewmodel
}

或通过绑定到项目容器的 IsSelected 属性在视图模型端处理它

于 2013-03-07T09:24:58.150 回答
1

通常:要在引发控件事件时调用命令,可以使用 EventTriggers。

<ListView>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="SelectionChanged" >
            <i:InvokeCommandAction Command="{Binding CommandToBindTo}" CommandParameter="{Binding CommandParameterToBindTo}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</ListView>

为此,您需要在 XAML中引用System.Windows.Interactivity.dll :

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

话虽如此,您应该使用 MVMM 框架,例如 MVVM 来简化一般命令的实现。从长远来看,为您需要的每个命令设置一个类是不可维护的。像 MVVMLight 或 PRISM 这样的框架提供了DelegateCommands允许您直接从委托(ViewModel 上的方法)创建新命令。

于 2013-03-07T10:25:40.843 回答
0

首先,您必须为 定义一个绑定Command,因此必须在调用命令时执行该函数。

可以在 XAML 中完成,例如:

<CommandBinding Command="name_of_the_namespace:ComputeCommand" Executed="ComputeCommandHandler" />

之后,您可以例如在某些类中初始化命令,例如:

 public class AppCommands {
    public static readonly ICommand ComputeCommand = 
             new   RoutedCommand("ComputeCommand", typeof(AppCommands));
 }

之后可以像这样使用它:

 AppCommands.ComputeCommand.Execute(sender);

当您处理 .so模式时WPFMVVM您需要像往常一样编写更多的代码,但要受益于它的灵活性。

于 2013-03-07T09:19:32.747 回答