WPF 通过拖拽改变Item的顺序 ItemsControl

2023-12-22 19:18

本文主要是介绍WPF 通过拖拽改变Item的顺序 ItemsControl,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

拖拽每个元素 移动位置 和点击前后移动位置  要求低一点就点击前后移动位置就够了

 

 

之前发过一篇 WPF,strackpanel 拖拽控件 改名,实际上是差不多的,随着对此深入理解可以更加的封装

https://blog.csdn.net/sinat_30224769/article/details/111668459?spm=1001.2014.3001.5501

git链接

https://github.com/442040292/ItemsControlDragSortDemo

 

基础代码重要

扩展方法

    internal static partial class ItemsControlDropSortExtendMethod{//根据子元素查找父元素public static T FindVisualParent<T>(DependencyObject obj) where T : class{while (obj != null){if (obj is T)return obj as T;obj = VisualTreeHelper.GetParent(obj);}return null;}public static bool GetDragItem(this MouseEventArgs e, object sender, out object data){data = null;var pos = e.GetPosition((IInputElement)sender);HitTestResult result = VisualTreeHelper.HitTest((Visual)sender, pos);if (result == null){return false;}var listBoxItem = ItemsControlDropSortExtendMethod.FindVisualParent<FrameworkElement>(result.VisualHit);if (listBoxItem == null){return false;}if (listBoxItem.DataContext == null){return false;}data = listBoxItem.DataContext;return true;}public static bool GetDropItem(this DragEventArgs e, object sender, out object from, out object to){from = null;to = null;var pos = e.GetPosition((IInputElement)sender);var result = VisualTreeHelper.HitTest((Visual)sender, pos);if (result == null){return false;}//查找元数据var sourcePerson = e.Data.GetData(e.Data.GetFormats()[0]);if (sourcePerson == null){return false;}//查找目标数据var listBoxItem = ItemsControlDropSortExtendMethod.FindVisualParent<FrameworkElement>(result.VisualHit);if (listBoxItem == null){return false;}from = sourcePerson;to = listBoxItem.DataContext;return true;}/// <summary>/// 移动列表元素 /// </summary>/// <typeparam name="T"></typeparam>/// <param name="itemSource"></param>/// <param name="fromObj"></param>/// <param name="toObj"></param>/// <param name="pre"></param>public static void ChangeIetmIndex<T>(this Collection<T> itemSource, object fromObj, object toObj, int pre){if (fromObj == null || toObj == null){return;}if (!(fromObj is T) || !(toObj is T)){return;}if (fromObj.Equals(toObj)){return;}var fromItem = (T)fromObj;var toItem = (T)toObj;itemSource.Remove(fromItem);int indexTo = itemSource.IndexOf(toItem);if (indexTo == 0 && pre == 0){itemSource.Insert(0, fromItem);}else if (indexTo == itemSource.Count - 1 && pre == 1){itemSource.Add(fromItem);}else{itemSource.Insert(indexTo + pre, fromItem);}}/// <summary>/// 移动列表元素/// </summary>/// <typeparam name="T"></typeparam>/// <param name="itemSource"></param>/// <param name="itemObj"></param>/// <param name="pre"></param>public static void ChangeIetmIndex<T>(this Collection<T> itemSource, object itemObj, int pre){if (itemObj == null){return;}if (!(itemObj is T)){return;}var item = (T)itemObj;int indexItem = itemSource.IndexOf(item);if (indexItem == 0 && pre == -1){//保持}else if (indexItem == itemSource.Count - 1 && pre == 1){//保持}else{itemSource.Remove(item);itemSource.Insert(indexItem + pre, item);}}}

 如何使用

界面部分

<Window x:Class="ItemsControlDragSortDemo.MainWindow"xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"xmlns:d="http://schemas.microsoft.com/expression/blend/2008"xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"xmlns:local="clr-namespace:ItemsControlDragSortDemo"xmlns:vm="clr-namespace:ItemsControlDragSortDemo"mc:Ignorable="d"Title="MainWindow" Height="450" Width="800"><Window.DataContext><vm:MainWindowViewModel  x:Name="MainWindowViewModel"/></Window.DataContext><Window.Resources><Style x:Key="GridMouseOverHighLightStyle" TargetType="{x:Type local:DragGrid}"><Setter Property="Background" Value="#01FFFFFF" /><Style.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter Property="Background" Value="#441AAA5E" /></Trigger><Trigger Property="IsDragMouseOver" Value="True"><Setter Property="Background" Value="#441AAA5E" /></Trigger></Style.Triggers></Style><Style x:Key="GridMouseOverHighLightStyle2" TargetType="{x:Type local:DragGrid}"><Setter Property="Background" Value="#01FFFFFF" /><Style.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter Property="Background" Value="#440000FF" /></Trigger><Trigger Property="IsDragMouseOver" Value="True"><Setter Property="Background" Value="#440000FF" /></Trigger></Style.Triggers></Style></Window.Resources><Grid><ItemsControl x:Name="LBoxSort"ItemsSource="{Binding YouItemSource}"AllowDrop="True"PreviewMouseMove="LBoxSort_OnPreviewMouseMove" ><!--Drop="LBoxSort_OnDrop"--><ItemsControl.ItemTemplate><DataTemplate><Grid Background="Red" Width="60" Height="30" Margin="10" ><TextBlock Text="{Binding Name}"/><Grid><Grid.ColumnDefinitions><ColumnDefinition/><ColumnDefinition/></Grid.ColumnDefinitions><local:DragGrid Style="{StaticResource GridMouseOverHighLightStyle}"  Drop="LBoxSort_Drop_Prev" MouseLeftButtonDown="LBoxSort_Move_Prev" /><local:DragGrid Style="{StaticResource GridMouseOverHighLightStyle2}" Drop="LBoxSort_Drop_Next" MouseLeftButtonDown="LBoxSort_Move_Next" Grid.Column="1"/></Grid></Grid></DataTemplate></ItemsControl.ItemTemplate><ItemsControl.ItemsPanel><ItemsPanelTemplate><WrapPanel /></ItemsPanelTemplate></ItemsControl.ItemsPanel></ItemsControl></Grid>
</Window>

界面cs 辅助

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;namespace ItemsControlDragSortDemo
{/// <summary>/// Interaction logic for MainWindow.xaml/// </summary>public partial class MainWindow : Window{public MainWindow(){InitializeComponent();}public MainWindowViewModel ViewModel { get => this.DataContext as MainWindowViewModel; }private void LBoxSort_OnPreviewMouseMove(object sender, MouseEventArgs e){if (e.LeftButton == MouseButtonState.Pressed){e.GetDragItem(sender, out object from);DragDrop.DoDragDrop(LBoxSort, from, DragDropEffects.Move);}}private void LBoxSort_Drop_Prev(object sender, DragEventArgs e){var success = e.GetDropItem(sender, out object from, out object to);if (success){ViewModel.ChangeIetmIndex(from, to, 0);}}private void LBoxSort_Drop_Next(object sender, DragEventArgs e){var success = e.GetDropItem(sender, out object from, out object to);if (success){ViewModel.ChangeIetmIndex(from, to, 1);}}private void LBoxSort_Move_Prev(object sender, MouseButtonEventArgs e){var control = sender as FrameworkElement;var dc = control.DataContext;ViewModel.ChangeIetmIndex(dc, -1);}private void LBoxSort_Move_Next(object sender, MouseButtonEventArgs e){var control = sender as FrameworkElement;var dc = control.DataContext;ViewModel.ChangeIetmIndex(dc, 1);}}
}

 

viewmodel 调用

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace ItemsControlDragSortDemo
{public class MainWindowViewModel : ViewModelBase{public MainWindowViewModel(){List<YouItemViewModel> list = new List<YouItemViewModel>();for (int i = 0; i < 10; i++){list.Add(new YouItemViewModel { Name = "" + i });}YouItemSource = new ObservableCollection<YouItemViewModel>(list);}private ObservableCollection<YouItemViewModel> _YouItemSource;public ObservableCollection<YouItemViewModel> YouItemSource { get => _YouItemSource; set => Set(ref _YouItemSource, value); }public class YouItemViewModel{public string Name { get; set; }}#region 拖拽移动顺序public void ChangeIetmIndex(object from, object to, int pre){YouItemSource.ChangeIetmIndex(from, to, pre);}public void ChangeIetmIndex(object item, int pre){YouItemSource.ChangeIetmIndex(item, pre);}#endregion}
}

viewmodel 基础类

 

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;namespace ItemsControlDragSortDemo
{public class ViewModelBase : NotifyPropertyBase{}public class NotifyPropertyBase : INotifyPropertyChanged{public event PropertyChangedEventHandler PropertyChanged;protected virtual bool Set<T>(ref T storage, T value, [CallerMemberName] string propertyName = null){if (object.Equals(storage, value)) return false;storage = value;this.OnPropertyChanged(propertyName);return true;}protected void OnPropertyChanged(string propertyName){this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));}}
}

