三、创建定制的反色行为组件
Silverlight 3中一个强大的功能是提供了对行为和触发器的支持。借助于行为和触发器等新特征,你可以以更加面向对象的方式来实现Silverlight编程。
一般情况下,在Silverlight 3编程环境下,你可以使用四种类型的行为—Behavior、TriggerAction、TriggerBase和TargetedTriggerAction。其中,在Microsoft Expression Blend 3中,你可以添加三种定制的行为类,分别是Behavior类、Trigger类和Action类。
在本文中,我们将创建这样一个定制的行为组件:当你单击某个图像时,由于与此图像相关联的行为的作用,图像的颜色能够以反色显示。
(1)开发定制行为组件—InverseColorClickBehavior
对于简单的应用情形,使用从泛型Behavior类派生的方式是创建一个定制行为的首要选择。这个类只有两个可重载的方法—OnAttached和OnDetaching,分别用于通知当前的行为某个对象何时附加于其上以及何时与其分离。
上面的泛型类Behavior中的T是一个依赖对象。在大多数情况下,你只需要从Behavior或Behavior加以派生即可。
为了简化编程,本游戏直接使用了开源网站http://www.codeplex.com/wpffx中提供的一个现成的WPF Pixel Shader 效果库的一部分。为了适应本游戏,我们还作了一些简单修改。
我们的定制行为组件名字是InverseColorClickBehavior,其关键代码如下:
using ShaderEffectsLibrary;
namespace SLFreeCell.Behaviors{
public class InverseColorClickBehavior : Behavior{
InverseColor inverseColor;
public InverseColorClickBehavior() :base(){
this.inverseColor = new InverseColor();
}
protected override void OnAttached(){
base.OnAttached();
this.AssociatedObject.MouseLeftButtonDown += new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonDown);
}
protected override void OnDetaching(){
base.OnDetaching();
this.AssociatedObject.MouseLeftButtonDown -= new MouseButtonEventHandler(AssociatedObject_MouseLeftButtonDown);
}
private void AssociatedObject_MouseLeftButtonDown(object sender, MouseButtonEventArgs e) {
this.AssociatedObject.Effect =
this.AssociatedObject.Effect == null ?
this.AssociatedObject.Effect = this.inverseColor :
this.AssociatedObject.Effect = null;
}
}
}
显然,针对我们想实现的反色效果而言,我们仅对鼠标单击事件感兴趣。
因此,在OnAttached方法中,我们需要订阅行为的关联对象的MouseLeftButtonDown事件。对应地,在OnDetaching方法中,我们还要实现取消订阅这个MouseLeftButtonDown事件。
接下来,剩下的就是在关联对象的MouseLeftButtonDown事件处理器中进行编程,以便实现我们想要的反色效果。
上述代码中的反色效果类inverseColor是我们自定制的一个效果类。效果组件(Effect)是自Silverlight 3始引入的一种控制图像效果的组件。有关如何创建定制效果组件是一个非常复杂的问题,请参考文章所附源码及MSDN有关资料,在此不再赘述。
在上面代码中的关联对象将指向游戏中的Card控件。根据游戏需要,我们只要控制这个控件的Effect属性值即可。根据单击扑克的次数是奇数次还是偶数次,相应地设置或清除控件的Effect属性值,从而实现扑克外观的反色效果。
(2)使用定制行为InverseColorClickBehavior
关于使用行为组件的一个重要特征是,一次只能把一个行为关联到一个控件上,而一个控件可以被关联到多个行为上。
首先,因为我们总共有52张扑克,所以可以定义一个数组变量来存储对应的52个反色行为:
InverseColorClickBehavior[] InverseBehaviorArray;
然后,要初始化这个数组(在InitAndStartGame方法中实现):
InverseBehaviorArray = new InverseColorClickBehavior[52];
for (int i = 0; i < 52; i++)
InverseBehaviorArray[i] = new InverseColorClickBehavior();
最后,看一下如何使用上述行为数组(在方法GenerateAndDealCards中):
InverseBehaviorArray[i].Attach(arrPoker[RandomI[i]]);
每当创建一张扑克时,我们把一个对应的反色行为关联到其上。