WPF架构关键技术剖析(3)--做自己的交互Action(1)

本来打算写得细些,但最近要换工作,所以比较忙点,而且也觉得没必要写那么多虚的东西,因此这里不再按照提纲进行,而是从代码入手,看清Silverlight的交互机制.依赖属性和附加属性的基本类都是一样的,但依赖属性和附加属性的用途还是有区别的,依赖属性更多的是属性,而附加属性更多的是扩展,有点类似于类的扩展方法,附加属性非常重要,很多交互的实现其实都是利用这个特性来实现的,附加属性为你对现有UI元素进行交互注入提供了切入点。从某种意义上来讲,这也是AOP编程的一个典范。依赖属性的模拟可以参见我前面的博文,这里不再对依赖属性进行讨论,附加属性的实现我会有具体的代码,因为这些代码也是我们自己的交互Action能够实现的关键。

我们要实现的Action交互,准备实现如下功能:
1)可以附加到任何界面元素;
2)能够响应到UI界面元素的一些事件;
3)能够调用设置的目标方法(类似于CallMethodBehavior).当然,这里的参数都是静态设置的,如果要可以互相绑定,其实可以利用Binding类。也可以自己简单解析路径取值.

为了提高可扩展性,我们定义一个MyAction基类,一个MyAction集合MyActionCollection.用于一个UI元素可以同时有多个Action.

A) MyAction和MyAction<T>类。

/// <summary>
/// 提供一个公共的借口
/// </summary>
public abstract class MyAction
{
public MyAction()
{
}
/// <summary>
/// 提供附加操作方法,供元素附加时调用,在具体Action附加时,可以注入功能。
/// </summary>
public abstract void OnAttached();
/// <summary>
/// 跟上面相反的功能.
/// </summary>
public abstract void OnDetaching();
/// <summary>
/// 附着对象,类似于Behavior的AssociatedObject.
/// </summary>
public object Obj { get; set; }
/// <summary>
/// 没什么用,可以不需要.
/// </summary>
public string MyName { get; set; }
}

/// <summary>
/// 定义一个模板类型的,目的是为了下面继承时操作方便,当然也可以利用反射在这里做一些处理,不过这里是演示,没做什么特别的处理。
/// </summary>
/// <typeparam name="T"></typeparam>
public class MyAction<T> : MyAction where T:UIElement
{
public MyAction()
{
}
public T WObj { get { return (T)(base.Obj); } } //换成目标泛型类,便于子类的书写方便,不用每次都要转换.
public override void OnAttached()
{

}
public override void OnDetaching()
{

}
}

B)Action集合类

/// <summary>
/// Action集合类,主要提供一些集合变化时的附加功能,这个类要肩负着将附着对象传递给Action的责任.
/// </summary>
public class MyActionCollection : System.Collections.ObjectModel.Collection<MyAction>
{
public MyActionCollection()
{

}
//注意这里,Action被插入进来,这里调用OnAttached方法,给Action子类注入功能的机会.
protected override void InsertItem(int index, MyAction item)
{
item.Obj = Obj;//将关联对象赋给Action,便于注入功能.
base.InsertItem(index, item);
item.OnAttached();//让Action有机会注入功能,Action初始化是并不能注入功能,因为其关联对象还没有,能做的事情有限。

}
//与上同.但没什么实际用处.
protected override void SetItem(int index, MyAction item)
{
item.Obj = Obj ;
base.SetItem(index, item);
item.OnAttached();
}
//Action被移除,提供Action释放资源的机会.
protected override void RemoveItem(int index)
{
MyAction theItem = this[index];
theItem.OnDetaching();
base.RemoveItem(index);

}
//附加对象,当然一般会定义成DependencyObject。
public object Obj { get; set; }
public string MyName { get; set; }
}

基本Action及其集合定义完成,下面就是如何让这个集合能附加到页面元素了.

你可能感兴趣的:(action)