2

我想从一个子活动的设计器中验证设计图面(在本例中为 Visual Studio)内的工作流。我想阻止用户继续前进,直到其他错误得到纠正,以简化以后的设计体验。

天真的实现不起作用:

var activity = (this.ModelItem.Root.GetCurrentValue() as ActivityBuilder)
                    .Implementation as Activity;
var validationResult = ActivityValidationServices.Validate(activity);
if (validationResult.Errors.Count > 0))
{
    MessageBox.Show("The Workflow is invalid.  Fix it.", "Derp");
    return;
}

问题是 ActivityBuilder (它不是Activity 并且不能传递给)包含在工作流的根上定义的Validate任何和所有变量和参数。因此,当您尝试验证根 ( Implementation) 的第一个子节点时,您会收到无效错误,因为对这些子节点的任何绑定都会失败。

我已经看到建议的黑客攻击,您可以将 Activity 添加Implementation到运营商 Activity(例如,序列),然后将 ActivityBuilder 中的所有变量和参数添加到运营商。

这很臭。

有没有更好的办法?

4

2 回答 2

1

我不认为有。我猜你的谷歌搜索在蒂姆想出几乎相同结果的论坛上出现了这个问题。

鉴于 ModelItem 是您的活动,添加了一个自定义函数来调用并进行您自己的检查,可能会有一个解决方案。这样您就可以从 CacheMetadata 和您的活动构建器中调用该函数。

于 2011-05-19T06:21:03.200 回答
0

黑客。除了黑客之外别无他法。

var sb = new StringBuilder();
using (var tw = new StringWriter(sb))
using (var xw = ActivityXamlServices.CreateBuilderWriter(
                    new XamlXmlWriter(tw, new XamlSchemaContext())))
{
    XamlServices.Save(xw, 
                      this.ModelItem.Root.GetCurrentValue() as ActivityBuilder);
    tw.Flush();
}
using(var tr = new StringReader(sb.ToString()))
using (var xr = ActivityXamlServices.CreateReader(
                    new XamlXmlReader(tr, new XamlSchemaContext())))
{
    var activity = ActivityXamlServices.Load(xr);
    var validationResult = ActivityValidationServices.Validate(activity);
    if (!validationResult.IsValid())
    {
        MessageBox.Show("OMG what an awful hack.", "Validation Sucks");
        return;
    }
}

有没有更好的方法将 ActivityBuilder 转换为 Activity 而无需序列化?

于 2011-05-18T20:53:13.000 回答