繁体   English   中英

在WPF(C#)中的两个Datagrid之间拖放

[英]Drag and Drop between two Datagrid in WPF (C#)

对不起,我的英语,这不是我的母语。 如果您听不懂,请告诉我。

我正在启动C#和WPF,并且需要实现两个数据网格之间的拖放功能。 我已经搜索了很多东西,但是找不到任何可以帮助我的东西。 它总是显示如何在两个不同的控件之间或仅在同一数据网格中进行拖放,并且由于我不了解解决方案的某些部分,因此我无法适应这些答案。 因此,我来​​这里提出一个非常精确的问题:如何在两个数据网格之间实现拖放?

如果您能帮助我,我将不胜感激。

这是一个示例代码( 此处有更多详细信息

  1. 定义MouseDown事件
  2. 定义MouseMove事件以启动DragAndDrop操作
  3. 定义DragOver以测试是否允许放置
  4. 定义Drop事件以执行放置操作

您可以对两个数据网格使用相同的事件

    private Point? _startPoint;

    private void dataGrid_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        _startPoint = e.GetPosition(null);
    }

    private void dataGrid_PreviewMouseMove(object sender, MouseEventArgs e)
    {
        // No drag operation
        if (_startPoint == null)
            return;

        var dg = sender as DataGrid;
        if (dg == null) return; 
        // Get the current mouse position
        Point mousePos = e.GetPosition(null);
        Vector diff = _startPoint.Value - mousePos;
        // test for the minimum displacement to begin the drag
        if (e.LeftButton == MouseButtonState.Pressed &&
            (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance ||
            Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance))
        {

            // Get the dragged DataGridRow
            var DataGridRow=
                FindAnchestor<DataGridRow>((DependencyObject)e.OriginalSource);

            if (DataGridRow == null)
                return;
            // Find the data behind the DataGridRow
            var dataTodrop = (DataModel)dg.ItemContainerGenerator.
                ItemFromContainer(DataGridRow);

            if (dataTodrop == null) return;

            // Initialize the drag & drop operation
            var dataObj = new DataObject(dataTodrop);
            dataObj.SetData("DragSource", sender);
            DragDrop.DoDragDrop(dg, dataObj, DragDropEffects.Copy);
            _startPoint = null;
        }
    }

    private void dataGrid_PreviewMouseUp(object sender, MouseButtonEventArgs e)
    {
        _startPoint = null;
    }

    private void dataGrid_Drop(object sender, DragEventArgs e)
    {
        var dg = sender as DataGrid;
        if (dg == null) return;
        var dgSrc = e.Data.GetData("DragSource") as DataGrid;
        var data = e.Data.GetData(typeof(DataModel));
        if (dgSrc == null || data == null) return;
        // Implement move data here, depends on your implementation
        MoveDataFromSrcToDest(dgSrc, dg, data);
        // OR
        MoveDataFromSrcToDest(dgSrc.DataContext, dg.DataContext, data);
    }

    private void dataGrid_PreviewDragOver(object sender, DragEventArgs e)
    {
         // TO test if drop is allowed, to avoid drop 
         // if false e.Effects = DragDropEffects.None;
    }


    // Helper to search up the VisualTree
    private static T FindAnchestor<T>(DependencyObject current)
        where T : DependencyObject
    {
        do
        {
            if (current is T)
            {
                return (T)current;
            }
            current = VisualTreeHelper.GetParent(current);
        }
        while (current != null);
        return null;
    }

希望这个帮助:)

为此,您需要在xaml中使用两个这样的Datagrid feed列表或observableCollection:

<DataGrid AllowDrop="True" Name="dg1" Margin="10,50,10,30" Grid.Column="1">
    //Set your column and what you want
</DataGrid>
<DataGrid Name="dg2" AllowDrop="True" Margin="10,50,10,30" Grid.Column="2">
    //Set your column and what you want
</DataGrid>

我让您插入Datagrid的源:

dg1.ItemSource = "yourlist1";

dg2.ItemSource = "yourlist2";

将源代码填充到datagrid中后,将其添加到代码c#的顶部:

namespace YourAppName
{
    public partial class MainWindow : Window
    {
        public delegate Point GetPosition(IInputElement element);
        int rowIndex = -1;
        string dgName;
        public MainWindow()
        {
            dg1.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(DgSupp_PreviewMouseLeftButtonDown);
            dg1.Drop += new DragEventHandler(Dg_Drop);
            dg2.PreviewMouseLeftButtonDown += new MouseButtonEventHandler(DgSupp_PreviewMouseLeftButtonDown);
            dg2.Drop += new DragEventHandler(Dg_Drop);
        }

然后在MainWindow之后添加所有这些内容:

void Dg_Drop(object sender, DragEventArgs e)
        {
            int index = -1;
            DataGrid dg = new DataGrid();
            if (sender is DataGrid)
            {
                dg = (DataGrid)sender;
            }
            if (rowIndex < 0)
                return;
            if (dg.Name == "dg1")
            {
                index = this.GetCurrentRowIndexSupp(e.GetPosition);
            }
            if (dg.Name == "dg2")
            {
                index = this.GetCurrentRowIndexAdd(e.GetPosition);
            }
            if (index < 0)
                return;
            if (index == rowIndex)
                return;
            if (index == dg.Items.Count - 1)
            {
                MessageBox.Show("Last line can't moove");
                return;
            }
            if (dg.Name == "dg1")
            {
                if (dgName == "dg2")
                {
                    DataOfGrid changedProduct = yourlist2[rowIndex];
                    yourlist2.RemoveAt(rowIndex);
                    yourlist1.Insert(index, changedProduct);
                }
                else
                {
                    DataOfGrid changedProduct = yourlist1[rowIndex];
                    yourlist1.RemoveAt(rowIndex);
                    yourlist1.Insert(index, changedProduct);
                }
            }
            if (dg.Name == "dg2")
            {
                if (dgName == "dg1")
                {
                    DataOfGrid changedProduct = yourlist1[rowIndex];
                    yourlist1.RemoveAt(rowIndex);
                    yourlist2.Insert(index, changedProduct);
                }
                else
                {
                    DataOfGrid changedProduct = yourlist2[rowIndex];
                    yourlist2.RemoveAt(rowIndex);
                    yourlist2.Insert(index, changedProduct);
                }
            }
            dg1.ItemsSource = yourlist1;
            dg1.Items.Refresh();
            dg2.ItemsSource = yourlist2;
            dg2.Items.Refresh();
        }

        void DgSupp_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            DataGrid dg = new DataGrid();
            if (sender is DataGrid)
            {
                dg = (DataGrid)sender;
            }
            if (dg.Name == "dg1")
            {
                rowIndex = GetCurrentRowIndexSupp(e.GetPosition);
                dgName = dg.Name;
            }
            if (dg.Name == "dg2")
            {
                rowIndex = GetCurrentRowIndexAdd(e.GetPosition);
                dgName = dg.Name;
            }
            if (rowIndex < 0)
                return;
            dg.SelectedIndex = rowIndex;
            DataOfGrid selectedEmp = dg.Items[rowIndex] as DataOfGrid;
            if (selectedEmp == null)
                return;
            DragDropEffects dragdropeffects = DragDropEffects.Move;
            if (DragDrop.DoDragDrop(dg, selectedEmp, dragdropeffects)
                                != DragDropEffects.None)
            {
                dg.SelectedItem = selectedEmp;
            }
        }

        private bool GetMouseTargetRow(Visual theTarget, GetPosition position)
        {
            Rect rect = VisualTreeHelper.GetDescendantBounds(theTarget);
            Point point = position((IInputElement)theTarget);
            return rect.Contains(point);
        }

        private DataGridRow GetRowItemList1(int index)
        {
            if (dg1.ItemContainerGenerator.Status
                    != GeneratorStatus.ContainersGenerated)
                return null;
            return dg1.ItemContainerGenerator.ContainerFromIndex(index) as DataGridRow;
        }

        private DataGridRow GetRowItemList2(int index)
        {
            if (dg2.ItemContainerGenerator.Status
                    != GeneratorStatus.ContainersGenerated)
                return null;
            return dg2.ItemContainerGenerator.ContainerFromIndex(index) as DataGridRow;
        }

        private int GetCurrentRowIndexSupp(GetPosition pos)
        {
            int curIndex = -1;
            for (int i = 0; i < dg1.Items.Count; i++)
            {
                DataGridRow itm = GetRowItemList1(i);
                if (GetMouseTargetRow(itm, pos))
                {
                    curIndex = i;
                    break;
                }
            }
            return curIndex;
        }

        private int GetCurrentRowIndexAdd(GetPosition pos)
        {
            int curIndex = -1;
            for (int i = 0; i < dg2.Items.Count; i++)
            {
                DataGridRow itm = GetRowItemList2(i);
                if (GetMouseTargetRow(itm, pos))
                {
                    curIndex = i;
                    break;
                }
            }
            return curIndex;
        }

您要做的就是用Datagrid的名称替换“ dg1”和“ dg2”,并用提供给Datagrid的列表替换“ yourlist1”和“ yourlist2”。

也请为我的英语打个招呼,因为我一点都不讲,而且我受到拉杰·库马尔的文章的启发: https : //www.c-sharpcorner.com/UploadFile/raj1979/drag-and-drop-datagrid-row -in-WPF /

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM