项目需要实现一个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 拖动 附加属性类的更多相关文章

  1. silverlight datagrid绑定匿名类

    原文 http://www.cnblogs.com/luweis/archive/2011/10/21/2220587.html 刚开始遇到的一个问题是这样的,我有一个datagrid,根据不同的条件 ...

  2. datagrid拖动列头更换排列顺序

    在做这个功能的时候在网上找了大量资料,发现都不适用,要不然就是代码太冗余,所以另起炉灶,自己封装了这个函数 下面是完整的代码: <!DOCTYPE html> <html> & ...

  3. 控制EasyUI DataGrid高度

    这次要说的是控制EasyUI的高度,平时我公司的项目,用EasyUI较多,然后datagrid这个组件是用的非常多的.平时我们都是固定高度,常见代码如下:             <table  ...

  4. VS2015中的项目类图

    发现右键项目的时候,是没有类图的. https://msdn.microsoft.com/en-us/library/hyxd8c85.aspx 右键项目--添加--新建项. 选择类图. 然后将整个项 ...

  5. Flutter进阶—点击、拖动和其他手势

    Flutter中的手势系统有两个层次.第一层具有原始指针事件,其描述了穿过屏幕的指针(例如触摸.鼠标和触控笔)的位置和移动.第二层具有手势,其描述由一个或多个指针移动组成的语义动作. 指针指针代表用户 ...

  6. Windows Community Toolkit 4.0 - DataGrid - Part03

    概述 在上面一篇 Windows Community Toolkit 4.0 - DataGrid - Part02 中,我们针对 DataGrid 控件的 Utilities 部分做了详细分享.而在 ...

  7. C# WinForm开发系列 - DataGrid/DataGridView

    在WinForm开发中,DataGrid/DataGridView被广泛使用于绑定数据库中数据进行呈现.整理一些关于DataGrid/DataGridView使用的文章,涉及DataGrid/Data ...

  8. easyui datagrid列拖拽

    <script type="text/javascript"> var cols = [{ field: 'testName', title: '<span cl ...

  9. Easyui datagrid自定义排序

    做项目遇到个关于排序问题,想着在前端排序,正好Easyui有这个功能,所以就拿来用了一下,因为跟官网的Demo不太一样,所以总结一下: 首先这一列是要排序的列(当然,在生产环境,这一列是隐藏的,在开发 ...

随机推荐

  1. 自定义alert弹框

    /**************** UIAlertControllerStyleAlert *************************/ /*创建一个 可以自定义文字颜色和字体大小的IAler ...

  2. DEDECMS去掉自动生成首页或栏目后面带的index.html

    Dede默认生成首页后,首页的链接后面会多出一个index.html.据官方说法这样有利于网站优化.但是这个index.html怎么看都不舒服,而且也不利于seo中主页url的统一.因为我的网站的ur ...

  3. Intellij idea 导入 jdbc

    第一步,去官网https://dev.mysql.com/downloads/connector/j/ 下载驱动程序 第二步,解压压缩包,记住路径 第三步,打开你的idea工程,打开Project S ...

  4. IOS UI 滚动视图 UIScrollView

    UIScrollView 常用属性 scrollView.maximumZoomScale= 2.0; //  缩放最大比例 scrollView.minimumZoomScale = 0.2;// ...

  5. WEB前端大神之路之基础篇

    CSS篇: 1.CSS权重: 不重复造轮子啦,直接传送门(CSS选择器的权重与优先规则) JavaScript篇: 1.this关键字: 它是一种引用(referent).指向的是当前上下文(cont ...

  6. CentOs下安装PHP扩展curl

    服务器运行一段时间后,可能突然会需求添加某个扩展,如curl.pdo.xmlrpc等,这就需要在不重新编译Linux PHP的情况下独立添加扩展. 1.安装crul wget http://curl. ...

  7. CentOS6.x机器安装Azure CLI2.0【2】

    安装Azure CLI 2.0的前提是:机器中必须有 Python 2.7.x 或 Python 3.x.如果机器中没有其中任何一个Python版本,请及时安装 1.准备一台CentOS 6.9的机器 ...

  8. Django_实现分页

    需求: 对于有很多数据,并不希望一次性全部展现在一个页面,需要一个分页的,定好每一页显示的内容 那,如何满足这个需求呢? 通过第三方模块  django-pure-pagination pip ins ...

  9. python_如何在循环引用中管理内存?

    案例: python中通过引用计数来回收垃圾对象,在某些环形数据结构(树,图--),存在对象间的循环引用,比如树的父节点引用子节点,子节点同时引用父节点,此时通过del掉引用父子节点,两个对象不能被立 ...

  10. python_py2和py3读写文本区别

    python2和python3的区别? python 2  str             对应      python3 bytes python 2 uincode            对应   ...