title: C# WPF Draggable UserControls in ListBox on Canvas
body: <p>I have UserControls which i have in a ListBox, which then hosts them on a Canvas. I've then made the UserControls draggable on the canvas by using the DraggableExtender(<a href="https://stackoverflow.com/questions/294220/dragging-an-image-in-wpf">Dragging an image in WPF</a>).</p>
  
  <p>But ever since I changed from ItemsControl to ListBox, to be able to make the controls selectable, the Dragging works really bad. For instance if I'm dragging a control over another control the other control gets focused and sticks to the dragging. Also if I move the mouse outside the canvas the usercontrol gets stuck at the edge and i loose dragging focus, like if CaptureMouse doesn't work.</p>
  
  <p>The ListBox looks like this(when it worked before it was an ItemsControl):</p>
  
  <pre><code>&lt;ListBox ItemsSource="{Binding Components}" SelectedItem="{Binding SelectedItem}" Background="Transparent"&gt;
              &lt;ListBox.ItemsPanel&gt;
                  &lt;ItemsPanelTemplate&gt;
                      &lt;Canvas ClipToBounds="True" Height="{Binding CurrentProject.Height, Converter={StaticResource SizeConverter}}"
                              Width="{Binding CurrentProject.Width, Converter={StaticResource SizeConverter}}" 
                              HorizontalAlignment="Left" VerticalAlignment="Top"&gt;
                          &lt;Canvas.Background&gt;
                              &lt;SolidColorBrush Color="{DynamicResource {x:Static SystemColors.WindowFrameColorKey}}"/&gt;
                          &lt;/Canvas.Background&gt;
                      &lt;/Canvas&gt;
                  &lt;/ItemsPanelTemplate&gt;
              &lt;/ListBox.ItemsPanel&gt;
              &lt;ListBox.ItemContainerStyle&gt;
                  &lt;Style TargetType="{x:Type ListBoxItem}"&gt;
                      &lt;Setter Property="HorizontalAlignment" Value="Stretch" /&gt;
                      &lt;Setter Property="Background" Value="Transparent" /&gt;
                      &lt;Setter Property="Template"&gt;
                          &lt;Setter.Value&gt;
                              &lt;ControlTemplate TargetType="{x:Type ListBoxItem}"&gt;
                                  &lt;Grid&gt;
                                      &lt;Border Background="{TemplateBinding Background}" /&gt;
                                      &lt;ContentPresenter/&gt;
                                  &lt;/Grid&gt;
                                  &lt;ControlTemplate.Triggers&gt;
                                      &lt;MultiTrigger&gt;
                                          &lt;MultiTrigger.Conditions&gt;
                                              &lt;Condition Property="IsMouseOver" Value="True" /&gt;
                                              &lt;Condition Property="IsSelected" Value="False"/&gt;
                                          &lt;/MultiTrigger.Conditions&gt;
                                          &lt;Setter Property="Background" Value="#8868D5FD" /&gt;
                                      &lt;/MultiTrigger&gt;
                                      &lt;Trigger Property="IsSelected" Value="True"&gt;
                                          &lt;Setter Property="Background" Value="#4468D5FD" /&gt;
                                      &lt;/Trigger&gt;
                                  &lt;/ControlTemplate.Triggers&gt;
                              &lt;/ControlTemplate&gt;
                          &lt;/Setter.Value&gt;
                      &lt;/Setter&gt;
                      &lt;Setter Property="Utils:DraggableExtender.CanDrag" Value="True" /&gt;
                      &lt;Setter Property="Canvas.Top" Value="{Binding Path=Conveyor.Y, Converter={StaticResource SizeConverter},Mode=TwoWay}" /&gt;
                      &lt;Setter Property="Canvas.Left" Value="{Binding Path=Conveyor.X, Converter={StaticResource SizeConverter},Mode=TwoWay}" /&gt;
                  &lt;/Style&gt;
              &lt;/ListBox.ItemContainerStyle&gt;
          &lt;/ListBox&gt;
  </code></pre>
  
  <p>My DraggableExtender looks like this:</p>
  
  <pre><code>public class DraggableExtender : DependencyObject
      {
          public static readonly DependencyProperty CanDragProperty = 
              DependencyProperty.RegisterAttached("CanDrag", typeof(bool), typeof(DraggableExtender), 
              new UIPropertyMetadata(false, OnChangeCanDragProperty));
  
          private static bool isDragging = false;
          private static Point offset;
  
          public static void SetCanDrag(UIElement element, bool o)
          {
              element.SetValue(CanDragProperty, o);
          }
  
          public static bool GetCanDrag(UIElement element, bool o)
          {
              return (bool)element.GetValue(CanDragProperty);
          }
  
          private static void OnChangeCanDragProperty(DependencyObject d, DependencyPropertyChangedEventArgs e)
          {
              UIElement element = d as UIElement;
              if (element == null) return;
  
              if (e.NewValue != e.OldValue)
              {
                  if ((bool)e.NewValue)
                  {
                      element.PreviewMouseDown += element_PreviewMouseDown;
                      element.PreviewMouseUp += element_PreviewMouseUp;
                      element.PreviewMouseMove += element_PreviewMouseMove;
                  }
                  else
                  {
                      element.PreviewMouseDown -= element_PreviewMouseDown;
                      element.PreviewMouseUp -= element_PreviewMouseUp;
                      element.PreviewMouseMove -= element_PreviewMouseMove;
                  }
              }
          }
  
          private static void element_PreviewMouseDown(object sender, MouseButtonEventArgs e)
          {
              FrameworkElement element = sender as FrameworkElement;
              if (element == null) return;
              Debug.WriteLine(element);
  
              isDragging = true;
              element.CaptureMouse();
              offset = e.GetPosition(element);
          }
  
          private static void element_PreviewMouseMove(object sender, MouseEventArgs e)
          {
              if (!isDragging) return;
  
              FrameworkElement element = sender as FrameworkElement;
              if (element == null) return;
  
              Canvas canvas = element.FindAncestor&lt;Canvas&gt;();
              if (canvas == null) return;
  
              Point mousePoint = e.GetPosition(canvas);
  
              mousePoint.Offset(-offset.X, -offset.Y);
  
              element.SetValue(Canvas.LeftProperty, mousePoint.X);
              element.SetValue(Canvas.TopProperty, mousePoint.Y);
          }
  
          private static void element_PreviewMouseUp(object sender, MouseButtonEventArgs e)
          {
              FrameworkElement element = sender as FrameworkElement;
              if (element == null) return;
              element.ReleaseMouseCapture();
              isDragging = false;
          }
   }
  </code></pre>
  
  <p>I've been trying to find a solution but so far I've been unsuccessful. Does anyone have any idea why this is happening and how I can solve it?</p>