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 ...
随机推荐
- DataX更换python3,File “datax.py“, line 114 print readerRef
datax 报错 File "datax.py", line 114 print readerRef 报错: File "datax.py", line 114 ...
- pgadmin数据输出不存在了?
菜单栏→文件→重置布局.这样数据输出就显示了.
- 2021-01-03:java中,描述一下什么情况下,对象会从年轻代进入老年代?
福哥答案2021-01-03: 1.对象的年龄超过一定阀值,-XX:MaxTenuringThreshold 可以指定该阀值.2.动态对象年龄判定,有的垃圾回收算法,比如 G1,并不要求 age 必须 ...
- 2021-01-29:redis同步机制是怎样的?
福哥答案2021-01-30: [答案1:](https://italk.mashibing.com/question/detail/ques_00006009)全量同步master服务器会开启一个后 ...
- 2021-02-16:n皇后问题。给定一个整数n,返回n皇后的摆法有多少种?
福哥答案2021-02-16: 自然智慧即可.1.普通递归.有代码.需要判断同列和斜线.2.位运算递归.有代码.3.我的递归.有代码.只需要判断斜线. 代码用golang编写,代码如下: packag ...
- 2021-05-21:给定一个数组arr,先递减然后递增,返回arr中有多少个绝对值不同的数字?
2021-05-21:给定一个数组arr,先递减然后递增,返回arr中有多少个绝对值不同的数字? 福大大 答案2021-05-21: 双指针.左指针最左,符合条件时右移:右指针最右,符合条件时左移.左 ...
- 2021-06-18:已知数组arr,生成一个数组out,out的每个元素必须大于等于1,当arr[cur]>arr[cur-1]时,out[cur]>out[cur-1];当arr[cur]>arr
2021-06-18:已知数组arr,生成一个数组out,out的每个元素必须大于等于1,当arr[cur]>arr[cur-1]时,out[cur]>out[cur-1]:当arr[cu ...
- GPT大语言模型Alpaca-lora本地化部署实践【大语言模型实践一】
模型介绍 Alpaca模型是斯坦福大学研发的LLM(Large Language Model,大语言)开源模型,是一个在52K指令上从LLaMA 7B(Meta公司开源的7B)模型微调而来,具有70亿 ...
- 【Python】爬虫下载视频
Python爬虫下载视频 前言 这两天我一时兴起想学习 PS ,于是去我的软件宝库中翻出陈年已久的 PhotoshopCS6 安装,结果发现很真流畅诶! 然后去搜索学习视频,网上的视频大多浮躁,收费, ...
- 如何在.net6webapi中配置Jwt实现鉴权验证
JWT(Json Web Token) jwt是一种用于身份验证的开放标准,他可以在网络之间传递信息,jwt由三部分组成:头部,载荷,签名.头部包含了令牌的类型和加密算法,载荷包含了用户的信息,签名则 ...