在wpf中有什么优雅的方法来处理命令和单击事件吗?
本文关键字:命令 处理 单击 事件 方法 wpf 什么 | 更新日期: 2023-09-27 18:06:12
我在WPF应用程序中有一个自定义控件,它有一个Apply按钮。当用户单击按钮时,我想在我的视图模型(业务逻辑)上执行命令,但我也想为用户界面执行一些事件。
在我看来,如果我使用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逻辑之前执行,不确定这是否会改变事情。
您可以使用System.Windows.Interactivity.InvokeCommandAction
来调用您的ProccessCommand
:
<i:Interaction.Triggers>
<i:EventTrigger EventName="Click">
<i:InvokeCommandAction Command="{Binding DataContext.ProcessCommand}" />
</i:EventTrigger>
</i:Interaction.Triggers>
您可以将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命令的全部功能,并能够以您想要的方式扩展它。执行顺序也是有保证的。