1

我正在为重新托管的工作流设计器实施 VisualTracking。如果文件是新加载到 WorkflowDesigner 中,则视觉跟踪工作正常,并且从SourceLocationProvider.CollectMapping工作中成功生成映射。但是,如果对工作流进行了修改并重新保存,则 SourceLocationProvider 仅映射来自原始 xaml。

有什么方法可以强制 SourceLocationProvider 在后台使用的 AttachedProperties 进行更新?

如果尝试使用WorkflowDesigner.Load(..)创建一个全新的 WorkflowDesigner 对象,则 WorkflowDesigner 只能加载一次文件。如果可能的话,我想避免这种情况,因为它会丢失任何已设置的调试数据。

4

3 回答 3

1

DebuggerService使用反射,可以直接从自身获取所需的信息。以下解决方案对我有用,并在更新工作流程后继续工作:

private static Dictionary<string, SourceLocation> CreateSourceLocationMapping(
    IDesignerDebugView debugView,
    ModelService modelService)
{
    var nonPublicInstance = BindingFlags.Instance | BindingFlags.NonPublic;
    var debuggerServiceType = typeof(DebuggerService);
    var ensureMappingMethodName = "EnsureSourceLocationUpdated";
    var mappingFieldName = "instanceToSourceLocationMapping";
    var ensureMappingMethod = debuggerServiceType.GetMethod(ensureMappingMethodName, nonPublicInstance);
    var mappingField = debuggerServiceType.GetField(mappingFieldName, nonPublicInstance);

    if (ensureMappingMethod == null)
        throw new MissingMethodException(debuggerServiceType.FullName, ensureMappingMethodName);
    if (mappingField == null)
        throw new MissingFieldException(debuggerServiceType.FullName, mappingFieldName);

    var rootActivity = modelService.Root.GetCurrentValue() as Activity;
    if (rootActivity != null) 
        WorkflowInspectionServices.CacheMetadata(rootActivity);

    ensureMappingMethod.Invoke(debugView, new object[0]);
    var mapping = (Dictionary<object, SourceLocation>) mappingField.GetValue(debugView);

    return (from pair in mapping
            let activity = pair.Key as Activity
            where activity != null
            select new {activity.Id, pair.Value})
        .ToDictionary(p => p.Id, p => p.Value);
}
于 2018-09-11T21:27:43.133 回答
0

抱歉,我自己还没有尝试过,但是您可以从设计器的 ModelChanged 事件中调用 SourceLocationProvider.CollectMapping(...) 吗?

于 2012-10-19T11:51:04.833 回答
0

我知道为时已晚,但可能会对其他人有所帮助。所以她是我的解决方案

private Dictionary<object, SourceLocation> UpdateSourceLocationMappingInDebuggerService()
    {    
       Dictionary<object, SourceLocation> sourceLocationMapping = new Dictionary<object, SourceLocation>();
       Dictionary<object, SourceLocation> designerSourceLocationMapping = new Dictionary<object, SourceLocation>();

       MemoryStream ms = new MemoryStream(Encoding.Default.GetBytes(this.WorkflowDesigner.Text));
       DynamicActivity activityToRun = ActivityXamlServices.Load(ms) as DynamicActivity;

       WorkflowInspectionServices.CacheMetadata(activityToRun);
       Activity documentRootElement = GetRootWorkflowElement(rootInstance);
       Activity rootActivity = GetRootRuntimeWorkflowElement(this.workflowToRun);
       var fileName = this.WorkflowDesigner.Context.Items.GetValue<WorkflowFileItem>().LoadedFile;

       SourceLocationProvider.CollectMapping(rootActivity, documentRootElement, sourceLocationMapping, fileName);
       SourceLocationProvider.CollectMapping(documentRootElement, documentRootElement, designerSourceLocationMapping, fileName);

           if (this.debuggerService != null)
            {
                ((DebuggerService)this.debuggerService).UpdateSourceLocations(designerSourceLocationMapping);
            }

           if (designerSourceLocationMapping.Count != sourceLocationMapping.Count)
            {
                foreach (var item in designerSourceLocationMapping)
                {
                    if (!sourceLocationMapping.ContainsValue(item.Value))
                        sourceLocationMapping.Add(item.Key, item.Value);
                }
            }

       this.designerSourceLocationMapping = designerSourceLocationMapping;
       return sourceLocationMapping;
   }

在这里我再次更新 sourceLocationMapping

((DebuggerService)this.debuggerService).UpdateSourceLocations()

于 2019-11-08T14:16:05.647 回答