DataGrid 拖动 附加属性类
项目需要实现一个DataGrid拖动排序,于是参考网上一些资源然后,修改了下实现了一个附加属性类,如下
使用方法
<DataGrid
x:Name="shareGrid"
test:DragDropRowBehavior.Enabled="True"
test:DragDropRowBehavior.DropFinish="{Binding TestCommand}" />
DropFinish有在鼠标释放时调用,参数中包含了 拖动的数据,行号,目标行号,目标数据等。
源码:
public static class DataGridDragDropRowBehavior
{
public delegate Point GetDragDropPosition(IInputElement theElement); public static DependencyProperty DropFinishProperty =
DependencyProperty.RegisterAttached("DropFinish", typeof(ICommand), typeof(DataGridDragDropRowBehavior),
new UIPropertyMetadata(null)); public static void SetDropFinish(UIElement target, ICommand value)
{
target.SetValue(DropFinishProperty, value);
} public static bool GetEnabled(DependencyObject obj)
{
return (bool)obj.GetValue(EnabledProperty);
} public static void SetEnabled(DependencyObject obj, bool value)
{
obj.SetValue(EnabledProperty, value);
} public static readonly DependencyProperty EnabledProperty =
DependencyProperty.RegisterAttached("Enabled", typeof(bool), typeof(DataGridDragDropRowBehavior), new PropertyMetadata(false, OnEnableChanged)); private static void OnEnableChanged(DependencyObject depObject, DependencyPropertyChangedEventArgs e)
{
var dataGrid = depObject as DataGrid; var enable = (bool)e.NewValue;
if (enable)
{
dataGrid.AllowDrop = true;
dataGrid.PreviewMouseLeftButtonDown += DataGrid_PreviewMouseLeftButtonDown;
dataGrid.Drop += DataGrid_Drop;
}
else
{
dataGrid.PreviewMouseLeftButtonDown -= DataGrid_PreviewMouseLeftButtonDown;
dataGrid.Drop -= DataGrid_Drop;
}
} private static void DataGrid_Drop(object sender, DragEventArgs e)
{
DragItem dragitem = e.Data.GetData("DragItem") as DragItem; if (dragitem.RowIndex < )
{
return;
}
DataGrid datagrid = sender as DataGrid;
int index = GetDataGridItemCurrentRowIndex(e.GetPosition, datagrid); //The current Rowindex is -1 (No selected)
if (index < )
{
return;
}
//If Drag-Drop Location are same
if (index == dragitem.RowIndex)
{
return;
} var targetItem = datagrid.Items[index]; DropEventArgs arg = new DropEventArgs();
arg.SourceRowIndex = dragitem.RowIndex;
arg.TargetRowIndex = index;
arg.Data = dragitem.Data;
arg.TargetData = targetItem; var command = (ICommand)datagrid.GetValue(DropFinishProperty);
if (command != null)
{
command.Execute(arg);
}
} private static void DataGrid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
DataGrid datagrid = sender as DataGrid;
var m_prevRowIndex = GetDataGridItemCurrentRowIndex(e.GetPosition, datagrid); if (m_prevRowIndex < )
{
return;
}
datagrid.SelectedIndex = m_prevRowIndex; var selectedItem = datagrid.Items[m_prevRowIndex]; if (selectedItem == null)
{
return;
} DragItem dragItem = new DragItem();
dragItem.RowIndex = m_prevRowIndex;
dragItem.Data = selectedItem;
DataObject data = new DataObject("DragItem", dragItem);
//Now Create a Drag Rectangle with Mouse Drag-Effect
//Here you can select the Effect as per your choice DragDropEffects dragdropeffects = DragDropEffects.Move; if (DragDrop.DoDragDrop(datagrid, data, dragdropeffects) != DragDropEffects.None)
{
//Now This Item will be dropped at new location and so the new Selected Item
datagrid.SelectedItem = selectedItem;
}
} /// <summary>
/// Method checks whether the mouse is on the required Target
/// Input Parameter (1) "Visual" -> Used to provide Rendering support to WPF
/// Input Paraneter (2) "User Defined Delegate" positioning for Operation
/// </summary>
/// <param name="theTarget"></param>
/// <param name="pos"></param>
/// <returns>The "Rect" Information for specific Position</returns>
private static bool IsTheMouseOnTargetRow(Visual theTarget, GetDragDropPosition pos)
{
Rect posBounds = VisualTreeHelper.GetDescendantBounds(theTarget);
Point theMousePos = pos((IInputElement)theTarget);
return posBounds.Contains(theMousePos);
} private static DataGridRow GetDataGridRowItem(DataGrid dataGrid, int index)
{
if (dataGrid.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
{
return null;
}
return dataGrid.ItemContainerGenerator.ContainerFromIndex(index)
as DataGridRow;
} private static int GetDataGridItemCurrentRowIndex(GetDragDropPosition pos, DataGrid dataGrid)
{
int curIndex = -;
for (int i = ; i < dataGrid.Items.Count; i++)
{
DataGridRow itm = GetDataGridRowItem(dataGrid, i);
if (IsTheMouseOnTargetRow(itm, pos))
{
curIndex = i;
break;
}
}
return curIndex;
}
} public class DragItem
{
public int RowIndex { get; set; }
public object Data { get; set; }
} public class DropEventArgs
{
public int SourceRowIndex { get; set; }
public object Data { get; set; } public int TargetRowIndex { get; set; } public object TargetData { get; set; }
}
参考资源:http://www.dotnetcurry.com/wpf/677/wpf-data-grid-row-drag-drop
DataGrid 拖动 附加属性类的更多相关文章
- silverlight datagrid绑定匿名类
原文 http://www.cnblogs.com/luweis/archive/2011/10/21/2220587.html 刚开始遇到的一个问题是这样的,我有一个datagrid,根据不同的条件 ...
- datagrid拖动列头更换排列顺序
在做这个功能的时候在网上找了大量资料,发现都不适用,要不然就是代码太冗余,所以另起炉灶,自己封装了这个函数 下面是完整的代码: <!DOCTYPE html> <html> & ...
- 控制EasyUI DataGrid高度
这次要说的是控制EasyUI的高度,平时我公司的项目,用EasyUI较多,然后datagrid这个组件是用的非常多的.平时我们都是固定高度,常见代码如下: <table ...
- VS2015中的项目类图
发现右键项目的时候,是没有类图的. https://msdn.microsoft.com/en-us/library/hyxd8c85.aspx 右键项目--添加--新建项. 选择类图. 然后将整个项 ...
- Flutter进阶—点击、拖动和其他手势
Flutter中的手势系统有两个层次.第一层具有原始指针事件,其描述了穿过屏幕的指针(例如触摸.鼠标和触控笔)的位置和移动.第二层具有手势,其描述由一个或多个指针移动组成的语义动作. 指针指针代表用户 ...
- Windows Community Toolkit 4.0 - DataGrid - Part03
概述 在上面一篇 Windows Community Toolkit 4.0 - DataGrid - Part02 中,我们针对 DataGrid 控件的 Utilities 部分做了详细分享.而在 ...
- C# WinForm开发系列 - DataGrid/DataGridView
在WinForm开发中,DataGrid/DataGridView被广泛使用于绑定数据库中数据进行呈现.整理一些关于DataGrid/DataGridView使用的文章,涉及DataGrid/Data ...
- easyui datagrid列拖拽
<script type="text/javascript"> var cols = [{ field: 'testName', title: '<span cl ...
- Easyui datagrid自定义排序
做项目遇到个关于排序问题,想着在前端排序,正好Easyui有这个功能,所以就拿来用了一下,因为跟官网的Demo不太一样,所以总结一下: 首先这一列是要排序的列(当然,在生产环境,这一列是隐藏的,在开发 ...
随机推荐
- Android-第三天
今天开始做一个提交的页面,本来是用LinearLayout,但是这种布局要使用到多组LinearLayout,于是采用表格布局+相对布局的方式. <TableLayout> <Tab ...
- JVM之对象的创建简要流程
- 2017-06-19 (cp mkdir rm 运行级别及修改)
mkdir 用于创建目录 mkdir -p 递归创建目录 mkdir -p /linux/linux rm 用于删除文件与目录 rm -r 删除目录 -f 强制删除 (一般情况下 rf 组 ...
- HX711初步处理记录
参考文档为极客工坊大神记录 http://www.geek-workshop.com/forum.php?mod=viewthread&tid=2315&highlight=hx711 ...
- javaweb后台转码
为什么需要转码? 客户端向服务器发送请求的四种情况:1.URL方式直接访问;2.页面链接(属于get请求);3.表单get提交;4.表单post提交 1.url(url和页面链接):各大浏览器.各个操 ...
- Java多线程之线程的通信
Java多线程之线程的通信 在总结多线程通信前先介绍一个概念:锁池.线程因为未拿到锁标记而发生的阻塞不同于前面五个基本状态中的阻塞,称为锁池.每个对象都有自己的锁池的空间,用于放置等待运行的线程.这些 ...
- CSS中设置border:none和border:0的区别
在我们设置CSS的时候,对标签元素不设置边框属性或者取消边框属性一般设置为:border:none;或border:0;两种方法均可. border:none;与border:0;的区别体现有两点:一 ...
- DNS服务器解析域名的过程
最近在读许令波老师的<深入分析Java Web技术内幕>,算是对DNS服务器域名解析有个大体的理解,以下的内容来自个人对书中内容的整理 1.什么是域名解析? 当我们在浏览器的地址栏输入一个 ...
- Notepad++ 运行java(转)
Notepad++ 运行java java, 2013/05/04, 9 replies, 6,007 views 文章目录 Notepad++ for java 安装必须的程序 配置NppExec ...
- JAVA设计模式---装饰者模式
写在前面的话: 该模式动态的将责任附加到对象上,若要扩展功能,装饰者提供了比继承更有弹性的替代方案.装饰者可以在被装饰者的行为前面与/或后面加上自己的行为,甚至将被装饰者的行为整个取代掉,而达到特定的 ...