2011年3月1日 星期二

WPF 拖放

請看下列文章 Overview:
http://msdn.microsoft.com/zh-tw/library/ms742859.aspx

這篇是範例:
http://www.wpftutorial.net/DragAndDrop.html

Drag&Drop in 6 Steps

  1. Detect a drag as a combinatination of MouseMove and MouseLeftButtonDown
  2. Find the data you want to drag and create a DataObject that contains the format, the data and the allowed effects.
  3. Initiate the dragging by calling DoDragDrop()
  4. Set the AllowDrop property to True on the elements you want to allow dropping.
  5. Register a handler to the DragEnter event to detect a dragging over the drop location. Check the format and the data by calling GetDataPresent() on the event args. If the data can be dropped, set the Effect property on the event args to display the appropriate mouse cursor.
  6. When the user releases the mouse button the DragDrop event is called. Get the data by calling the GetData() method on the Data object provided in the event args. 

Example Code:

XAML  ---------------------------------------------------------

<Window x:Class="WpfDragDrop.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="237" Width="284">
    <Grid>
        <Label Content="DragSource" Height="28" HorizontalAlignment="Left" Margin="29,12,0,0" 
               Name="label1" VerticalAlignment="Top" 
               PreviewMouseLeftButtonDown="label1_PreviewMouseLeftButtonDown" 
               PreviewMouseMove="label1_PreviewMouseMove" />
        
        <Label Content="Label" Height="28" HorizontalAlignment="Left" Margin="79,78,0,0" 
               Name="label2" VerticalAlignment="Top" Drop="label2_Drop" AllowDrop="True" />
    </Grid>
</Window>

C# ---------------------------------------------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace WpfDragDrop
{
    /// <summary>
    /// MainWindow.xaml 的互動邏輯
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private Point startPoint;

        private void label1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            startPoint = e.GetPosition(null);
        }

        private void label1_PreviewMouseMove(object sender, MouseEventArgs e)
        {
            // Get the current mouse position
            Point mousePos = e.GetPosition(null);
            Vector diff = startPoint - mousePos;

            if (e.LeftButton == MouseButtonState.Pressed &&
                Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance &&
                Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance)
            {
                //// Get the dragged ListViewItem
                //ListView listView = sender as ListView;
                //ListViewItem listViewItem =
                //    FindAnchestor<ListViewItem>((DependencyObject)e.OriginalSource);

                //// Find the data behind the ListViewItem
                //object contact = (object)listView.ItemContainerGenerator.
                //    ItemFromContainer(listViewItem);

                // Initialize the drag & drop operation
                DataObject dragData = new DataObject(DataFormats.Text, label1.Content);
                DragDrop.DoDragDrop(label1, dragData, DragDropEffects.Move);
            }
        }

        private void label2_Drop(object sender, DragEventArgs e)
        {
            label2.Content = e.Data.GetData(DataFormats.Text);
        }

        private static T FindAnchestor<T>(DependencyObject current) where T : DependencyObject
        {
            do
            {
                if (current is T)
                {
                    return (T)current;
                }
                current = VisualTreeHelper.GetParent(current);
            }
            while (current != null);
            return null;
        }
    }
}