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

相关文章

浅析Spring如何控制Bean的加载顺序

《浅析Spring如何控制Bean的加载顺序》在大多数情况下,我们不需要手动控制Bean的加载顺序,因为Spring的IoC容器足够智能,但在某些特殊场景下,这种隐式的依赖关系可能不存在,下面我们就来... 目录核心原则:依赖驱动加载手动控制 Bean 加载顺序的方法方法 1:使用@DependsOn(最直

在Linux中改变echo输出颜色的实现方法

《在Linux中改变echo输出颜色的实现方法》在Linux系统的命令行环境下,为了使输出信息更加清晰、突出,便于用户快速识别和区分不同类型的信息,常常需要改变echo命令的输出颜色,所以本文给大家介... 目python录在linux中改变echo输出颜色的方法技术背景实现步骤使用ANSI转义码使用tpu

Spring如何使用注解@DependsOn控制Bean加载顺序

《Spring如何使用注解@DependsOn控制Bean加载顺序》:本文主要介绍Spring如何使用注解@DependsOn控制Bean加载顺序,具有很好的参考价值,希望对大家有所帮助,如有错误... 目录1.javascript 前言2. 代码实现总结1. 前言默认情况下,Spring加载Bean的顺

Java中JSON格式反序列化为Map且保证存取顺序一致的问题

《Java中JSON格式反序列化为Map且保证存取顺序一致的问题》:本文主要介绍Java中JSON格式反序列化为Map且保证存取顺序一致的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未... 目录背景问题解决方法总结背景做项目涉及两个微服务之间传数据时,需要提供方将Map类型的数据序列化为co

使用WPF实现窗口抖动动画效果

《使用WPF实现窗口抖动动画效果》在用户界面设计中,适当的动画反馈可以提升用户体验,尤其是在错误提示、操作失败等场景下,窗口抖动作为一种常见且直观的视觉反馈方式,常用于提醒用户注意当前状态,本文将详细... 目录前言实现思路概述核心代码实现1、 获取目标窗口2、初始化基础位置值3、创建抖动动画4、动画完成后

MySQL中SQL的执行顺序详解

《MySQL中SQL的执行顺序详解》:本文主要介绍MySQL中SQL的执行顺序,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录mysql中SQL的执行顺序SQL执行顺序MySQL的执行顺序SELECT语句定义SELECT语句执行顺序总结MySQL中SQL的执行顺序

SpringBoot中配置文件的加载顺序解读

《SpringBoot中配置文件的加载顺序解读》:本文主要介绍SpringBoot中配置文件的加载顺序,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录SpringBoot配置文件的加载顺序1、命令⾏参数2、Java系统属性3、操作系统环境变量5、项目【外部】的ap

Spring Boot 配置文件之类型、加载顺序与最佳实践记录

《SpringBoot配置文件之类型、加载顺序与最佳实践记录》SpringBoot的配置文件是灵活且强大的工具,通过合理的配置管理,可以让应用开发和部署更加高效,无论是简单的属性配置,还是复杂... 目录Spring Boot 配置文件详解一、Spring Boot 配置文件类型1.1 applicatio

前端原生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(