Note that there are some explanatory texts on larger screens.

plurals
  1. PORoutedUICommand PreviewExecuted Bug?
    text
    copied!<p>I'm building an application using the MVVM design pattern and I want to make use of the RoutedUICommands defined in the ApplicationCommands class. Since the CommandBindings property of a View (read UserControl) isn't a DependencyProperty we can't bind CommandBindings defined in a ViewModel to the View directly. I solved this by defining an abstract View class which binds this programmatically, based on a ViewModel interface which ensures every ViewModel has an ObservableCollection of CommandBindings. This all works fine, however, in some scenarios I want to execute logic which is defined in different classes (the View and ViewModel) same command. For instance, when saving a document.</p> <p>In the ViewModel the code saves the document to disk:</p> <pre><code>private void InitializeCommands() { CommandBindings = new CommandBindingCollection(); ExecutedRoutedEventHandler executeSave = (sender, e) =&gt; { document.Save(path); IsModified = false; }; CanExecuteRoutedEventHandler canSave = (sender, e) =&gt; { e.CanExecute = IsModified; }; CommandBinding save = new CommandBinding(ApplicationCommands.Save, executeSave, canSave); CommandBindings.Add(save); } </code></pre> <p>At first sight the previous code is all I wanted to do, but the TextBox in the View to which the document is bound, only updates its Source when it loses its focus. However, I can save a document without losing focus by pressing Ctrl+S. This means the document is saved before the changes where Updated in the source, effectively ignoring the changes. But since changing the UpdateSourceTrigger to PropertyChanged isn't a viable option for performance reasons, something else must force an update before saving. So I thought, lets use the PreviewExecuted event to force the update in the PreviewExecuted event, like so:</p> <pre><code>//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) =&gt; { if (IsModified) { BindingExpression be = rtb.GetBindingExpression(TextBox.TextProperty); be.UpdateSource(); } e.Handled = false; }; } } </code></pre> <p>However, assigning an handler to the PreviewExecuted event seems to cancel the event altogether, even when I explicitly set the Handled property to false. So the executeSave eventhandler I defined in the previous code sample isn't executed anymore. Note that when I change the cb.PreviewExecuted to cb.Executed both pieces of code <strong>do</strong> execute, but not in the correct order.</p> <p>I think this is a Bug in .Net, because you should be able to add a handler to PreviewExecuted and Executed and have them be executed in order, provided you don't mark the event as handled. </p> <p>Can anyone confirm this behavior? Or am I wrong? Is there a workaround for this Bug?</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload