Avalonia 列表拖拽替换

这篇具有很好参考价值的文章主要介绍了Avalonia 列表拖拽替换。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

实现目标,在一个ListBox中选择一个子项进行拖拽到另一个ListBox中,拖拽到某一子项区域进行替换

axaml代码

Avalonia 列表拖拽替换Avalonia 列表拖拽替换
 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
Avalonia 列表拖拽替换Avalonia 列表拖拽替换
<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添加指针移动事件

Avalonia 列表拖拽替换Avalonia 列表拖拽替换
 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); 

对应事件实现,其中需要获取到需要替换的项的下标,本处是通过定位进行计算

Avalonia 列表拖拽替换Avalonia 列表拖拽替换
 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     }
具体实现

对应的实体类

 1 public class ItemCoordinates
 2     {
 3         public int Index { get; }
 4         public double DistanceToTop { get; }
 5 
 6         public ItemCoordinates(int index, double distanceToTop)
 7         {
 8             Index = index;
 9             DistanceToTop = distanceToTop;
10         }
11     }

最终效果:

初始画面

Avalonia 列表拖拽替换

拖拽后:

Avalonia 列表拖拽替换

 文章来源地址https://www.toymoban.com/news/detail-623611.html

到了这里,关于Avalonia 列表拖拽替换的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 如何使用CSS实现一个拖拽排序效果?

    前端入门之旅:探索Web开发的奇妙世界 欢迎来到前端入门之旅!感兴趣的可以订阅本专栏哦!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发者,这里都将为你提供一个系统而又亲切的学习平台。在这个

    2024年02月11日
    浏览(47)
  • 认识环境变量和进程替换,实现一个简易的shell

    首先,在百度百科中,环境变量的解释是这样的: 环境变量(environment variables)一般是指在操作系统中用来指定操作系统运行环境的一些参数,如:临时文件夹位置和系统文件夹位置等。环境变量是在操作系统中一个具有特定名字的对象,它包含了一个或者多个应用程序所将

    2024年02月08日
    浏览(53)
  • 【工具】VUE 前端列表拖拽功能代码

    使用组件 yarn add sortablejs --save Sortable.js中文网 (sortablejs.com) 以下代码只是举个例子, 大家可以举一反三去实现各自的业务功能 DataList1.js DataList2.js

    2024年02月04日
    浏览(37)
  • 基于Element-ui 封装穿梭框(左侧树 右侧列表,可全选,列表可拖拽)

    Element-ui提供的穿梭框只支持列表,根据实际需求自己写了一个左边是树结构,右边是列表结构的穿梭框,(如果需要两边都是树结构的话,需要把右侧的逻辑参考左侧改一改)拖拽使用了 vuedraggable 插件

    2024年02月11日
    浏览(58)
  • CSS实现一个交互感不错的卡片列表

    横向滚动 鼠标悬停时突出显示 默认堆叠展示 鼠标悬停时,完整展示当前块+适当旋出效果 移动端样式优化、磁吸效果 美化滚动条 flex 布局 css 简单变换+过渡 transform、transition 渐变色函数 linear-gradient … 伪类、伪元素 滚动条、::after、 ::before …

    2024年02月11日
    浏览(41)
  • Java--ListUtil工具类,实现将一个大列表,拆分成指定长度的子列表

    前言 在项目中有时会出现列表很大,无法一次性批量操作,我们需要将列表分成指定大小的几个子列表,一份一份进行操作,本文提供这样的工具类实现这个需求。 实现代码 以下为ListUtil工具类代码实现: 执行结果 在上述类里写个main方法用以测试结果。 执行main方法,得到

    2024年02月01日
    浏览(85)
  • [MAUI]在.NET MAUI中实现可拖拽排序列表

    .NET MAUI 中提供了拖放(drag-drop)手势识别器,允许用户通过拖动手势来移动控件。在这篇文章中,我们将学习如何使用拖放手势识别器来实现可拖拽排序列表。在本例中,列表中显示不同大小的磁贴(Tile)并且可以拖拽排序。 使用.NET MAU实现跨平台支持,本项目可运行于Andro

    2024年02月12日
    浏览(50)
  • react-sortable-hoc 拖拽列表上oncick事件失效

    问题:onClick 无效 解决:添加distance

    2024年02月11日
    浏览(31)
  • Unity实现一个可扩展的UGUI无限滑动列表控件

    12月20日新增 增加一个可收缩的滑动列表,适用于游戏中的任务系统,成就等 使用说明 创建时需要两个模板slot,一个是button,另一个则是btn下显示的cell 配置如下图添加 ExpandableView 脚本,新增的IsDefaultExpand用来控制是否展开 11月28日新增 增加可调节的顶部间隙和左侧间隙 采

    2024年01月19日
    浏览(42)
  • 如何在 Android 应用中使用 RecyclerView 实现一个列表显示,并实现点击事件?

    首先,需要在项目的 build.gradle 文件中添加 RecyclerView 的依赖: 接下来,在布局文件中添加 RecyclerView: 接着,需要创建一个 Adapter 类,用于将数据绑定到 RecyclerView 上,如下所示: 在 onBindViewHolder() 方法中,我们可以将数据绑定到 ViewHolder 中的视图上。 需要注意的是,在 V

    2024年02月05日
    浏览(52)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包