另外拖拽的时候是没有mouseover效果的 所以 对Grid 做了一点调整 可以把这一段代码直接写在cs 也可以 重新搞个控件 我这里是重新搞控件继承了一下

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;namespace ItemsControlDragSortDemo
{public class DragGrid : Grid{public bool IsDragMouseOver{get { return (bool)GetValue(IsDragMouseOverProperty); }set { SetValue(IsDragMouseOverProperty, value); }}// Using a DependencyProperty as the backing store for IsDragMouseOver.  This enables animation, styling, binding, etc...public static readonly DependencyProperty IsDragMouseOverProperty =DependencyProperty.Register("IsDragMouseOver", typeof(bool), typeof(DragGrid), new PropertyMetadata(false));protected override void OnDragEnter(DragEventArgs e){base.OnDragEnter(e);IsDragMouseOver = true;}protected override void OnDragLeave(DragEventArgs e){base.OnDragLeave(e);IsDragMouseOver = false;}protected override void OnDragOver(DragEventArgs e){base.OnDragOver(e);IsDragMouseOver = true;}protected override void OnDrop(DragEventArgs e){base.OnDrop(e);IsDragMouseOver = false;}}
}

这样的话就能满足 拖拽每个元素 移动位置 和点击前后移动位置  要求低一点就点击前后移动位置就够了

 

这篇关于WPF 通过拖拽改变Item的顺序 ItemsControl的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/525155

相关文章

前端原生js实现拖拽排课效果实例

《前端原生js实现拖拽排课效果实例》:本文主要介绍如何实现一个简单的课程表拖拽功能,通过HTML、CSS和JavaScript的配合,我们实现了课程项的拖拽、放置和显示功能,文中通过实例代码介绍的... 目录1. 效果展示2. 效果分析2.1 关键点2.2 实现方法3. 代码实现3.1 html部分3.2

Python中顺序结构和循环结构示例代码

《Python中顺序结构和循环结构示例代码》:本文主要介绍Python中的条件语句和循环语句,条件语句用于根据条件执行不同的代码块,循环语句用于重复执行一段代码,文章还详细说明了range函数的使... 目录一、条件语句(1)条件语句的定义(2)条件语句的语法(a)单分支 if(b)双分支 if-else(

关于Spring @Bean 相同加载顺序不同结果不同的问题记录

《关于Spring@Bean相同加载顺序不同结果不同的问题记录》本文主要探讨了在Spring5.1.3.RELEASE版本下,当有两个全注解类定义相同类型的Bean时,由于加载顺序不同,最终生成的... 目录问题说明测试输出1测试输出2@Bean注解的BeanDefiChina编程nition加入时机总结问题说明

C++实现封装的顺序表的操作与实践

《C++实现封装的顺序表的操作与实践》在程序设计中,顺序表是一种常见的线性数据结构,通常用于存储具有固定顺序的元素,与链表不同,顺序表中的元素是连续存储的,因此访问速度较快,但插入和删除操作的效率可能... 目录一、顺序表的基本概念二、顺序表类的设计1. 顺序表类的成员变量2. 构造函数和析构函数三、顺序表

最好用的WPF加载动画功能

《最好用的WPF加载动画功能》当开发应用程序时,提供良好的用户体验(UX)是至关重要的,加载动画作为一种有效的沟通工具,它不仅能告知用户系统正在工作,还能够通过视觉上的吸引力来增强整体用户体验,本文给... 目录前言需求分析高级用法综合案例总结最后前言当开发应用程序时,提供良好的用户体验(UX)是至关重要

JAVA利用顺序表实现“杨辉三角”的思路及代码示例

《JAVA利用顺序表实现“杨辉三角”的思路及代码示例》杨辉三角形是中国古代数学的杰出研究成果之一,是我国北宋数学家贾宪于1050年首先发现并使用的,:本文主要介绍JAVA利用顺序表实现杨辉三角的思... 目录一:“杨辉三角”题目链接二:题解代码:三:题解思路:总结一:“杨辉三角”题目链接题目链接:点击这里

顺序表之创建,判满,插入,输出

文章目录 🍊自我介绍🍊创建一个空的顺序表,为结构体在堆区分配空间🍊插入数据🍊输出数据🍊判断顺序表是否满了,满了返回值1,否则返回0🍊main函数 你的点赞评论就是对博主最大的鼓励 当然喜欢的小伙伴可以:点赞+关注+评论+收藏(一键四连)哦~ 🍊自我介绍   Hello,大家好,我是小珑也要变强(也是小珑),我是易编程·终身成长社群的一名“创始团队·嘉宾”

web群集--nginx配置文件location匹配符的优先级顺序详解及验证

文章目录 前言优先级顺序优先级顺序(详解)1. 精确匹配(Exact Match)2. 正则表达式匹配(Regex Match)3. 前缀匹配(Prefix Match) 匹配规则的综合应用验证优先级 前言 location的作用 在 NGINX 中,location 指令用于定义如何处理特定的请求 URI。由于网站往往需要不同的处理方式来适应各种请求,NGINX 提供了多种匹

react笔记 8-18 事件 方法 定义方法 获取/改变数据 传值

1、定义方法并绑定 class News extends React.Component {constructor(props) {super(props)this.state = {msg:'home组件'}}run(){alert("我是一个run") //方法写在类中}render() {return (<div><h2>{this.state.msg}</h2><button onCli