Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>There are many ways to implement drag/drop in WPF, and none of them are really trivial. For example you could:</p> <ul> <li>Add <a href="http://msdn.microsoft.com/en-us/library/system.windows.controls.primitives.thumb%28v=vs.100%29.aspx" rel="nofollow">Thumbs</a> to a Canvas and implement dragstart, dragcomplete and dragdelta</li> <li>Use Adorners. Good article <a href="http://www.zagstudio.com/blog/488#.Ug3agpLIapc" rel="nofollow">here</a>.</li> <li>Use RenderTransform and create a TranslateTransform to move the control. And manually implement mousedown, mousemove and mouseup on your window/usercontrol.</li> </ul> <p>The following code uses the RenderTransform property of runtime generated Labels to move them around on the screen as the user drags them with the mouse. A limitation of my example is that you cannot have other transforms applied to your labels because it will be overwritten. Consider using a TransformGroup.</p> <p><strong>Xaml</strong></p> <pre><code>&lt;Window x:Class="WpfApplication2.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="MainWindow" Height="350" Width="525" Background="Gray" PreviewMouseLeftButtonDown="Window_PreviewMouseLeftButtonDown" PreviewMouseMove="Window_PreviewMouseMove" PreviewMouseLeftButtonUp="Window_PreviewMouseLeftButtonUp"&gt; &lt;Grid&gt; &lt;ItemsControl ItemsSource="{Binding LabelsCollection}"&gt; &lt;ItemsControl.ItemsPanel&gt; &lt;ItemsPanelTemplate&gt; &lt;StackPanel /&gt; &lt;/ItemsPanelTemplate&gt; &lt;/ItemsControl.ItemsPanel&gt; &lt;ItemsControl.ItemTemplate&gt; &lt;DataTemplate&gt; &lt;Label HorizontalAlignment="Center" Content="{Binding}"&gt;&lt;/Label&gt; &lt;/DataTemplate&gt; &lt;/ItemsControl.ItemTemplate&gt; &lt;/ItemsControl&gt; &lt;/Grid&gt; </code></pre> <p></p> <p><strong>Code behind</strong></p> <pre><code>public partial class MainWindow : Window, INotifyPropertyChanged { private List&lt;DependencyObject&gt; _hitResultsList = new List&lt;DependencyObject&gt;(); private Point _currentlyDraggedMouseOffset; private Label _currentlyDragged; private ObservableCollection&lt;string&gt; _labelsCollection; public event PropertyChangedEventHandler PropertyChanged; public MainWindow() { DataContext = this; InitializeComponent(); LabelsCollection = new ObservableCollection&lt;string&gt;(); for (int i = 1; i &lt;= 10; i++) { LabelsCollection.Add("Label " + i); } } public ObservableCollection&lt;string&gt; LabelsCollection { get { return _labelsCollection; } set { _labelsCollection = value; if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs("LabelsCollection")); } } } private void Window_PreviewMouseMove(object sender, MouseEventArgs e) { if (_currentlyDragged != null) { var mousePos = e.GetPosition(this); _currentlyDragged.RenderTransform = new TranslateTransform(mousePos.X - _currentlyDraggedMouseOffset.X, mousePos.Y - _currentlyDraggedMouseOffset.Y); } } private void Window_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e) { _currentlyDragged = null; ReleaseMouseCapture(); } private void Window_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) { CaptureMouse(); Point pt = e.GetPosition((UIElement)sender); _hitResultsList.Clear(); VisualTreeHelper.HitTest(this, null, new HitTestResultCallback(MyHitTestResult), new PointHitTestParameters(pt)); if (_hitResultsList.Count &gt; 0) { foreach (DependencyObject d in _hitResultsList) { var parent = VisualTreeHelper.GetParent(d); if (parent != null &amp;&amp; parent is Label) { _currentlyDragged = parent as Label; if (_currentlyDragged.RenderTransform is TranslateTransform) { _currentlyDraggedMouseOffset.X = e.GetPosition(this).X - ((TranslateTransform)_currentlyDragged.RenderTransform).X; _currentlyDraggedMouseOffset.Y = e.GetPosition(this).Y - ((TranslateTransform)_currentlyDragged.RenderTransform).Y; } else { _currentlyDraggedMouseOffset.X = pt.X; _currentlyDraggedMouseOffset.Y = pt.Y; } return; } } } _currentlyDragged = null; } // Return the result of the hit test to the callback. public HitTestResultBehavior MyHitTestResult(HitTestResult result) { _hitResultsList.Add(result.VisualHit); return HitTestResultBehavior.Continue; } } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload