基于WPF實現(xiàn)ListBox拖動子項
更新時間:2024年04月02日 10:01:31 作者:WPF開發(fā)者
這篇文章主要為大家詳細介紹了如何基于WPF實現(xiàn)ListBox拖動子項效果,文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以參考下
WPF 實現(xiàn) ListBox 拖動子項
框架支持.NET4 至 .NET8
;
Visual Studio 2022
;
實現(xiàn)代碼
XAML 部分
1)新增 MainWindow.xaml
代碼如下:
Grid
定義兩列。- 第一列
ListBox
控件,命名ListBoxStart
,原數(shù)據(jù)被拖動者。 Canvas
畫布,用于在拖動過程中呈獻拖動項。- 第二列
ListBox
控件,命名ListBoxEnd
,用于接收拖動者。
<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>
,分別用于存儲ListBoxStart
和ListBoxEnd
中的項。ListBoxStart_PreviewMouseLeftButtonDown
方法處理當在ListBoxStart
按下鼠標左鍵時的Item
數(shù)據(jù),標記拖放操作的開始。FindVisualParent
在可視樹中查找元素。GetListBoxItemData
獲取選中項ListBoxItem
的數(shù)據(jù)。ListBoxStart_PreviewMouseLeftButtonUp
處理當在ListBoxStart
釋放鼠標左鍵的事件執(zhí)行實際的拖放操作。ListBoxStart_PreviewMouseMove
處理當在ListBoxStart
移動鼠標時的事件在拖動過程中更新拖動的位置。ListBoxEnd_Drop
處理當將ListBoxStart
拖動項放到ListBoxEnd
的事件,將拖動項添加到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實現(xiàn)ListBox拖動子項的文章就介紹到這了,更多相關(guān)WPF ListBox拖動子項內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
淺析C# 9.0 新特性之 Lambda 棄元參數(shù)
這篇文章主要介紹了C# 9.0 新特性之 Lambda 棄元參數(shù)的的相關(guān)資料,文中講解非常細致,代碼幫助大家更好的理解和學習,想學習c#的朋友可以了解下2020-06-06C#與js實現(xiàn)去除textbox文本框里面重復(fù)記錄的方法
這篇文章主要介紹了C#與js實現(xiàn)去除textbox文本框里面重復(fù)記錄的方法,很實用的功能,需要的朋友可以參考下2014-08-08