上一节我们在设计器的显示方面进行了完善,在这一节,我们将深入状态机设计器的一些逻辑细节,给我 们的设计器添加逻辑规则.为生成代码做好准备.
在开始之前,我们先看一下Transition的几个属性之间的关系:
1.编辑Event,Condition,Action属性时,Label属性能够自动计算显示,计算逻辑为Event [Condition] / Action
2.当修改属性Label时,Event,Condition,Action的值也能够对应自动更新.
我们使用Vs.net Dsl的规则来实现:
1.在Dsl项目下新增CustomCode文件夹来存放我们的自定义的代码,这是Dsl开发中的通用做法,Dsl再强 大也不可能不一点代码不用写就能够使满足需求,一般情况下,无论是在开发Dsl还是在使用Dsl时,都需要 结合生成的代码和自定义代码.在CustomCode文件夹下面新建文件夹 Validation,用于存放手写的自定义 验证类.
2.在Validation文件夹下面添加类TransitionLabelRule.
3.修改TransitionLabelRule继承于ChangeRule,并使用RuleOn属性标签标识此规则应用到域关系 Transition上面.
using Microsoft.VisualStudio.Modeling;
namespace Company.LanguageSm
{
[RuleOn(typeof(Transition))]
public sealed class TransitionLabelRule : ChangeRule
{
}
}
4.在规则类里面,我们需要实现ChangeRule唯一的一个方法 ElementPropertyChanged (ElementPropertyChangedEventArgs e),从这个方法我们可以看出,当Transition的一些属性发生变化时 就会触发这个规则,参数类型 ElementPropertyChangedEventArgs,这个参数包含当前的模型元素 ModelElement,编辑的属性 DomainProperty,原值OldValue,新值NewValue,我们只需要判断当前的属性,如 果是以上的 Event,Condition,Action,Lable时,修改后就计算其余的属性.
public override void ElementPropertyChanged(ElementPropertyChangedEventArgs e)
{
Transition t = e.ModelElement as Transition;
// Compute Label when Event changes
if (e.DomainProperty.Id == Transition.EventDomainPropertyId)
t.Label = ComputeSummary(e.NewValue as string, t.Condition, t.Action);
// Compute Label when Condition changes
else if (e.DomainProperty.Id == Transition.ConditionDomainPropertyId)
t.Label = ComputeSummary(t.Event, e.NewValue as string, t.Action);
// Compute Label when Action changes
else if (e.DomainProperty.Id == Transition.ActionDomainPropertyId)
t.Label = ComputeSummary(t.Event, t.Condition, e.NewValue as string);
// Compute Event, Condition, Action when Label changes
else if (e.DomainProperty.Id == Transition.LabelDomainPropertyId)
ComputeProperties(e.NewValue as string, t);
}
ComputeSummary是我们的辅助方法,通过Event,Condition,Action三个值来计算Lable的 值,ComputeProperties方法是由Lable的值来分别匹配出另外三个属性的值.最后可以直接对域类的属性进 入赋值. 这两个辅助方法就不在这里列出来了,在下载代码里可以看到.(在这里其实是默认提交,整个规则 事件就在一个事务中).