重新托管 WF4 删除 Activity 场景
Rehosted WF4 Delete Activity scenario
为了达到分配 activity 的上下文,我将其托管到自定义 activity 中,如下所示:
<sap:ActivityDesigner x:Class="ARIASquibLibrary.Design.CustomAsignDesigner"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"
xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"
xmlns:statements="http://schemas.microsoft.com/netfx/2009/xaml/activities" Collapsible="False">
<sap:ActivityDesigner.Template>
<ControlTemplate TargetType="sap:ActivityDesigner">
<Grid>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</sap:ActivityDesigner.Template>
<DockPanel LastChildFill="True">
<sap:WorkflowItemPresenter Item="{Binding Path=ModelItem.Body, Mode=TwoWay}"/>
</DockPanel>
以及库中的代码:
public sealed class CustomAssign : NativeActivity, IActivityTemplateFactory
{
[Browsable(false)]
public Activity Body { get; set; }
protected override void Execute(NativeActivityContext context)
{
ActivityInstance res = context.ScheduleActivity(Body, new CompletionCallback(OnExecuteComplete));
}
/// <summary>
/// Called from Execute when Condition evaluates to true.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="instance">The instance.</param>
public void OnExecuteComplete(NativeActivityContext context, ActivityInstance instance)
{
//to be added
}
Activity IActivityTemplateFactory.Create(System.Windows.DependencyObject target)
{
return new CustomAssign
{
Body = new Assign()
};
}
}
在设计器上拖动此 activity 时,它看起来与默认分配完全一样。但是在尝试删除它时出现问题。被托管时,它的父级将保留在设计器中,因为事实上,即使用户看不到它,我也会删除主体。
是否有传播到父级以便从设计器中删除整个 activity 的方法?
好的,您需要覆盖工作流设计器上的 OnModelChanged 事件。
ModelService modelSvc = (ModelService)designer.Context.Services.GetService<System.Activities.Presentation.Services.ModelService>();
if (modelSvc != null)
{
modelSvc.ModelChanged += OnModelChanged;
}
完成此操作后,您可以访问已从设计器中删除的活动。
void modelSvc_ModelChanged(object sender, ModelChangedEventArgs e)
{
//we have deleted something from the design surfaace
if (e.ModelChangeInfo.ModelChangeType == ModelChangeType.CollectionItemRemoved)
{
ModelItem modelItem = (ModelItem)e.ModelChangeInfo.Value;
}
}
基于已删除 activity 中的模型项,您可以遍历工作流树以查找您希望删除的相关活动。
这个概念解释的很好here。
然后您可以使用带有以下代码的 ModelEditingScope 删除活动。
using (ModelEditingScope editingScope = modelSvc.Root.BeginEdit("Activities"))
{
//to add an activity
modelSvc.Root.Properties["Activities"].Collection.Add(new Sequence());
//to remove an activity
modelSvc.Root.Properties["Activities"].Collection.Remove(*A model Item to remove);
editingScope.Complete();
}
这不是一项微不足道的任务,在执行此操作时有一些有趣的地方。就我个人而言,我没有在我自己的应用程序中实现这个确切的要求,但我已经完成了与删除相关的变量的类似删除 activity 并且有各种问题,但上面的代码应该给你一个起点。
为了达到分配 activity 的上下文,我将其托管到自定义 activity 中,如下所示:
<sap:ActivityDesigner x:Class="ARIASquibLibrary.Design.CustomAsignDesigner"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:sap="clr-namespace:System.Activities.Presentation;assembly=System.Activities.Presentation"
xmlns:sapv="clr-namespace:System.Activities.Presentation.View;assembly=System.Activities.Presentation"
xmlns:statements="http://schemas.microsoft.com/netfx/2009/xaml/activities" Collapsible="False">
<sap:ActivityDesigner.Template>
<ControlTemplate TargetType="sap:ActivityDesigner">
<Grid>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</sap:ActivityDesigner.Template>
<DockPanel LastChildFill="True">
<sap:WorkflowItemPresenter Item="{Binding Path=ModelItem.Body, Mode=TwoWay}"/>
</DockPanel>
以及库中的代码:
public sealed class CustomAssign : NativeActivity, IActivityTemplateFactory
{
[Browsable(false)]
public Activity Body { get; set; }
protected override void Execute(NativeActivityContext context)
{
ActivityInstance res = context.ScheduleActivity(Body, new CompletionCallback(OnExecuteComplete));
}
/// <summary>
/// Called from Execute when Condition evaluates to true.
/// </summary>
/// <param name="context">The context.</param>
/// <param name="instance">The instance.</param>
public void OnExecuteComplete(NativeActivityContext context, ActivityInstance instance)
{
//to be added
}
Activity IActivityTemplateFactory.Create(System.Windows.DependencyObject target)
{
return new CustomAssign
{
Body = new Assign()
};
}
}
在设计器上拖动此 activity 时,它看起来与默认分配完全一样。但是在尝试删除它时出现问题。被托管时,它的父级将保留在设计器中,因为事实上,即使用户看不到它,我也会删除主体。
是否有传播到父级以便从设计器中删除整个 activity 的方法?
好的,您需要覆盖工作流设计器上的 OnModelChanged 事件。
ModelService modelSvc = (ModelService)designer.Context.Services.GetService<System.Activities.Presentation.Services.ModelService>();
if (modelSvc != null)
{
modelSvc.ModelChanged += OnModelChanged;
}
完成此操作后,您可以访问已从设计器中删除的活动。
void modelSvc_ModelChanged(object sender, ModelChangedEventArgs e)
{
//we have deleted something from the design surfaace
if (e.ModelChangeInfo.ModelChangeType == ModelChangeType.CollectionItemRemoved)
{
ModelItem modelItem = (ModelItem)e.ModelChangeInfo.Value;
}
}
基于已删除 activity 中的模型项,您可以遍历工作流树以查找您希望删除的相关活动。
这个概念解释的很好here。
然后您可以使用带有以下代码的 ModelEditingScope 删除活动。
using (ModelEditingScope editingScope = modelSvc.Root.BeginEdit("Activities"))
{
//to add an activity
modelSvc.Root.Properties["Activities"].Collection.Add(new Sequence());
//to remove an activity
modelSvc.Root.Properties["Activities"].Collection.Remove(*A model Item to remove);
editingScope.Complete();
}
这不是一项微不足道的任务,在执行此操作时有一些有趣的地方。就我个人而言,我没有在我自己的应用程序中实现这个确切的要求,但我已经完成了与删除相关的变量的类似删除 activity 并且有各种问题,但上面的代码应该给你一个起点。