我想在其中一个子活动设计器中验证设计图面(在本例中为Visual Studio)中的工作流程。我想阻止用户继续前进,直到其他错误得到纠正,以便在以后简化设计体验。
naiive实现不起作用:
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(不是一个活动,无法传递给Validate
)包含任何和所有变量和参数在工作流程的根源。因此,当您尝试验证根(Implementation
)的第一个子节点时,您将获得无效的错误,因为任何绑定都会失败。
我见过建议的黑客,你将Implementation
添加到运营商活动(比如,序列),然后将ActivityBuilder中找到的所有变量和参数添加到运营商。< / p>
这很臭。
有更好的方法吗?
答案 0 :(得分:1)
我认为没有。我猜你的谷歌搜索出现了this问题,在蒂姆提出的论坛上提出了几乎相同的结果。
鉴于ModelItem是您的活动,添加自定义函数来调用和进行自己的检查,可能会有一个解决方案。这样,您就可以从CacheMetadata和您的活动构建器中调用该函数。
答案 1 :(得分: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而不将其序列化?