Friday, September 5, 2008

Drag and Drop Using Databound in WPF


data-bound drag-drop.xaml
*************************

Grid>
Grid.RowDefinitions>
RowDefinition Height="Auto" />
RowDefinition Height="*" />
/Grid.RowDefinitions>
Grid.ColumnDefinitions>
ColumnDefinition Width="*" />
ColumnDefinition Width="*" />
/Grid.ColumnDefinitions>
TextBlock Grid.ColumnSpan="2" TextWrapping="WrapWithOverflow">
Set the color.
LineBreak />
Set the color in Right Side.!
/TextBlock>
ListBox Grid.Row="1" Name="ListBox1" />
ListBox Grid.Row="1" Grid.Column="1" Name="ListBox2" />
/Grid>
/Window>






data-bound drag-drop.xaml.cs
***************************

using System;
using System.Collections.Generic;
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.Shapes;
using System.Collections.ObjectModel;

namespace Practice
{
///
/// Interaction logic for data_bound_drag_drop.xaml
///

public partial class data_bound_drag_drop : System.Windows.Window
{
private static DependencyProperty DraggingElementProperty = DependencyProperty.RegisterAttached("DraggingElement", typeof(string), typeof(Window), new FrameworkPropertyMetadata(null));
private static DependencyProperty IsDownProperty = DependencyProperty.RegisterAttached("IsDown", typeof(bool), typeof(Window), new FrameworkPropertyMetadata(false));
private static DependencyProperty StartPointProperty = DependencyProperty.RegisterAttached("StartPoint", typeof(Point), typeof(Window), new FrameworkPropertyMetadata(default(Point)));

public data_bound_drag_drop()
{
InitializeComponent();
}

private void Window_Loaded(object sender, RoutedEventArgs e)
{


ListBox1.ItemsSource = new ObservableCollection(new List(new string[] { "North", "Blue", "South", "East", "West", "Green", "Yellow", }));
ListBox2.ItemsSource = new ObservableCollection(new List(new string[] { "Red", }));

PrepareListBoxForDragDrop(ListBox1);
PrepareListBoxForDragDrop(ListBox2);
}

private void PrepareListBoxForDragDrop(ListBox listbox)
{
listbox.AllowDrop = true;
listbox.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(ListboxPreviewMouseLeftButtonDown);
listbox.PreviewMouseMove += new MouseEventHandler(ListboxPreviewMouseMove);
listbox.PreviewMouseLeftButtonUp += new MouseButtonEventHandler(ListboxPreviewMouseLeftButtonUp);
listbox.Drop += new DragEventHandler(ListboxDrop);
}

private void ListboxPreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
ListBox listbox = (ListBox)sender;
string s = GetBoundItemFromPoint(listbox, e.GetPosition(listbox));
if (s != null)
{
listbox.SetValue(IsDownProperty, true);
listbox.SetValue(DraggingElementProperty, s);
listbox.SetValue(StartPointProperty, e.GetPosition(listbox));
}
}

private string GetBoundItemFromPoint(ListBox box, Point point)
{
UIElement element = box.InputHitTest(point) as UIElement;
while (element != null)
{
if (element == box)
{
return null;
}
object item = box.ItemContainerGenerator.ItemFromContainer(element);
bool itemFound = !object.ReferenceEquals(item, DependencyProperty.UnsetValue);
if (itemFound)
{
return (string)item;
}
else
{
element = VisualTreeHelper.GetParent(element) as UIElement;
}
}
return null;
}

private void ListboxPreviewMouseMove(object sender, MouseEventArgs e)
{
ListBox listbox = (ListBox)sender;

bool isDown = (bool)listbox.GetValue(IsDownProperty);
if (!isDown)
{
return;
}

Point startPoint = (Point)listbox.GetValue(StartPointProperty);

if (Math.Abs(e.GetPosition(listbox).X - startPoint.X) > SystemParameters.MinimumHorizontalDragDistance ||
Math.Abs(e.GetPosition(listbox).Y - startPoint.Y) > SystemParameters.MinimumVerticalDragDistance)
{
DragStarted(listbox);
}
}

private void DragStarted(ListBox listbox)
{
listbox.ClearValue(IsDownProperty); // SetValue to false would also work.

// Add the bound item, available as DraggingElement, to a DataObject, however we see fit.
string draggingElement = (string)listbox.GetValue(DraggingElementProperty);
DataObject d = new DataObject(DataFormats.UnicodeText, draggingElement);
DragDropEffects effects = DragDrop.DoDragDrop(listbox, d, DragDropEffects.Copy | DragDropEffects.Move);
if ((effects & DragDropEffects.Move) != 0)
{
// Move rather than copy, so we should remove from bound list.
ObservableCollection collection = (ObservableCollection)listbox.ItemsSource;
collection.Remove(draggingElement);
}
}

private void ListboxDrop(object sender, DragEventArgs e)
{
ListBox listbox = (ListBox)sender;
ObservableCollection collection = (ObservableCollection)listbox.ItemsSource;
if (e.Data.GetDataPresent(DataFormats.UnicodeText, true))
{
collection.Add((string)e.Data.GetData(DataFormats.UnicodeText, true));
e.Effects =
((e.KeyStates & DragDropKeyStates.ControlKey) != 0) ?
DragDropEffects.Copy : DragDropEffects.Move;
e.Handled = true;
}
}

private void ListboxPreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
ListBox listbox = (ListBox)sender;
listbox.ClearValue(IsDownProperty);
listbox.ClearValue(DraggingElementProperty);
listbox.ClearValue(StartPointProperty);
}
}
}



No comments: