【www.gdgbn.com--Silverlight】

silverlight智能表单实现代码

控件从工具箱到画板的拖动让我想到了tookit中dragdroptarget控件,工具箱好说用listbox或者treeview,画板就不知道怎么搞了,于是决定自己做dragdrop。

 

左侧的是一个listbox,右侧红色的是canvas。创建一个类库dragdroplibrary(这个名不知道好不好听)。

点击左侧的listbox,然后移动鼠标到右侧红色部分,松开鼠标控件就放到松开的位置,思路就这么简单。

listbox的xaml:(controls = new string[3] { "textbox", "button", "textblock" };这个是给listbox的数据,测试。。。)


   
       
           
       

   

item就一个textblock,我们要注册mouseleftbuttondown事件。

在dragdroplibrary中添加一个类:

show sourceview sourceprint?01 using system.windows; 

02 using system.windows.controls; 

03 using system.windows.input; 

04 using system.windows.media; 

05 using system.windows.media.imaging; 

06   

07 namespace dragdroplibrary 

08 { 

09     public static class dragdropmanage 

10     { 

11         private static panel _root, _board; 

12         //drop 

13         public delegate void drop(dragdropeventargs target); 

14         private static drop _ondrag; 

15         private static dragdropeventargs eveargs; 

16           

17         //鼠标拖动时跟随效果 

18         private static image _mouseeffert; 

19   

20         ///

 

21         /// 拖动之前调用 

22         ///

 

23         /// 根panel(children中包含工具箱和画板) 

24         /// 画板 

25         public static void register(panel root, panel board) 

26         { 

27             _root = root; 

28             _board = board; 

29             if (_root is grid) 

30             { 

31                 grid.setcolumnspan(_mouseeffert, (_root as grid).columndefinitions.count+1); 

32                 grid.setrowspan(_mouseeffert, (_root as grid).rowdefinitions.count+1); 

33             } 

34         } 

35   

36         static dragdropmanage() 

37         { 

38             _mouseeffert = new image(); 

39         } 

40   

41         public static void begindrag(object sender, mousebuttoneventargs e, drop drop) 

42         { 

43             frameworkelement target = sender as frameworkelement; 

44             writeablebitmap bitmap = new writeablebitmap(target, new translatetransform()); 

45             _mouseeffert.source =bitmap; 

46             _mouseeffert.height = bitmap.pixelheight; 

47             _mouseeffert.width = bitmap.pixelwidth; 

48             _root.children.add(_mouseeffert); 

49             point position = e.getposition(_root); 

50             _mouseeffert.margin = new thickness(position.x, position.y, 0, 0); 

51   

52             _mouseeffert.horizontalalignment = horizontalalignment.left; 

53             _mouseeffert.verticalalignment = verticalalignment.top; 

54             _mouseeffert.capturemouse(); 

55             eveargs = new dragdropeventargs(target); 

56   

57             _ondrag = drop; 

58             _root.mousemove += onrootmousemove; 

59             _root.mouseleftbuttonup += onrootmouseleftbuttonup; 

60         } 

61   

62         private static void clear() 

63         { 

64             _root.mousemove -= onrootmousemove; 

65             _root.mouseleftbuttonup -= onrootmouseleftbuttonup; 

66             _root.children.remove(_mouseeffert); 

67             _ondrag = null; 

68             eveargs = null; 

69         } 

70   

71         private static void onrootmouseleftbuttonup(object sender, mousebuttoneventargs e) 

72         { 

73             eveargs.position = e.getposition(_board); 

74             _ondrag(eveargs); 

75             clear(); 

76         } 

77   

78         private static void onrootmousemove(object sender, mouseeventargs e) 

79         { 

80             point position = e.getposition(_root); 

81             _mouseeffert.margin = new thickness(position.x, position.y, 0, 0); 

82   

83             point currentposition = e.getposition(_board); 

84             if (currentposition.x > 0 && currentposition.x < _board.actualwidth 

85                 && currentposition.y > 0 && currentposition.y < _board.actualheight) 

86             { 

87                 eveargs.accept = true; 

88             } 

89             else

90             { 

91                 eveargs.accept = false; 

92             } 

93         } 

94     } 

95 }
show sourceview sourceprint?01 using system; 

02 using system.windows; 

03   

04 namespace dragdroplibrary 

05 { 

06     public class dragdropeventargs : eventargs 

07     { 

08         public bool accept { get; set; } 

09   

10         public point position { get; internal set; } 

11   

12         public frameworkelement target { get; private set; } 

13   

14         public dragdropeventargs(frameworkelement target) 

15         { 

16             target = target; 

17             position = new point(0, 0); 

18         } 

19     } 

20 }

 

  这个eventargs类也一并贴出。

dragdropmanage我做成了静态类,我的电脑只有一个鼠标,而且我也没有多点触控的装备,不知道多点触控能不能同时托两个或者更多控件。

在最最最开始,我们需要初始化dragdroplibrary.dragdropmanage.register(layoutroot, boardcanvas);

layoutroot这个都知道,就是程序的根容器,boardcanvas就是上面说的红色的canvas。

textblock鼠标点击事件,这时我们就开始拖动了。drop1是一个方法,用来当我们松开鼠标时的回调方法。

private void onlistboxitemmouseleftbuttondown(object sender, mousebuttoneventargs e)
{
            dragdroplibrary.dragdropmanage.begindrag(sender, e, drop1);
}

 

show sourceview sourceprint?01 public void drag1(dragdroplibrary.dragdropeventargs target) 

02 { 

03     if (target.accept) 

04     { 

05         string name = (target.target as textblock).text; 

06         frameworkelement element = null; 

07           

08         type type = gettypefromstring(name); 

09         if (type != null) 

10         { 

11             element = activator.createinstance(type) as frameworkelement; 

12   

13             if (target.position != null) 

14             { 

15                 canvas.setleft(element, target.position.x); 

16                 canvas.settop(element, target.position.y); 

17             } 

18   

19             element.width = 80; 

20             element.height = 40; 

21   

22             boardcanvas.children.add(element); 

23         } 

24     } 

25 } 

26 private type gettypefromstring(string typename) 

27 { 

28     type type = null; 

29     typename = "system.windows.controls." + typename; 

30     assembly assembly = assembly.load("system.windows, version=2.0.5.0, culture=neutral, publickeytoken=7cec85d7bea7798e"); 

31   

32     type = assembly.gettype(typename); 

33     return type; 

34 }

 

 

在drop1中target是listbox中的textblock所以直接转了。

几点说明:

1.dragdropeventargs中accept是用来说明,松开鼠标时,当前鼠标的位置是不是落在canvas中。position指示当前位置

2.dragdropeventargs中target是鼠标点击时的控件。

3.生成控件我是根据名称和程序集,这两个东西获取的,一开始我设想的就是把所有的控件存到xml文件中,包括他的中文名,全名,以及程序集,这样listbox中的控件就可以反射出来了。

4.拖动时要在根容器中注册mousemove事件以及mousedown。

5.打了个漫长的电话就不知道该说些什么了,今天周五,各位大侠玩的开心。

本文来源:http://www.gdgbn.com/asp/28897/