[原文地址]
这是有关”部件与状态”模式系列的最后一篇!
今天,我们讨论一些关于如何使用”部件与状态”模式的使用建议.我们还会看看有关VisualStageManager在未来的Silverlight及WPF中的情况.
“部件与状态”模式使用推荐
1.在UserControls用户控件和Custom Control自定义控件中使用”部件与状态”模式
就像我们在第一篇中提到的,”部件与状态”模式只是一个模式.在实际运行中并不是强制的,你可以在创建控件时不采用这种方式.
但是,我们觉得这是一个很好的模式.而且Blend针对自定义控件的的可视化编辑方式只支持这种模式.
虽然我们这一系列一直关注在自定义控件Custom Controls中的VSM,但是你同样可以在用户控件User Control中使用他.
2.自行命名VSM xmlns
因为一个已知的Silverlight 2 Beta 2 Bug,你必须在头部申明VisualStateManager的xmlns.
xmlns:vsm=“clr-namespace:System.Windows;assembly=System.Windows”
3.命名约定
为了控件的一致性,我们推荐使用如下的一些命名约定.

4.CommonStates 和 FocusStates 比较特殊
许多控件都使用了这二个状态组

如果你的控件也有这些状态的特征,为了一致性,我们推荐使用相同的组名和名称
5.能够适应模板中没有Parts & States的情况
有很多原因能说明为什么控件模板中没有给一些部件和状况:设计师可能没有创建等原因.
需要有一些良好的编写习惯去防止由于部件遗失造成的程序崩溃.
注意:VisualStateManager.GoToState()方法已经有这种预防措施,当VisualState没有找到时,会返回false.
6.考虑支持一个”fallback”状态(当状态不存在时,用另一状态替代)
在复杂的控件中,可以提供一个fallback控制当某些状态不存在时提供一种替代方案
if (VisualStateManager.GoToState(this, “FocusContent”, useTransitions) == false){VisualStateManager.GoToState(this, “Focus", useTransitions);}
这个处理方式的好处显而易见:当设计师没有提供合适的状态时,控件能够继续进行一些视觉上的正常表现.
但也有一些不好的影响:fallback状态机制并不是完全整合在”部件与状态”模式中,这意味着Blend软件并不能很好的识别出来(在可视化编辑中)
所以,请减少使用fallback状态并只在控件非常复杂时才使用.
同样,如果你认为这种方式对你有用的话,让我们知道!我们乐意接受你的反馈.
7.子类的状态应该添加在新的状态组中(而不是已存在的状态组)
如你所知,每一个状态组是orthogonal(同时使用二个组中的二个状态).这使得子类很容易添加新的状态组.例如,你可以创建一个StackButton从Button继承并添加一个StackState组:

这个可以正常运作因为StackState状态组的状态是完全独立于Button的CommonStates & FocusStates.
然尔,如果你想把一个新的状态加到一个已经存在的状态组中,这个状态组的逻辑就变得混乱.就无法保证在状态发生时找到正确的状态.
我们这个例子简单一些.BasicControl定义了二个状态在CommonStates中:Normal,MouseOver.创新的逻辑是:
- if(鼠标没有移上来) goto Normal
- if(鼠标移上来) goto MouseOver
现在,ExtendedControl从BasicControls继承并想加一个Pressed状态,这个逻辑状态的目标可能是:
- if(鼠标没有移上来) goto Normal
- if(鼠标移上来而且鼠标按钮没有按下) goto MouseOver
- if(鼠标按下) goto Pressed
然尔,并没有好的方式让ExtendedControl去添加有关(而且鼠标按钮没有按下)MouseOver状态的检测,因为这个逻辑存在于Button基类中.
这一切都说明:子类通常只能把状态加到新的状态组中.但我们推荐如果是全新的状态(不破坏原有逻辑的),可以加到状态组中.
注意:为在未来解决这些问题我们有不同的方式(有好的也有坏的).我们现在正在提供一个Triggers-Based基于触发的解决方案.如果想了解更多,继续阅读.
展望未来
VSM & Windows Presentation Foundation
Silverlight的”控件与状态”模式改变了WPF存在的很多现有特性(像ControlTemplates,GetTemplateChild() Hellper,etc).

然尔,这些相关的特性如VisualStateManager和相关的类并不存在于WPF中.好消息是我们在下一版的WPF中会包含VisualStageManager!
为了让大家能够把Silverlight 2的控件和皮肤移植到WPF,下一版.NET Framework会支持得更好一些.为帮助我们实现,我们会在下一版的完整WPF发售前,就中提供一个包含VisualStateManager的程序集.现然这个计划还为时尚早,未来会提供时间表的细节.
未来的Silverlight特性
经常有人问在Silverlight控件模型中,Triggers触发器在哪里?
有很多原因使得我们不打算在Silverlight 2 的发布中加入触发器.一个主要的技术挑战是我们的属性系统架构不够达到能支持触发器.这在未来的Silverlight会改变,并会加入触发器的支持.
触发器和VSM之间如何协作呢?我们初步的方案是这样构想的:
提供一个GoToState触发器去调用状态变化.
设计师会有一个选项去使用内置的控件状态(不使用视觉状态变化的逻辑去控制).或者,设计师愿意在XAML中使用所有的触发器和VSM状态变化.也可能设计师能够自行添加新的状态到新状态组或存在的状态组中,而不去考虑控件的代码的情况下.
更多激动的特性会到来!
结束
这就是这四篇的有关Silverlight 2 “部件与状态”模式的全部了.如果你有问题,请反馈给我们.
如果这一系列还不够了解VisualStateManager,这有一些其它资源:
- Christian Schormann’s Blog (Group Program Manager for Expression Blend)
- Steve White的视频教程(Program Manager for Expression Blend)
- Celso Gomes的教程(Designer for Expression Blend)
- Tim Heuer’s Blog (Senior Program Manager on the .NET Developer Platform)
- Scott Guthrie’s Blog (Corporate Vice President of the Developer Division)
June 26th, 2008 at 8:06 am by allan. 0 Comments
filed under Silverlight