您的位置:首页 > 运维架构 > 网站架构

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

2011-09-21 23:17 323 查看
下面我们利用附加属性,将我们准备好的Action集合能作为附加属性出现在xaml中:

1)附加属性类:

/// <summary>

/// 附加属性定义类,注意必须是静态的,这有点类似于给类增加扩展方法。

/// </summary>

public static class WPFTestDettach

{

/// <summary>

/// 注册附加属性。

/// </summary>

public static readonly DependencyProperty MyObjectsProperty =

DependencyProperty.RegisterAttached("MyObjects", typeof(MyActionCollection), typeof(WPFTestDettach),

new PropertyMetadata(null,(dobj,darg)=>{

//一般情况下这里可以不要。附加属性的目的是切入,而不会关心其属性的变化。

}));

/// <summary>

/// 这个方法是必须的,命名也有规则MyObjects =》 MyObjectsProperty = GetMyObjects。

/// 便于解释分析器获取该方法.

/// </summary>

/// <param name="obj"></param>

/// <returns></returns>

public static MyActionCollection GetMyObjects(DependencyObject obj)

{

MyActionCollection theC = (MyActionCollection)(obj.GetValue(MyObjectsProperty));

if (theC == null)

{

theC = new MyActionCollection();

obj.SetValue(MyObjectsProperty, theC);

}

theC.Obj = obj;

return theC;

}

//设置方法类似,不过这里没什么用处,所以从略.

}

2)定义好了附加属性,就可以用了,如何用,我们暂且不管,先看看,我们如何达到我们在前面一篇所提到的目的,这里我们实现一个具体的Action

/// <summary>

/// 具体的Action应用,面向TreeView类,可以截获事件,并执行相应的方法.

/// </summary>

public class MyActionTest : MyAction<TreeView>

{

/// <summary>

/// 挂接事件的地方,切入点.

/// </summary>

public override void OnAttached()

{

base.OnAttached();

//利用反射可以获取到对象的事件信息,并动态设置连接

//这里因为只是测试,所以简化。

switch (EventName)

{

case "SelectedItemChanged":

this.WObj.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(MyWPF_SelectedItemChanged);

break;

}

}

/// <summary>

/// 接挂的地方,清楚事件处理挂接,释放不必要的资源.

/// </summary>

public override void OnDetaching()

{

base.OnDetaching();

switch (EventName)

{

case "SelectedItemChanged":

this.WObj.SelectedItemChanged -= new RoutedPropertyChangedEventHandler<object>(MyWPF_SelectedItemChanged);

break;

}

}

/// <summary>

/// 事件处理的地方。

/// </summary>

/// <param name="sender"></param>

/// <param name="e"></param>

void MyWPF_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)

{

DoSomething(Params);

}

/// <summary>

/// 公开属性可通过Xaml中设置,EventName 要触发的时间名.

/// </summary>

public string EventName { get; set; }

/// <summary>

/// 参数字符串

/// </summary>

public string Params { get; set; }

/// <summary>

/// 目标对象,可以是当前页面的UI元素。当然,你也可以自己规定规则,做的非常复杂。

/// </summary>

public string TargetName { get; set; }

/// <summary>

/// 目标对象上的方法名,就是你需要执行的,注意对象上的这种方法必须是公共的.

/// </summary>

public string MethodName { get; set; }

/// <summary>

/// 具体事件处理,这里用到了反射.

/// </summary>

/// <param name="PMs"></param>

public void DoSomething(string PMs)

{

object theRootObj = GetRootObject(this.WObj);

object theTargetObj = null;

//如果目标元素为空,则取页面root element.

if (TargetName == "")

{

theTargetObj = theRootObj;

}

else

{

//获取目标UI元素.

theTargetObj = ((FrameworkElement)theRootObj).FindName(TargetName);

}

//获取目标方法并调用.

MethodInfo theMI = theTargetObj.GetType().GetMethod(MethodName);

if (theMI != null)

{

theMI.Invoke(theTargetObj,new object[]{PMs});

}

}

/// <summary>

/// 一个自定义的辅助函数,用于获取页面的根结点,这样可以查找本页的UI元素.

/// </summary>

/// <param name="obj"></param>

/// <returns></returns>

private FrameworkElement GetRootObject(FrameworkElement obj)

{

if (obj.Parent != null && obj.Parent is FrameworkElement)

{

return GetRootObject((FrameworkElement)(obj.Parent));

}

return obj;

}

}

做好了准备,下面我们就可以应用了.....待续
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: