SL3开始支持Behavior(行为),这个东西可不得了,可以为不同的UI提供各种“花招”。
比如在Expression Blend里本身的MouseDrapElementBehavior,更是一句代码不用写,就可以实现元素拖动效果。
太强大了。
小弟不才,也学着写了一个小示例学习一下,发现制作起来还是非常简单的。先看看效果:
这个示例是为了解决Silverlight本身的ToolTip不能跟随鼠标移动问题的。
实现的代码都不太难,注释也比较清晰了,不在此赘叙了。
行为代码
1 public class MoveingTipsBehavior:Behavior<UIElement>
2 {
3 public static readonly DependencyProperty MoveingToolTipProperty = DependencyProperty.Register("MoveingToolTip", typeof(FrameworkElement), typeof(MoveingTipsBehavior), new PropertyMetadata(new TextBlock { Text = "MoveingToolTips", }));
4
5 /**//// <summary>
6 /// 行为附加
7 /// </summary>
8 protected override void OnAttached()
9 {
10 //注册行为对象鼠标事件
11 AssociatedObject.MouseEnter += new MouseEventHandler(AssociatedObject_MouseEnter);
12 AssociatedObject.MouseLeave += new MouseEventHandler(AssociatedObject_MouseLeave);
13 AssociatedObject.MouseMove += new MouseEventHandler(AssociatedObject_MouseMove);
14 base.OnAttached();
15 }
16
17 /**//// <summary>
18 /// 需要移动的ToolTip对象
19 /// </summary>
20 public FrameworkElement MoveingToolTip
21 {
22 get
23 {
24 return (FrameworkElement)GetValue(MoveingToolTipProperty);
25 }
26 set
27 {
28 SetValue(MoveingToolTipProperty, value);
29 }
30 }
31
32 /**//// <summary>
33 /// 当鼠标在行为附加对象上移动事执行
34 /// </summary>
35 void AssociatedObject_MouseMove(object sender, MouseEventArgs e)
36 {
37 Panel parent = GetFristParentPanel();
38 if (parent.Children.Contains(MoveingToolTip))
39 {
40 Point MousePoint = e.GetPosition(parent);
41 //调整ToolTip位置
42 MoveingToolTip.Margin = new Thickness(MousePoint.X, MousePoint.Y, 0, 0);
43 }
44 }
45
46 /**//// <summary>
47 /// 获取最近的一个Panel容器
48 /// </summary>
49 /// <remarks>当没有找到任何Panel时,抛出异常</remarks>
50 private Panel GetFristParentPanel()
51 {
52 var temp = VisualTreeHelper.GetParent(AssociatedObject);
53 if (!(temp is Panel))
54 {
55 while (true)
56 {
57 temp = VisualTreeHelper.GetParent(temp);
58 if (temp != null && temp is Panel)
59 {
60 return (Panel)temp;
61 }
62 if (temp == null)
63 {
64 throw new MethodAccessException();
65 }
66 }
67 }
68 else
69 {
70 return (Panel)temp;
71 }
72 }
73
74 /**//// <summary>
75 /// 鼠标在行为对象上离开事件
76 /// </summary>
77 void AssociatedObject_MouseLeave(object sender, MouseEventArgs e)
78 {
79 Panel parentPanel = GetFristParentPanel();
80 if(parentPanel.Children.Contains(MoveingToolTip))
81 {
82 //清除ToolTip
83 parentPanel.Children.Remove(MoveingToolTip);
84 }
85 }
86
87 /**//// <summary>
88 /// 鼠标移动到行为对象上执行
89 /// </summary>
90 void AssociatedObject_MouseEnter(object sender, MouseEventArgs e)
91 {
92 Panel parentPanel = GetFristParentPanel();
93 if (!parentPanel.Children.Contains(MoveingToolTip))
94 {
95 //把ToolTip添加到最近的容器中
96 parentPanel.Children.Add(MoveingToolTip);
97 }
98 }
99 } 写以上代码只用了10分钟左右,当然BUG是有不少:
1.MouseMove事件取消了在SL2中的Handled属性,导致如果在多个Panel嵌套的时候,会出现多个ToolTip的情况。
2.鼠标移动到ToolTip上时,依然会接受MouseEnter事件,希望有高手能指导一下,谢谢!
点击这里下载源文件