如何在重新托管的工作流设计器中扩展上下文菜单?

时间:2016-02-06 08:52:30

标签: workflow-foundation-4 workflow-foundation-4.5

我们正在使用一个带有大量自定义活动的重新设计的设计器(目前是WF 4.0),它们都有自定义设计器。对于它们中的一大堆,我想在设计模式下向设计器的上下文菜单添加条目。我正在谈论这个菜单:

enter image description here

E.g。对于XAML编码活动,我希望有一个"开源......"将该特定活动的XAML源加载到新设计器中的条目。为此,我必须将该条目添加到菜单中,并在单击时确定单击了哪个活动。这两个部分对我来说都不清楚。我怎样才能做到这一点?

在WF 3中,有ActivityDesignerVerb课程。在WF 4中似乎有workflowDesigner.Context.Services.Publish<ICommandService>(...),,但我无法弄清楚如何使用它来向上下文菜单添加自定义操作。我怎么能这样做?

This SO entry显示内部调试器命令,但我想添加一个全新的命令。

2 个答案:

答案 0 :(得分:2)

在主机中解决

如果您想在工作流设计器主机上解决此问题,而不是在单个活动中解决此问题,那么执行此操作非常简单明了。

当您托管工作流设计器并创建工作流设计器时,您只需访问其ContextMenu属性并修改其Items集合。

var wfd = new WorkflowDesigner();
wfd.ContextMenu.Items.Add(new MenuItem() { Header = "Hello", Command = yourCommand, });

如果您想为每项活动提供不同的菜单项,可以订阅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;
    }
}

在活动设计师

中解决它

如果您想要始终显示特定的上下文菜单项,而不管您的工作流设计器UI的托管位置,您可以在活动设计器XAML中创建自定义项:

<sap:ActivityDesigner.ContextMenu>
    <ContextMenu>
        <MenuItem Header="Show" Command="{Binding YourCommand}"/>
    </ContextMenu>
</sap:ActivityDesigner.ContextMenu>

答案 1 :(得分:0)

好的,所以您需要做的就是在自定义活动上实现ICommand接口。

因此,例如 - 从客户活动类公开自定义命令属性,然后在构造函数中将委托事件应用于命令处理程序 -

static void *
return_stack_ptr ()
{
    gpointer i;
    return &i;
}

最后,  通过活动设计器xaml将新命令挂钩到UI。

/// <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();
        );
    }

}