I'm rehosting the WF4 workflow designer in a custom MVVM WPF application, along the lines of Maurices excellent blog post
But I could not figure out how to bind the application commands like Cut, Copy, Paste, Undo, Redo (which I want to expose in a main menu) to the designer. The keyboard bindings like Ctrl-X work out of the box, but I want to have my MenuItems do the same. Any help here?
Selecting Edit->Copy in the main menu bar should copy the currently selected activity to the clipboard, just like Ctrl-C does. Is that possible at all?
Edit 1:
If I simply add the general application commands like
MenuItem Header="Cu_t" Command="Cut" />
I get a menu with always disabled items:
Edit 2:
The general command binding seems to be ok. If I select some text in a textbox (somewhere outside the designer surface in my application, or even inside an activity), the menu items get enabled and work as expected:
-->
But if I select the activity as a whole and want to cut/copy.. it, the menu items are all dimmed - although the keyboard bindings work as expected, and in the builtin context menu the items are enabled:
Context menu:
But the main menu:
So it is not a general problem with the menu items, it is strictly related to the workflow designer. On http://msdn.microsoft.com/en-us/library/system.windows.input.applicationcommands.copy.aspx we can read
When the CommandTarget is not set, the target for the command is the element which has keyboard focus. If the element which has keyboard focus does not support the Paste command or cannot currently execute the paste command (the clipboard is empty, for example) then the MenuItem would be grayed out.
In this situation, the workflow designer has the focus, and Cut could be performed, but still grayed out. Does this mean that the workflow designer does not support application commands at all?
Edit 3:
Another extremely weird finding. I added the "Delete" Command to the menu, and this one does get enabled when an activity is selected. Clicking this menu item indeed deletes the activity from the designer surface.
<MenuItem Header="_Delete" Command="Delete" />
So it is completely inconsistent with the Cut/Copy/past commands...
On DesignerView class you've a bunch of commands to use on top of Workflow Designer. The trick here is to set CommandTarget
to current designer's DesignerView
.
For example, having this on code-behind:
public DesignerView CurrentDesignerView
{
get { return WorkflowDesigner.Context.Services.GetService<DesignerView>(); }
}
public ICommand CopyCommand
{
get { return DesignerView.CopyCommand; }
}
public ICommand CutCommand
{
get { return DesignerView.CutCommand; }
}
public ICommand PasteCommand
{
get { return DesignerView.PasteCommand; }
}
You would bind to commands like this:
<MenuItem Command="{Binding CopyCommand}" CommandTarget="{Binding CurrentDesignerView}"/>
<MenuItem Command="{Binding CutCommand}" CommandTarget="{Binding CurrentDesignerView}"/>
<MenuItem Command="{Binding PasteCommand}" CommandTarget="{Binding CurrentDesignerView}"/>