I'm trying to rehost the designer, but every time I slap a workflow into the designer:
_workflowDesigner = new WorkflowDesigner();
// added to UI here
Properties.Content = _workflowDesigner.PropertyInspectorView;
_workflowDesigner.Load(myWorkflowInstance);
where myWorkflowInstance
is a workflow defined in a referenced assembly. I have done the magic Register
to get the default activity metadata registered:
new DesignerMetadata().Register();
and I've registered all my custom NativeActivities:
public static void Register(IEnumerable<Type> activityTypes)
{
// activityTypes are all my custom NativeActivities
// and all workflows (root of System.Activities.Activity)
var builder = new AttributeTableBuilder();
var attrGroups =
from x in activityTypes
from y in x.GetCustomAttributes(true).OfType<Attribute>()
group y by x into g
select g;
foreach (var typeGroup in attrGroups)
builder.AddCustomAttributes(typeGroup.Key, typeGroup.ToArray());
MetadataStore.AddAttributeTable(builder.CreateTable());
}
yet, when I load an activity in开发者_如何转开发 the designer this is what I get:
What am I missing here?
I'm thinking it has something to do with the fact that these workflows are compiled and only exist within the Implementation property of an Activity...
Is your workflow instance wrapped in an ActivityBuilder?
Update: Investigating a little further here I found one possible solution using the WorkflowInspectionServices.
var activities = WorkflowInspectionServices.GetActivities(new DemoWorkflow());
designer.Load(activities.First());
A bit of reflector and reflection has led me to this travesty:
var impl = (typeof(DemoWorkflow)
.GetProperty("Implementation",
BindingFlags.NonPublic | BindingFlags.Instance)
.GetValue(new DemoWorkflow(), new object[0])
as System.Func<System.Activities.Activity>)();
_workflowDesigner.Load(new ActivityBuilder { Implementation = impl });
Is this it? Seriously? I feel sick knowing that I wrote that. Dirty.
I noticed in reflector that the xaml for the workflow actually is embedded in the assembly in a resource stream:
but all attempts to use this failed.
var target = typeof(DemoWorkflow);
var name = string.Format("{0}.obj.Debug.{1}.g.xaml",
target.Assembly.GetName().Name,
target.Name);
Activity derp = null;
using (var stream = assy.Assembly.GetManifestResourceStream(name))
{
var reader = new XamlXmlReader(stream, new XamlSchemaContext());
// throws an exception as the property Implementation is in the xaml;
// it is protected and cannot be set, so deserialization blows up
derp = ActivityXamlServices.Load(reader);
}
I don't see any other option at this point.
精彩评论