원문 : Drag And Drop Item in ListBox in WPF








Drag And Drop Item in ListBox in WPF




아래와 같이 두개의 ListBox 를 배치한다.



<Window x:Class="DragDropListBoxSample.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Drag And Drop ListBox Item" Height="300" Width="529">
    <Grid>
        <ListBox x:Name="lbOne" PreviewMouseLeftButtonDown="ListBox_PreviewMouseLeftButtonDown"
                 HorizontalAlignment="Left" Margin="12,29,0,12" Width="215"
                 ScrollViewer.VerticalScrollBarVisibility="Visible" />
        <ListBox x:Name="lbTwo" Drop="ListBox_Drop" AllowDrop="True"
                 HorizontalAlignment="Right" Margin="0,29,12,12" Width="215"
                 ScrollViewer.VerticalScrollBarVisibility="Visible"/>
        <TextBlock Height="21" Text="ListBox One" HorizontalAlignment="Left"
                   Margin="12,2,0,0" VerticalAlignment="Top" Width="120" />
        <TextBlock Height="21" Text="ListBox Two" HorizontalAlignment="Right"
                   Margin="0,2,107,0" VerticalAlignment="Top" Width="120" />
    </Grid>
</Window>


DragDrop 을 구현하기 위해 데이터를 Drag 할 ListBox 에서는 PreviewMouseLeftButtonDown 이벤트 핸들러를 정의해 주어야 한다. Drop 할 목적지 ListBox 에서는 AllowDrop 프로퍼티를 True 로 설정하고, Drop 이벤트 핸들러를 정의해주어야 한다.

PreviewMouseLeftButtonDown
마우스 포인터가 ListBox 위에 있을 때 마우스 왼쪽 버튼을 클릭하면 발생하는 이벤트

AllowDrop
이 요소를 끌어서 놓기 작업의 대상으로 사용할 수 있는지 여부를 나타내는 값을 가져오거나 설정.
기본값은 false 이다.

Drop
해당 요소에(ListBox) 아이템을 끌어다 놓았을 때 발생하는 이벤트


첫 번째 ListBox 에 테스트할 데이터를 넣는다. TimeZoneInfo 클래스로 부터 TimeZones 리스트를 넣어 준다.
public Window1()
{
    InitializeComponent();

    foreach (TimeZoneInfo tzi in TimeZoneInfo.GetSystemTimeZones())
    {
         zoneList.Add(tzi.ToString());
    }
    lbxOne.ItemsSource = zoneList;
}





PreviewMouseLeftButtonDown 이벤트 핸들러 구현 코드는 다음과 같다. GetDataFromListBox 메소드를 눈여겨 보자

ListBox
dragSource = null;

private void ListBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    ListBox parent = (ListBox)sender;
    dragSource = parent;
    object data = GetDataFromListBox(dragSource, e.GetPosition(parent));
 
    if (data != null)
    {
        DragDrop.DoDragDrop(parent, data, DragDropEffects.Move);
    }
}
#region GetDataFromListBox(ListBox,Point)
        private static object GetDataFromListBox(ListBox source, Point point)
        {
            UIElement element = source.InputHitTest(point) as UIElement;
            if (element != null)
            {
                object data = DependencyProperty.UnsetValue;
                while (data == DependencyProperty.UnsetValue)
                {
                    data = source.ItemContainerGenerator.ItemFromContainer(element);

                    if (data == DependencyProperty.UnsetValue)
                    {
                        element = VisualTreeHelper.GetParent(element) as UIElement;
                    }

                    if (element == source)
                    {
                        return null;
                    }
                }

                if (data != DependencyProperty.UnsetValue)
                {
                    return data;
                }
            }

            return null;
        }
       
#endregion



목적지 ListBox 의 Drop 이벤트 핸들러 구현 코드는 다음과 같다.

private void ListBox_Drop(object sender, DragEventArgs e)
{
     ListBox parent = (ListBox)sender;
     object data = e.Data.GetData(typeof(string));
     ((IList)dragSource.ItemsSource).Remove(data);
     parent.Items.Add(data);
 }



예제 소스


Posted by six605
,