基于WPF實(shí)現(xiàn)ListBox拖動(dòng)子項(xiàng)
WPF 實(shí)現(xiàn) ListBox 拖動(dòng)子項(xiàng)
框架支持.NET4 至 .NET8;
Visual Studio 2022;

實(shí)現(xiàn)代碼
XAML 部分
1)新增 MainWindow.xaml 代碼如下:
Grid定義兩列。- 第一列
ListBox控件,命名ListBoxStart,原數(shù)據(jù)被拖動(dòng)者。 Canvas畫布,用于在拖動(dòng)過程中呈獻(xiàn)拖動(dòng)項(xiàng)。- 第二列
ListBox控件,命名ListBoxEnd,用于接收拖動(dòng)者。
<wd:Window
x:Class="WPFListBoxItemDrag.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WPFListBoxItemDrag"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers"
Title="WPF開發(fā)者 - ListBoxItemDrag"
Width="800"
Height="450"
WindowStartupLocation="CenterScreen"
mc:Ignorable="d">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<ListBox
x:Name="ListBoxStart"
AllowDrop="True"
BorderThickness="1"
ItemsSource="{Binding ItemsA}"
PreviewMouseLeftButtonDown="ListBoxStart_PreviewMouseLeftButtonDown"
PreviewMouseLeftButtonUp="ListBoxStart_PreviewMouseLeftButtonUp"
PreviewMouseMove="ListBoxStart_PreviewMouseMove" />
<Canvas
x:Name="DragCanvas"
Grid.ColumnSpan="2"
Panel.ZIndex="1000" />
<ListBox
x:Name="ListBoxEnd"
Grid.Column="1"
AllowDrop="True"
Drop="ListBoxEnd_Drop"
ItemsSource="{Binding ItemsB}" />
</Grid>
</wd:Window>
CSharp 部分
2)新增 MainWindow.xaml.cs 代碼如下:
ItemsA和ItemsB是ObservableCollection<string>,分別用于存儲(chǔ)ListBoxStart和ListBoxEnd中的項(xiàng)。ListBoxStart_PreviewMouseLeftButtonDown方法處理當(dāng)在ListBoxStart按下鼠標(biāo)左鍵時(shí)的Item數(shù)據(jù),標(biāo)記拖放操作的開始。FindVisualParent在可視樹中查找元素。GetListBoxItemData獲取選中項(xiàng)ListBoxItem的數(shù)據(jù)。ListBoxStart_PreviewMouseLeftButtonUp處理當(dāng)在ListBoxStart釋放鼠標(biāo)左鍵的事件執(zhí)行實(shí)際的拖放操作。ListBoxStart_PreviewMouseMove處理當(dāng)在ListBoxStart移動(dòng)鼠標(biāo)時(shí)的事件在拖動(dòng)過程中更新拖動(dòng)的位置。ListBoxEnd_Drop處理當(dāng)將ListBoxStart拖動(dòng)項(xiàng)放到ListBoxEnd的事件,將拖動(dòng)項(xiàng)添加到ListBoxEnd的數(shù)據(jù)源中。
using System.Collections.ObjectModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
namespace WPFListBoxItemDrag
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow
{
private bool isDragging;
private ListBoxItem item;
private ListBoxItem dragItem;
private object data;
public ObservableCollection<string> ItemsA { get; set; }
public ObservableCollection<string> ItemsB { get; set; }
public MainWindow()
{
InitializeComponent();
DataContext = this;
ItemsA = new() { "WPFDevelopersOrg", "WPFDevelopers", "WPF開發(fā)者", "ListBox", "ListBoxItem" };
ItemsB = new ObservableCollection<string>();
}
private void ListBoxStart_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
data = GetListBoxItemData(ListBoxStart, e.GetPosition(ListBoxStart));
item = FindVisualParent<ListBoxItem>((DependencyObject)e.OriginalSource);
if (item != null)
isDragging = true;
}
private T FindVisualParent<T>(DependencyObject obj) where T : DependencyObject
{
while (obj != null)
{
if (obj is T)
return (T)obj;
obj = VisualTreeHelper.GetParent(obj);
}
return null;
}
private object GetListBoxItemData(ListBox source, Point point)
{
var element = source.InputHitTest(point) as UIElement;
if (element != null)
{
var 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;
}
private void ListBoxStart_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
if (data != null)
DragDrop.DoDragDrop(ListBoxStart, data, DragDropEffects.Move);
isDragging = false;
if (dragItem != null)
{
DragCanvas.Children.Remove(dragItem);
dragItem = null;
}
}
private void ListBoxStart_PreviewMouseMove(object sender, MouseEventArgs e)
{
if (isDragging)
{
if (dragItem == null)
{
dragItem = new ListBoxItem
{
Content = item.Content,
Width = item.ActualWidth,
Height = item.ActualHeight,
Background = Brushes.Gray,
ContentTemplate = item.ContentTemplate,
ContentTemplateSelector = item.ContentTemplateSelector,
Style = item.Style,
Padding = item.Padding,
Opacity = .5,
IsHitTestVisible = false,
};
DragCanvas.Children.Add(dragItem);
}
var mousePos = e.GetPosition(DragCanvas);
Canvas.SetLeft(dragItem, mousePos.X - dragItem.ActualWidth / 2);
Canvas.SetTop(dragItem, mousePos.Y - dragItem.ActualHeight / 2);
}
}
private void ListBoxEnd_Drop(object sender, DragEventArgs e)
{
if (e.Data.GetDataPresent(typeof(string)))
{
var data = e.Data.GetData(typeof(string)).ToString();
ItemsB.Add(data);
ItemsA.Remove(data.ToString());
}
}
}
}效果圖

到此這篇關(guān)于基于WPF實(shí)現(xiàn)ListBox拖動(dòng)子項(xiàng)的文章就介紹到這了,更多相關(guān)WPF ListBox拖動(dòng)子項(xiàng)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
在Framework 4.0中:找出新增的方法與新增的類(二)
為什么動(dòng)態(tài)加載程序集無法找出Framework 4.0 和Framwork2.0 新增的方法和類2013-05-05
C# 實(shí)現(xiàn)WebSocket服務(wù)端教程
這篇文章主要介紹了C# 實(shí)現(xiàn)WebSocket服務(wù)端教程,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-10-10
在Winform和WPF中注冊(cè)全局快捷鍵實(shí)現(xiàn)思路及代碼
如果注冊(cè)快捷鍵,RegisterHotKey中的fsModifiers參數(shù)為0,即None選項(xiàng),一些安全軟件會(huì)警報(bào),可能因?yàn)檫@樣就可以全局監(jiān)聽鍵盤而造成安全問題,感興趣的你可以參考下本文2013-02-02
C#動(dòng)態(tài)創(chuàng)建button按鈕的方法實(shí)例詳解
這篇文章主要介紹了C#動(dòng)態(tài)創(chuàng)建button按鈕的方法實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-06-06
c#判斷代碼是否執(zhí)行超時(shí)的幾種方式總結(jié)
這篇文章主要介紹了c#判斷代碼是否執(zhí)行超時(shí)的幾種方式總結(jié),具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01
C#調(diào)用海康工業(yè)相機(jī)SDK采集圖像并在Halcon窗口中顯示方式
這篇文章主要介紹了C#調(diào)用??倒I(yè)相機(jī)SDK采集圖像并在Halcon窗口中顯示方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-02-02

