轉(zhuǎn)帖|其它|編輯:郝浩|2011-04-14 13:42:35.000|閱讀 1121 次
概述:實(shí)際中經(jīng)常用到拖拽控件本身,這在WPF中怎么實(shí)現(xiàn)呢?筆者想到可以利用WPF中的DataTemple, DataTemple定義了用來展現(xiàn)數(shù)據(jù)的界面模板,你可以想象即使在界面層,你操作控制的也是一堆數(shù)據(jù),這些數(shù)據(jù)的展現(xiàn)交給DataTemplate來做。那還等什么,利用它來實(shí)現(xiàn)Drag&Drop控件吧。
# 界面/圖表報(bào)表/文檔/IDE等千款熱門軟控件火熱銷售中 >>
WPF中提供一套十分簡(jiǎn)便的實(shí)現(xiàn)Drag&Drop的機(jī)制,方便了開發(fā)人員定制自己的Drag&Drop行為。
但是WPF中提供的Drag&Drop是基于數(shù)據(jù)傳遞的,通過Drag把你希望傳遞的數(shù)據(jù)放入DataObject對(duì)象里, 調(diào)用DragDrop.DoDragDrop(), 在Drop事件Hander里就可以獲取到你剛才傳入的數(shù)據(jù),在使對(duì)這些數(shù)據(jù)做處理就完成了整個(gè)Drag&Drop行為。
實(shí)際中經(jīng)常用到拖拽控件本身,這在WPF中怎么實(shí)現(xiàn)呢?筆者想到可以利用WPF中的DataTemple, DataTemple定義了用來展現(xiàn)數(shù)據(jù)的界面模板,你可以想象即使在界面層,你操作控制的也是一堆數(shù)據(jù),這些數(shù)據(jù)的展現(xiàn)交給DataTemplate來做。那還等什么,利用它來實(shí)現(xiàn)Drag&Drop控件吧。
下面是我的一個(gè)Sample, 供大家參考:
1.首先定義PresenterDataForButton和PresenterDataForTextBox 分別代表 Button 和TextBox控件的Data類型:
1 public interface ITragable
2 {
3 }
4 public class PresenterDataForButton :ITragable
5 {
6 public string Content
7 {
8 get;
9 set;
10 }
11
12 public RoutedEventHandler ButtonClickHandler;
13
14 }
15
16 public class PresenterDataForTextBox : ITragable
17 {
18 public string Text
19 {
20 get;
21 set;
22 }
23 }
2. 利用DataTemple使數(shù)據(jù)分別展現(xiàn)成Button和TextBox控件,注意本例中DataTemple的定義是放在Window的Resouce中,并且是使用的是DataType,這樣整個(gè)window中的PresenterDataForButton和PresenterDataForTextBox 都會(huì)被展現(xiàn)成相應(yīng)的控件:
1 <Window x:Class="MyDragAndDrop.MainWindow"
2 xmlns="//schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x= "//schemas.microsoft.com/winfx/2006/xaml"
4 xmlns:local= "clr-namespace:MyDragAndDrop"
5 Title= "MainWindow" Height="350" Width="525">
6 <Window.Resources>
7
8 <DataTemplate DataType="{x:Type local:PresenterDataForButton}">
9 <Button Content="{Binding Path=Content}"/>
10 </DataTemplate>
11 <DataTemplate DataType="{x:Type local:PresenterDataForTextBox}">
12 <TextBox Text="{Binding Path=Text}"/>
13 </DataTemplate>
14
15 </Window.Resources>
16 <DockPanel >
17 <ListView x:Name="listView" DockPanel.Dock="Left"
18 PreviewMouseLeftButtonDown="listView_PreviewMouseLeftButtonDown"
19 PreviewMouseMove="listView_PreviewMouseMove"/>
20 <Canvas Drop="ContentControl_Drop" DockPanel.Dock="Right"
21 AllowDrop="True" Background="LightBlue"
22 DragEnter="ContentControl_DragEnter" Height="260" Width="272">
23 <StackPanel x:Name="myStackPanel"/>
24
25 </Canvas>
26 </DockPanel>
27
28 </Window>
3. 最后通過Drag&Drop你的數(shù)據(jù),達(dá)到拖拽控件的效果。
1 using System;
2 using System.Collections.Generic;
3 using System.Linq;
4 using System.Text;
5 using System.Windows;
6 using System.Windows.Controls;
7 using System.Windows.Data;
8 using System.Windows.Documents;
9 using System.Windows.Input;
10 using System.Windows.Media;
11 using System.Windows.Media.Imaging;
12 using System.Windows.Navigation;
13 using System.Windows.Shapes;
14
15 namespace MyDragAndDrop
16 {
17 /// <summary>
18 /// Interaction logic for MainWindow.xaml
19 /// </summary>
20 public partial class MainWindow : Window
21 {
22 private Point m_startPoint;
23
24 public MainWindow()
25 {
26 InitializeComponent();
27 this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
28 }
29
30
31 private void MainWindow_Loaded(object sender, RoutedEventArgs e)
32 {
33
34 this.listView.Items.Add(new PresenterDataForButton
35 {
36 Content = "Click Me",
37 ButtonClickHandler = (object sender1, RoutedEventArgs e1) =>
38 {
39 MessageBox.Show("Clicked");
40 }
41 });
42
43 this.listView.Items.Add(new PresenterDataForTextBox
{ Text = "It is a TextBox." });
44
45 }
46
47 private void listView_PreviewMouseLeftButtonDown
(object sender, MouseButtonEventArgs e)
48 {
49 m_startPoint = e.GetPosition(null);
50
51 }
52
53 private void listView_PreviewMouseMove(object sender, MouseEventArgs e)
54 {
55 // Get the current mouse position
56 Point mousePos = e.GetPosition(null);
57 Vector diff = m_startPoint - mousePos;
58
59 if (e.LeftButton == MouseButtonState.Pressed &&
60 Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
61 Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
62 {
63 // Get the dragged ListViewItem
64 ListView listView = sender as ListView;
65 if (null != listView)
66 {
67
68 ListViewItem listViewItem =
69 FindAnchestor<ListViewItem>((DependencyObject)e.OriginalSource);
70
71 if (null != listViewItem)
72 {
73
74 // Find the data behind the ListViewItem
75 object dragedObject = listView.ItemContainerGenerator.
76 ItemFromContainer(listViewItem);
77
78 // Initialize the drag & drop operation
79 DataObject dragData = new DataObject("myFormat", dragedObject);
80 DragDrop.DoDragDrop(listViewItem, dragData, DragDropEffects.Move);
81 }
82 }
83 }
84
85 }
86
87
88 // Helper to search up the VisualTree
89 private static T FindAnchestor<T>(DependencyObject current)
90 where T : DependencyObject
91 {
92 do
93 {
94 if (current is T)
95 {
96 return (T)current;
97 }
98 current = VisualTreeHelper.GetParent(current);
99 }
100 while (current != null);
101 return null;
102 }
103
104 private void ContentControl_Drop(object sender, DragEventArgs e)
105 {
106 if (e.Data.GetDataPresent("myFormat"))
107 {
108 ITragable dragedObject = e.Data.GetData("myFormat") as ITragable;
109 if(null!=dragedObject)
110 {
111 Canvas canvas = sender as Canvas;
112 var content = new ContentControl();
113 content.Content = dragedObject;
114 myStackPanel.Children.Add(content);
115 }
116 }
117
118 }
119
120 private void ContentControl_DragEnter(object sender, DragEventArgs e)
121 {
122 if (!e.Data.GetDataPresent(typeof(ITragable)) ||
123 sender == e.Source)
124 {
125 e.Effects = DragDropEffects.None;
126 }
127
128
129 }
130
131
132
133 }
134 }
本站文章除注明轉(zhuǎn)載外,均為本站原創(chuàng)或翻譯。歡迎任何形式的轉(zhuǎn)載,但請(qǐng)務(wù)必注明出處、不得修改原文相關(guān)鏈接,如果存在內(nèi)容上的異議請(qǐng)郵件反饋至chenjj@fc6vip.cn
文章轉(zhuǎn)載自:博客園