我的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逻辑之前执行,不确定是否会改变。
答案 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命令的全部功能,并能够以您希望的方式扩展它。执行顺序也是有保证的。