zoukankan      html  css  js  c++  java
  • 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 < 0)
                {
                    return;
                }
                DataGrid datagrid = sender as DataGrid;
                int index = GetDataGridItemCurrentRowIndex(e.GetPosition, datagrid);
    
                //The current Rowindex is -1 (No selected)
                if (index < 0)
                {
                    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 < 0)
                {
                    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 = -1;
                for (int i = 0; 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

  • 相关阅读:
    常用的gem source
    The `master` repo requires CocoaPods 0.29.0
    day 26 对象的封装 抽象和接口
    day25 面向对象继承 多态
    day24 面向对象 命名空间组合 以及继承
    day23 模块和包的复习 初识面向对象
    day22 模块和包
    day21 其他常用模块和异常处理
    day20 模块
    day19正则表达式和re模块
  • 原文地址:https://www.cnblogs.com/karl-F/p/WPF.html
Copyright © 2011-2022 走看看