问题描述
我建设使用MVVM设计模式的应用程序,我想利用在ApplicationCommands类中定义的RoutedUICommands的。由于视图的CommandBindings属性(读取用户控件)不,我们不能绑定在一个视图模型直接查看定义CommandBindings一个的DependencyProperty。我解决了这个通过定义编程结合这一个抽象的视图类,基于一个ViewModel接口,保证了每一个视图模型具有CommandBindings的一个ObservableCollection上。这一切工作正常,但是,在某些情况下我要执行它在不同的类(视图和视图模型)相同的命令定义的逻辑。 ,例如,保存文档时
在视图模型的代码保存文档磁盘:
私人无效InitializeCommands()
{
CommandBindings =新CommandBindingCollection();
ExecutedRoutedEventHandler executeSave =(发件人,E)=>
{
document.Save(路径);
将IsModified = FALSE;
};
CanExecuteRoutedEventHandler canSave =(发件人,E)=>
{
e.CanExecute =将IsModified;
};
保存的CommandBinding =新的CommandBinding(ApplicationCommands.Save,executeSave,canSave);
CommandBindings.Add(保存);
}
乍一看前面的代码是我想做的事,但在TextBox在该文件所绑定的视图,只有当它失去它的焦点更新其来源。不过,我可以将文档保存而不按Ctrl + S失去焦点。这意味着文档,其中源更新,有效地忽略的变化更改之前保存。但由于改变了UpdateSourceTrigger到的PropertyChanged是不是出于性能的考虑一种可行的选择,别的东西必须在保存之前强制更新。所以我想,让使用PreviewExecuted事件迫使更新的PreviewExecuted事件,像这样:
//查找保存命令(如果存在)
的foreach(在CommandBindings CB的CommandBinding)
{
延长的行为,如果(cb.Command.Equals(ApplicationCommands.Save))
{
cb.PreviewExecuted + =(发件人,E)=>
{
如果(将IsModified)
{
BindingExpression是= rtb.GetBindingExpression(TextBox.TextProperty);
be.UpdateSource();
}
e.Handled = FALSE;
};
}
}
然而,分配一个处理程序的PreviewExecuted事件似乎完全取消的情况下,甚至当我明确设置处理的属性设置为false。所以,我前面的代码示例中定义的executeSave事件处理程序不再被执行。需要注意的是,当我改变cb.PreviewExecuted到cb.Executed代码两片做执行,但不正确的顺序。
我认为这是.NET中的一个Bug,因为你应该能够处理程序添加到PreviewExecuted和执行,并让他们为了来执行,只要是处理你不庆祝活动。
任何人都可以证实这种行为?还是我错了? ?是否有这个Bug一种解决方法
If you look at the CommandBinding class source code there is OnExecuted() method that is responsible for calling the handlers you register for PreviewExecuted and Executed events through CommandBinding. There is that bit there:
PreviewExecuted(sender, e);
e.Handled = true;
this sets the event as handled right after your PreviewExecuted handler returns and so the Executed is not called.
Note, that it only works this way when handlers are registered through CommandBinding.
If you still want to have both PreviewExecuted and Executed to run you have two options:
- You can can call
Execute()
method of the routed command from within PreviewExecuted handler. Just thinking about it - you might run into sync issues as you're calling Executed handler before the PreviewExecuted is finished. To me this doesn't look like a good way to go. - You can register PreviewExecuted handler separately through
CommandManager.AddPreviewExecutedHandler()
static method. This will be called directly from UIElement class and will not involve CommandBinding.EDIT 2: Look at the point 4 at the beginning of the post - these are the events we're adding the handlers for.
From the looks of it - it was done this way on purpose. Why? One can only guess...
这篇关于RoutedUICommand PreviewExecuted漏洞?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!