我正在使用MVVM设计模式构建应用程序,我想使用ApplicationCommands类中定义的RoutedUICommands.由于View的CommandBindings属性(读取UserControl)不是DependencyProperty,因此我们无法将ViewModel中定义的CommandBindings直接绑定到View.我通过定义一个抽象的View类来解决这个问题,该类基于ViewModel接口以编程方式绑定它,该接口确保每个ViewModel都有一个ObBableCollection的CommandBindings.这一切都很好,但是,在某些情况下我想执行在不同类(View和ViewModel)相同命令中定义的逻辑.例如,保存文档时.
在ViewModel中,代码将文档保存到磁盘:
private void InitializeCommands()
{
CommandBindings = new CommandBindingCollection();
ExecutedRoutedEventHandler executeSave = (sender, e) =>
{
document.Save(path);
IsModified = false;
};
CanExecuteRoutedEventHandler canSave = (sender, e) =>
{
e.CanExecute = IsModified;
};
CommandBinding save = new CommandBinding(ApplicationCommands.Save, executeSave, canSave);
CommandBindings.Add(save);
}
Run Code Online (Sandbox Code Playgroud)
乍一看,前面的代码就是我想要做的,但是文档绑定到的View中的TextBox只在它失去焦点时才更新它的Source.但是,我可以通过按Ctrl + S保存文档而不会失去焦点.这意味着文档在源中更新的更改之前保存,实际上忽略了更改.但是,由于出于性能原因将UpdateSourceTrigger更改为PropertyChanged不是一个可行的选项,因此在保存之前必须强制更新其他内容.所以我想,让我们使用PreviewExecuted事件强制更新PreviewExecuted事件,如下所示:
//Find the Save command and extend behavior if it is present
foreach (CommandBinding cb in CommandBindings)
{
if (cb.Command.Equals(ApplicationCommands.Save))
{
cb.PreviewExecuted += (sender, e) =>
{
if (IsModified)
{
BindingExpression be = rtb.GetBindingExpression(TextBox.TextProperty);
be.UpdateSource();
} …Run Code Online (Sandbox Code Playgroud)