腾讯小企鹅 发表于 2023-8-3 20:58:59

Avalonia 列表拖拽替换

实现目标,在一个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(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.Index == -1)33             {34               continue;35             }36             if (position.Y >= itemsPoint.DistanceToTop && position.Y
页: [1]
查看完整版本: Avalonia 列表拖拽替换