Перетаскивание элемента в список ListBox в WPF
Автор: Диптимая Патра (Diptimaya Patra)
В этой статье будет показано, как обеспечить поведение перетаскивания для значения ListBox.
Создание проекта WPF
Запустите Visual Studio 2008 и создайте новый проект WPF. Назовите его DragDropListBoxSample.
.gif)
Основная идея нашего приложения-примера — использование двух списков ListBox и перетаскивание элемента из первого списка ListBox во второй список ListBox.
Поэтому создадим два списка ListBox и назовем эти списки ListBox как lbOne и lbTwo.
Ниже приведен принципиальный макет внешнего вида приложения.
.gif)
Здесь мы заполним первый список ListBox. Список часовых поясов из класса TimeZoneInfo.
ObservableCollection<string> zoneList = new ObservableCollection<string>();
public Window1()
{
InitializeComponent();
foreach (TimeZoneInfo tzi in TimeZoneInfo.GetSystemTimeZones())
{
zoneList.Add(tzi.ToString());
}
lbOne.ItemsSource = zoneList;
}
.gif)
Как видно, первый список Listbox заполнен всеми часовыми поясами.
Теперь, чтобы реализовать перетаскивание, нужно установить AllowDrop="True" для конечного списка ListBox, нам также понадобится события для списков ListBox: событие PreviewMouseLeftButtonDown для списка-источника и событие Drop для списка-получателя.
Соответствующие события и свойства приведены в следующем XAML-коде.
<Window x:Class="DragDropListBoxSample.Window1"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://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>
Теперь введем код обработчика событий ListBox_PreviewMouseLeftButtonDown.
ListBox dragSource = null;
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);
}
Теперь запустим приложение и перетащим приложение из первого списка ListBox во второй список ListBox. Функциональная возможность перетаскивания реализована.
.gif)
Надеюсь, что эта статья окажется полезной.