2008-11-16 28 views
16

Bir resmi sürükleyebileceğim bir WPF uygulaması oluşturmaya çalışıyorum.Bir görüntüyü WPF'ye sürükleme

Şu anda pencerenin ortasına yerleştirilmiş bir görüntü var ve görüntü sürüklerken yeni konumu hesaplamak için üç fare hareketini MouseDown, MouseMove ve MouseUp kullanmayı düşünüyorum.

Bunun nasıl yapılacağı konusunda başka iyi fikirler var mı? WPF'ye tamamen yeniyim, bu yüzden zihnim hala Windows Forms dünyasında.

Görebildiğim kadarıyla, mutlak konumlandırmaya sahip olmak için kullanmam gerekiyor.

cevap

31

Tamam, burada ekli bir özelliği sürüklenebilir herhangi eleman bir tuval üzerinde bulunuyor sağlanan yapmak için kullanabilirsiniz "davranış":

Ardından sınıftır ad ithal ederek XAML kullanabilirsiniz
public class DraggableExtender : DependencyObject 
{ 
    // This is the dependency property we're exposing - we'll 
    // access this as DraggableExtender.CanDrag="true"/"false" 
    public static readonly DependencyProperty CanDragProperty = 
     DependencyProperty.RegisterAttached("CanDrag", 
     typeof(bool), 
     typeof(DraggableExtender), 
     new UIPropertyMetadata(false, OnChangeCanDragProperty)); 

    // The expected static setter 
    public static void SetCanDrag(UIElement element, bool o) 
    { 
     element.SetValue(CanDragProperty, o); 
    } 

    // the expected static getter 
    public static bool GetCanDrag(UIElement element) 
    { 
     return (bool) element.GetValue(CanDragProperty); 
    } 

    // This is triggered when the CanDrag property is set. We'll 
    // simply check the element is a UI element and that it is 
    // within a canvas. If it is, we'll hook into the mouse events 
    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; 
      } 
     } 
    } 

    // Determine if we're presently dragging 
    private static bool _isDragging = false; 
    // The offset from the top, left of the item being dragged 
    // and the original mouse down 
    private static Point _offset; 

    // This is triggered when the mouse button is pressed 
    // on the element being hooked 
    static void element_PreviewMouseDown(object sender, 
      System.Windows.Input.MouseButtonEventArgs e) 
    { 
     // Ensure it's a framework element as we'll need to 
     // get access to the visual tree 
     FrameworkElement element = sender as FrameworkElement; 
     if (element == null) return; 

     // start dragging and get the offset of the mouse 
     // relative to the element 
     _isDragging = true; 
     _offset = e.GetPosition(element); 
    } 

    // This is triggered when the mouse is moved over the element 
    private static void element_PreviewMouseMove(object sender, 
       MouseEventArgs e) 
    { 
     // If we're not dragging, don't bother - also validate the element 
     if (!_isDragging) return; 

     FrameworkElement element = sender as FrameworkElement; 
     if (element == null) return; 

     Canvas canvas = element.Parent as Canvas; 
     if(canvas == null) return; 

     // Get the position of the mouse relative to the canvas 
     Point mousePoint = e.GetPosition(canvas); 

     // Offset the mouse position by the original offset position 
     mousePoint.Offset(-_offset.X, -_offset.Y); 

     // Move the element on the canvas 
     element.SetValue(Canvas.LeftProperty, mousePoint.X); 
     element.SetValue(Canvas.TopProperty, mousePoint.Y); 
    } 

    // this is triggered when the mouse is released 
    private static void element_PreviewMouseUp(object sender, 
      MouseButtonEventArgs e) 
    { 
     _isDragging = false; 
    } 

} 

içerdiği (böyle bir şey

<Window x:Class="WPFFunWithDragging.Window1" 
     xmlns:local="clr-namespace:WPFFunWithDragging" .. > 

:) Ve sonra öylece sürüklemek unsurları DraggableExtender.CanDrag = "true" ayarlayabilirsiniz:

<Canvas> 
    <Image Source="Garden.jpg" 
      Width="50" 
      Canvas.Left="10" Canvas.Top="10" 
      local:DraggableExtender.CanDrag="true"/> 
</Canvas> 

Bunun bir yararı olduğunu umuyorum :)

+2

Teşekkürler - çok kullanışlı kod. Elemanın fareyi farenin içinde yakalamasını sağlayarak ve fareyle fareyi ele geçirdikten sonra onu biraz iyileştiririm. Aksi taktirde farenin sürüklenmekte olan öğenin sınırlarının dışına düşmesi durumunda fare hareketlerini kaçırmak kolaydır. –

+0

İyi nokta - Ben sadece chromeless pencereleri için benzer bir şey yaptım, bu öneri ekleyecektir;) –

+0

Görüntünün sadece tuval sınırında sürüklenmesini zorlamak için bir yol var mı? – Melursus

İlgili konular