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<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 }
具体实现
最终效果:
初始画面

拖拽后:

Avalonia 列表拖拽替换的更多相关文章
- ListView列表拖拽排序
ListView列表拖拽排序能够參考Android源代码下的Music播放列表,他是能够拖拽的,源代码在[packages/apps/Music下的TouchInterceptor.java下]. 首 ...
- Android滑动列表(拖拽,左滑删除,右滑完成)功能实现(2)
ItemTouchHelper类 之前我们实现了滑动列表的一些基本功能,为了实现更多的效果,我们来仔细看一下ItemTouchHelper中的类: ItemTouchHelper.SimpleCall ...
- vue列表拖拽排序功能实现
1.实现目标:目标是输入一个数组,生成一个列表:通过拖拽排序,拖拽结束后输出一个经过排序的数组. 2.实现思路: 2.1是使用HTML5的drag功能来实现,每次拖拽时直接操作Dom节点排序,拖拽结束 ...
- dev gridview 单元格值拖拽替换
public class GridViewDropCell { //dvginfo根据鼠标点击的x.y坐标获取该点的相关信息 private GridHitInfo downHitInfo; priv ...
- Android滑动列表(拖拽,左滑删除,右滑完成)功能实现(1)
场景: 近期做的TODO APP需要在主页添加一个功能,就是可以左滑删除,右滑完成.看了一下当前其他人做的例如仿探探式的效果,核心功能基本一样,但是和我预想的还是有少量区别,于是干脆自己重头学一遍如何 ...
- vue列表拖拽组件 vue-dragging
安装 $ npm install awe-dnd --save 应用 在main.js中,通过Vue.use导入插件 import VueDND from 'awe-dnd' Vue.use(VueD ...
- jQuery图片列表拖拽排序布局
在线演示 本地下载
- Android高级控件(六)——自定义ListView高仿一个QQ可拖拽列表的实现
Android高级控件(六)--自定义ListView高仿一个QQ可拖拽列表的实现 我们做一些好友列表或者商品列表的时候,居多的需求可能就是需要列表拖拽了,而我们选择了ListView,也是因为使用L ...
- html5 Sortable.js 拖拽排序源码分析
最近公司项目经常用到一个拖拽 Sortable.js插件,所以有空的时候看了 Sortable.js 源码,总共1300多行这样,写的挺完美的. 本帖属于原创,转载请出名出处. 官网http:// ...
- sortable.js 拖拽排序及配置项说明
// 拖动排序 $(function() { /*排序*/ //排序 // Simple list ]; new Sortable(list, { group: "name", a ...
随机推荐
- flutter系列之:做一个修改组件属性的动画
目录 简介 flutter中的动画widget AnimatedContainers使用举例 总结 简介 什么是动画呢?动画实际上就是不同的图片连续起来形成的.flutter为我们提供了一个Anima ...
- 2020-10-30:给定一个正数数组arr(即数组元素全是正数),找出该数组中,两个元素相减的最大值,其中被减数的下标不小于减数的下标。即求出: maxValue = max{arr[j]-arr[i] and j >= i}?
福哥答案2020-10-30:1.双重遍历法.2.一次遍历法.golang代码如下: package main import "fmt" const INT_MAX = int(^ ...
- 2021-05-05:一个数组中只有两种字符‘G‘和‘B‘,可以让所有的G都放在左侧,所有的B都放在右侧。或者可以让所有的G都放在右侧,所有的B都放在左侧。但是只能在相邻字符之间进行交换操作。返回至少
2021-05-05:一个数组中只有两种字符'G'和'B',可以让所有的G都放在左侧,所有的B都放在右侧.或者可以让所有的G都放在右侧,所有的B都放在左侧.但是只能在相邻字符之间进行交换操作.返回至少 ...
- 2021-07-21:一张扑克有3个属性,每种属性有3种值(A、B、C),比如“AAA“,第一个属性值A,第二个属性值A,第三个属性值A,比如“BCA“,第一个属性值B,第二个属性值C,第三个属性值A
2021-07-21:一张扑克有3个属性,每种属性有3种值(A.B.C),比如"AAA",第一个属性值A,第二个属性值A,第三个属性值A,比如"BCA",第一个 ...
- Maven安装、阿里云镜像配置、Idea中创建Maven项目、Tomcat的部署
我为什么要学这个技术? 为了更快创建web开发项目和jar包 在javaweb开发中,需要使用大量的jar包,我们手动去导入: 如何能够让一个东西自动帮我导入和配置这个jar包 因此,Maven诞生了 ...
- Cesium开发案例整理
weigis近几年越来越被人们所关注,但是二三维开发难度也比普通web要高出许多,不管我们是在在开发或者是学习过程中,往往需要耗费大量的时间去查阅资料,和研究官方案例, 而大多二三维的包(openla ...
- qq飞车端游最全按键指法教学
目录 起步篇 超级起步 弹射起步 段位起步 基础篇 点飘 撞墙漂移 撞墙点喷 进阶篇 双喷 叠喷 断位漂移 段位双喷 侧身漂移 快速出弯 CW WCW CWW 牵引 甩尾点飘 甩尾漂移 右侧卡 左侧卡 ...
- 上下文管理者(ServletContext)
作用1.获取全局初始化参数2.资源共享(servlet通信) 能让上下文呢的Servlet相互关联起来3.获取资源文件 生命周期创建服务器启动的时候会为每个项目创建一个servletContext上下 ...
- 认识Dubbo与RPC
关注王有志,分享硬核Java技术的互金摸鱼侠 加入Java人的提桶跑路群:共同富裕的Java人 开个新坑,和大家一起学习Dubbo 3.X.我们按照一个由浅入深顺序来学习,先从使用Dubbo开始,再深 ...
- CDI的概念理解
1.CDI是什么?目的和作用是什么? 概念(是什么):是JavaEE 6标准中一个规范, 作用(干什么): 它提供了Java EE平台上服务注入的组件管理核心,简化应该是CDI的目标,让一切都可以被注 ...