實現目標,在一個ListBox中選擇一個子項進行拖拽到另一個ListBox中,拖拽到某一子項區域進行替換 axaml代碼 1 <ListBox 2 Name="consumableListBox" 3 Margin="5" 4 ItemsSource="{Binding ConsumableList ...
實現目標,在一個ListBox中選擇一個子項進行拖拽到另一個ListBox中,拖拽到某一子項區域進行替換
axaml代碼

1 <ListBox 2 Name="consumableListBox" 3 Margin="5" 4 ItemsSource="{Binding ConsumableList}" 5 SelectionMode="Single"> 6 <ListBox.ItemTemplate> 7 <DataTemplate> 8 <StackPanel Margin="5,5,5,0"> 9 <Border 10 Width="160" 11 Height="100" 12 Margin="0,0,0,5" 13 HorizontalAlignment="Center" 14 Background="Red" 15 CornerRadius="5" /> 16 <TextBlock HorizontalAlignment="Center" Text="{Binding}" /> 17 </StackPanel> 18 </DataTemplate> 19 </ListBox.ItemTemplate> 20 </ListBox>源ListBox

<ListBox Name="platePositionListBox" Margin="5" ItemsSource="{Binding PlatePositionList}" SelectionMode="Single"> <ListBox.ItemTemplate> <DataTemplate> <StackPanel Margin="5,5,5,0"> <Border Width="160" Height="100" Margin="0,0,0,5" HorizontalAlignment="Center" Background="Red" CornerRadius="5" /> <TextBlock HorizontalAlignment="Center" Text="{Binding}" /> </StackPanel> </DataTemplate> </ListBox.ItemTemplate> </ListBox>目標ListBox
給源ListBox添加指針移動事件

1 private void SourceList_PointerMoved(object sender, PointerEventArgs e) 2 { 3 // 當拖拽操作開始時,在源列表中開始拖拽 4 if (e.GetCurrentPoint(consumableListBox).Properties.IsLeftButtonPressed) 5 { 6 DataObject dataObject = new DataObject(); 7 dataObject.Set("dataObject", consumableListBox.SelectedItem); 8 DragDrop.DoDragDrop(e, dataObject, DragDropEffects.Move); 9 } 10 }源ListBox指針移動
將目標ListBox設為允許拖入
DragDrop.SetAllowDrop(platePositionListBox, true);
由於ListBox沒有DropEvent事件,需要進行添加事件
platePositionListBox.AddHandler(DragDrop.DropEvent, PlatePositionListBox_DropEvent, RoutingStrategies.Bubble | RoutingStrategies.Direct);
對應事件實現,其中需要獲取到需要替換的項的下標,本處是通過定位進行計算

1 private void PlatePositionListBox_DropEvent(object? sender, DragEventArgs e) 2 { 3 var a = e.Data.Get("dataObject"); 4 if (e.Data.Contains("dataObject") && a != null) 5 { 6 var targetIndex = GetDropTargetIndex(platePositionListBox, e.GetPosition(platePositionListBox)); 7 if (targetIndex >= 0) 8 { 9 if (this.DataContext is PlanViewModel viewModel) 10 { 11 viewModel.PlatePositionList.RemoveAt(targetIndex); 12 viewModel.PlatePositionList.Insert(targetIndex, a.ToString()); 13 } 14 } 15 } 16 } 17 18 19 //獲取目標項下標 20 private int GetDropTargetIndex(ListBox targetListBox, Avalonia.Point position) 21 { 22 var itemsControl = targetListBox; 23 24 var itemsPoint = GetAllItemDistances(targetListBox); 25 var firstItemPanel = (StackPanel)Avalonia.VisualTree.VisualExtensions.FindDescendantOfType<StackPanel>(itemsControl); 26 var itemContainer = (Control)firstItemPanel; 27 var firstItemBounds = itemContainer.Bounds; 28 var items = itemsControl.Items; 29 var y = firstItemBounds.Y; 30 for (int i = 0; i < items.Count; i++) 31 { 32 if (itemsPoint[i].Index == -1) 33 { 34 continue; 35 } 36 if (position.Y >= itemsPoint[i].DistanceToTop && position.Y <= itemsPoint[i].DistanceToTop + firstItemBounds.Height) 37 { 38 return i; 39 } 40 } 41 return items.Count; 42 } 43 44 //獲取目標ListBox的項距離頂部邊框的距離,如果未呈現到畫面上,下標設為-1 45 private List<ItemCoordinates> GetAllItemDistances(ListBox listBox) 46 { 47 var itemCoordinatesList = new List<ItemCoordinates>(); 48 var items = listBox.Items; 49 var scrollViewer = listBox.FindDescendantOfType<ScrollViewer>(); 50 var topOffset = scrollViewer.Offset.Y; 51 52 for (int i = 0; i < items.Count; i++) 53 { 54 var itemContainer = listBox.ItemContainerGenerator.ContainerFromIndex(i) as Control; 55 if (itemContainer != null) 56 { 57 var itemBounds = itemContainer.Bounds; 58 var distanceToTop = itemBounds.Top - topOffset; 59 itemCoordinatesList.Add(new ItemCoordinates(i, distanceToTop)); 60 } 61 else 62 { 63 itemCoordinatesList.Add(new ItemCoordinates(-1, -999)); 64 } 65 } 66 return itemCoordinatesList; 67 }具體實現
最終效果:
初始畫面
拖拽後:
本文來自博客園,作者:阿金啊,轉載請註明原文鏈接:https://www.cnblogs.com/fengxinyuan/p/17604442.html