您可以通过检查 ModelItem 树的父级并检查 DelegeateInArgument 来访问 ForEach 活动的 DelegeateInArgument。如果您需要特定的代码示例来实现这一点,我可能需要一些时间来编写示例代码。由于我已经很久没有这样做了,请参阅我在 msdn 上提出的问题
所以基本上你的断点在哪里,你可以访问变量值,因为这些值是在你的活动范围内定义为“变量”的。然而,“item”变量实际上只能从父循环活动中访问。因此,您必须获取当前执行活动的模型项,然后向上遍历树以找到包含所需 DelegateInArgument 的父项。
你能具体说明你想要实现的目标吗?是不是当您在重新托管的设计器中调试工作流时,您希望在 UI 中更改时向用户显示变量值?
编辑 - 添加跟踪示例
因此,如果您希望在工作流执行期间显示变量值,我们需要使用跟踪来实现此目的。在示例中,您使用作者已经实现了一些基本跟踪。因此,要实现您想要的扩展变量跟踪,您需要更改跟踪配置文件。
首先修改WorkflowDesignerHost.xaml.cs文件修改RunWorkflow方法定义SimulatorTrackingParticipant如下。
SimulatorTrackingParticipant simTracker = new SimulatorTrackingParticipant()
{
TrackingProfile = new TrackingProfile()
{
Name = "CustomTrackingProfile",
Queries =
{
new CustomTrackingQuery()
{
Name = all,
ActivityName = all
},
new WorkflowInstanceQuery()
{
**States = {all },**
},
new ActivityStateQuery()
{
// Subscribe for track records from all activities for all states
ActivityName = all,
States = { all },
**Arguments = {all},**
// Extract workflow variables and arguments as a part of the activity tracking record
// VariableName = "*" allows for extraction of all variables in the scope
// of the activity
Variables =
{
{ all }
}
}
}
}
};
现在这将正确捕获所有工作流实例状态,而不仅仅是已开始/已完成。您还将捕获记录跟踪数据的每个活动的所有参数,而不仅仅是变量。这很重要,因为感兴趣的“变量”实际上(如前所述)是一个 DelegateInArgument。
因此,一旦我们更改了跟踪配置文件,我们还需要更改 SimulatorTrackingParticipant.cs 以提取我们现在正在跟踪的其他数据。
如果您更改 OnTrackingRecordReceived 方法以包含以下部分,这些部分将在执行期间捕获变量数据以及参数数据。
protected void OnTrackingRecordReceived(TrackingRecord record, TimeSpan timeout)
{
System.Diagnostics.Debug.WriteLine(
String.Format("Tracking Record Received: {0} with timeout: {1} seconds.", record, timeout.TotalSeconds)
);
if (TrackingRecordReceived != null)
{
ActivityStateRecord activityStateRecord = record as ActivityStateRecord;
if (activityStateRecord != null)
{
IDictionary<string, object> variables = activityStateRecord.Variables;
StringBuilder vars = new StringBuilder();
if (variables.Count > 0)
{
vars.AppendLine("\n\tVariables:");
foreach (KeyValuePair<string, object> variable in variables)
{
vars.AppendLine(String.Format(
"\t\tName: {0} Value: {1}", variable.Key, variable.Value));
}
}
}
if (activityStateRecord != null)
{
IDictionary<string, object> arguments = activityStateRecord.Arguments;
StringBuilder args = new StringBuilder();
if (arguments.Count > 0)
{
args.AppendLine("\n\tArgument:");
foreach (KeyValuePair<string, object> argument in arguments)
{
args.AppendLine(String.Format(
"\t\tName: {0} Value: {1}", argument.Key, argument.Value));
}
}
//bubble up the args to the UI for the user to see!
}
if((activityStateRecord != null) && (!activityStateRecord.Activity.TypeName.Contains("System.Activities.Expressions")))
{
if (ActivityIdToWorkflowElementMap.ContainsKey(activityStateRecord.Activity.Id))
{
TrackingRecordReceived(this, new TrackingEventArgs(
record,
timeout,
ActivityIdToWorkflowElementMap[activityStateRecord.Activity.Id]
)
);
}
}
else
{
TrackingRecordReceived(this, new TrackingEventArgs(record, timeout,null));
}
}
}
希望这会有所帮助!