如何在重新托管的工作流设计器中扩展上下文菜单?
How to extend the context menu inside the rehosted workflow designer?
我们正在使用一个重新托管的设计器(目前是 WF 4.0),其中包含许多自定义活动,它们都有自定义设计器。对于其中的一堆,我想在设计模式下将条目添加到设计器的上下文菜单中。我说的是这个菜单:
例如对于编码为 activity 的 XAML,我想要一个 "Open source..." 条目,它会将特定 activity 的 XAML 源加载到新设计器中。为此,我必须将条目添加到菜单中,并在单击时确定单击了哪个 activity。这两部分我都不清楚。我怎样才能做到这一点?
WF 3 中有 ActivityDesignerVerb class to do that. In WF 4 there seems to be workflowDesigner.Context.Services.Publish<ICommandService>(...),,但我不知道如何使用它向上下文菜单添加自定义操作。我该怎么做?
This SO entry 显示了一些用于内部调试器命令的内容,但我想添加一个全新的命令。
好的,您需要做的就是在自定义 activity 上实现 ICommand 接口。
因此,例如 - 从客户 activity class 公开自定义命令 属性,然后在构造函数中将委托事件应用于命令处理程序 -
/// <summary>
/// Custom activity
/// </summary>
public partial class CustomActivityDesigner
{
/// <summary>
/// Command used to display a dialog at design time
/// </summary>
public ICommand ShowCustomDialog{ get; set; }
public CustomSchedulerDesigner()
{
InitializeComponent();
ShowCustomDialog= new DelegateCommand(x =>
//Do some stuff here that will display your dialog
//you may want to consider passing the `this.ModelItem`
//to your dialog so it can then interact with the ModelTrees etc
//for example
var dialog = new MyDialog(this.ModelItem);
dialog.ShowDialog();
);
}
}
最后,
通过 activity 设计器 xaml.
将新命令连接到 UI
<sap:ActivityDesigner.ContextMenu>
<ContextMenu>
<MenuItem Header="Show" Command="{Binding ShowCustomDialog}"/>
</ContextMenu>
</sap:ActivityDesigner.ContextMenu>
宿主中解决
如果您想在工作流设计器主机上解决此问题,而不是在各个活动中,这样做非常简单直接。
当您托管工作流设计器并创建工作流设计器时,您只需访问其 ContextMenu
属性 并修改其 Items
集合。
var wfd = new WorkflowDesigner();
wfd.ContextMenu.Items.Add(new MenuItem() { Header = "Hello", Command = yourCommand, });
如果您希望每个 activity 有不同的菜单项,您可以订阅 SelectionChanged
事件:
wfd.Context.Items.Subscribe<Selection>(SelectionChanged);
然后实现自己的逻辑:
private void SelectionChanged(Selection selection)
{
// Remove old menu item
if (oldMenuItem != null)
{
wfd.ContextMenu.Items.Remove(oldMenuItem);
oldMenuItem = null;
}
var modelItem = selection.PrimarySelection;
if (selection.SelectionCount == 1 && modelItem != null)
{
// Get activity type
var activityType = modelItem.ItemType;
var menuItem = new MenuItem() { /* ... */ };
wfd.ContextMenu.Items.Add(menuItem);
oldMenuItem = menuItem;
}
}
在 activity 设计器中解决
如果您希望始终显示特定的上下文菜单项,而不管您的工作流设计器 UI 托管在何处,您可以在 activity 设计器 XAML 中创建自定义项:
<sap:ActivityDesigner.ContextMenu>
<ContextMenu>
<MenuItem Header="Show" Command="{Binding YourCommand}"/>
</ContextMenu>
</sap:ActivityDesigner.ContextMenu>
我们正在使用一个重新托管的设计器(目前是 WF 4.0),其中包含许多自定义活动,它们都有自定义设计器。对于其中的一堆,我想在设计模式下将条目添加到设计器的上下文菜单中。我说的是这个菜单:
例如对于编码为 activity 的 XAML,我想要一个 "Open source..." 条目,它会将特定 activity 的 XAML 源加载到新设计器中。为此,我必须将条目添加到菜单中,并在单击时确定单击了哪个 activity。这两部分我都不清楚。我怎样才能做到这一点?
WF 3 中有 ActivityDesignerVerb class to do that. In WF 4 there seems to be workflowDesigner.Context.Services.Publish<ICommandService>(...),,但我不知道如何使用它向上下文菜单添加自定义操作。我该怎么做?
This SO entry 显示了一些用于内部调试器命令的内容,但我想添加一个全新的命令。
好的,您需要做的就是在自定义 activity 上实现 ICommand 接口。
因此,例如 - 从客户 activity class 公开自定义命令 属性,然后在构造函数中将委托事件应用于命令处理程序 -
/// <summary>
/// Custom activity
/// </summary>
public partial class CustomActivityDesigner
{
/// <summary>
/// Command used to display a dialog at design time
/// </summary>
public ICommand ShowCustomDialog{ get; set; }
public CustomSchedulerDesigner()
{
InitializeComponent();
ShowCustomDialog= new DelegateCommand(x =>
//Do some stuff here that will display your dialog
//you may want to consider passing the `this.ModelItem`
//to your dialog so it can then interact with the ModelTrees etc
//for example
var dialog = new MyDialog(this.ModelItem);
dialog.ShowDialog();
);
}
}
最后, 通过 activity 设计器 xaml.
将新命令连接到 UI<sap:ActivityDesigner.ContextMenu>
<ContextMenu>
<MenuItem Header="Show" Command="{Binding ShowCustomDialog}"/>
</ContextMenu>
</sap:ActivityDesigner.ContextMenu>
宿主中解决
如果您想在工作流设计器主机上解决此问题,而不是在各个活动中,这样做非常简单直接。
当您托管工作流设计器并创建工作流设计器时,您只需访问其 ContextMenu
属性 并修改其 Items
集合。
var wfd = new WorkflowDesigner();
wfd.ContextMenu.Items.Add(new MenuItem() { Header = "Hello", Command = yourCommand, });
如果您希望每个 activity 有不同的菜单项,您可以订阅 SelectionChanged
事件:
wfd.Context.Items.Subscribe<Selection>(SelectionChanged);
然后实现自己的逻辑:
private void SelectionChanged(Selection selection)
{
// Remove old menu item
if (oldMenuItem != null)
{
wfd.ContextMenu.Items.Remove(oldMenuItem);
oldMenuItem = null;
}
var modelItem = selection.PrimarySelection;
if (selection.SelectionCount == 1 && modelItem != null)
{
// Get activity type
var activityType = modelItem.ItemType;
var menuItem = new MenuItem() { /* ... */ };
wfd.ContextMenu.Items.Add(menuItem);
oldMenuItem = menuItem;
}
}
在 activity 设计器中解决
如果您希望始终显示特定的上下文菜单项,而不管您的工作流设计器 UI 托管在何处,您可以在 activity 设计器 XAML 中创建自定义项:
<sap:ActivityDesigner.ContextMenu>
<ContextMenu>
<MenuItem Header="Show" Command="{Binding YourCommand}"/>
</ContextMenu>
</sap:ActivityDesigner.ContextMenu>