我正在为重新托管的工作流设计器实现VisualTracking。如果文件刚刚加载到WorkflowDesigner中,则可视跟踪工作正常,并且SourceLocationProvider.CollectMapping
生成的映射可以成功运行。但是,如果对工作流进行了修改并重新保存,则SourceLocationProvider仅映射原始xaml。
有没有办法强制SourceLocationProvider使用的AttachedProperties更新?
如果尝试使用WorkflowDesigner.Load(..)
,则会创建一个全新的WorkflowDesigner对象,因为WorkflowDesigner只能加载一次文件。如果可能的话,我想避免这种情况,因为它丢失了已设置的任何调试数据。
答案 0 :(得分:0)
很抱歉,我自己没试过,但你可以从设计师的ModelChanged事件中调用SourceLocationProvider.CollectMapping(...)吗?
答案 1 :(得分:0)
使用反射,人们可以直接从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);
}
答案 2 :(得分: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()