是否有任何优雅的方法来处理wpf中的命令和单击事件?

时间:2014-06-02 19:25:54

标签: c# wpf mvvm icommand click

我的WPF应用程序中有一个自定义控件,它有一个应用按钮。当用户单击该按钮时,我想在我的视图模型(业务逻辑)上执行命令,但我也想为用户界面执行一些事件。

在我看来,如果我使用Command属性,我就无法使用Click事件处理程序。但是,我真的不想把我的逻辑混合在一起(一些逻辑是业务逻辑,一些是UI逻辑)。

目前,我已经决定从后面的代码调用ICommand.Execute方法并使用Click事件。现在的问题是我无法利用ICommand.CanExecute方法。

public class OrderViewModel : ViewModelBase
{
    public DelegateCommand ProcessCommand { get; private set; }

    public void Process(object parameter)
    {
        // Business logic here...
    }
}

<Button Click="OnProcess_Click" />

public void OnProcess_Click(object sender, RoutedEventArgs e)
{
    ViewModel.ProcessCommand.Execute();

    // Do UI specific stuff...
}

我觉得我这样做的方式很糟糕,特别是因为我失去了全部ICommand.CanExecute的好处,但我不知道我还能在这做什么。

更新:我认为值得一提的是,我更希望我的命令在UI逻辑之前执行,不确定是否会改变。

2 个答案:

答案 0 :(得分:1)

您可以使用System.Windows.Interactivity.InvokeCommandAction来调用ProccessCommand

 <i:Interaction.Triggers>
        <i:EventTrigger EventName="Click">
            <i:InvokeCommandAction Command="{Binding DataContext.ProcessCommand}" />
        </i:EventTrigger>
  </i:Interaction.Triggers>

答案 1 :(得分:1)

您可以将Button的Command属性绑定到视图中的命令,该命令执行与当前事件处理程序相同的逻辑。受益于此,可以定义切换按钮启用状态的CanExecute。这样您就可以从ViewModel的命令传播CanExecute逻辑。例如:

您可以在根控件上有一个命令:

<Button Command="{Binding ProcessCommand, ElementName=root, Mode=OneWay}" />

以上代码段适用于具有x:Name="root"的控件,但您可以根据需要为其命名。或者,您可以选择另一种导航到根控件的方式,并在代码隐藏中定义您的视图命令。命令可以如下:

    private ICommand _processCommand;

    public ICommand ProcessCommand
    {
        get { return _processCommand ?? (_processCommand = new DelegateCommand(Process, CanProcess)); }
    }

    private bool CanProcess(object obj)
    {
        return ViewModel.ProcessCommand.CanExecute(obj);
    }

    private void Process(object obj)
    {
        ViewModel.ProcessCommand.Execute(obj);

        // Do UI specific stuff...
    }

这样,您将重用ViewModel命令的全部功能,并能够以您希望的方式扩展它。执行顺序也是有保证的。