简体   繁体   中英

Drag and Drop rows of Datagrid WPF Code convertion from C# to VB.NET

So I have been trying to implement Drag and Drop functionality for WPF datagrid in vb.net . I have found this tutorial which is doing the same. the only problem for me is - the tutorial and code is in C#.

C# Code :

namespace WPF40_DataGrid_Row_Drag_Drop
{

// Declare a Delegate which will return the position of the 
// DragDropEventArgs and the MouseButtonEventArgs event object
public delegate Point GetDragDropPosition(IInputElement theElement);

   public partial class MainWindow : Window
{
    int prevRowIndex = -1;
    public MainWindow()
    {
        InitializeComponent();
        //The Event on DataGrid for selecting the Row
        this.dgEmployee.PreviewMouseLeftButtonDown += 
            new MouseButtonEventHandler(dgEmployee_PreviewMouseLeftButtonDown);
        //The Drop Event
        this.dgEmployee.Drop += new DragEventHandler(dgEmployee_Drop);
    }

    void dgEmployee_Drop(object sender, DragEventArgs e)
    {
        if (prevRowIndex < 0)
            return;

        int index = this.GetDataGridItemCurrentRowIndex(e.GetPosition);

        //The current Rowindex is -1 (No selected)
        if (index < 0)
            return;
        //If Drag-Drop Location are same
        if (index == prevRowIndex)
            return;
        //If the Drop Index is the last Row of DataGrid(
        // Note: This Row is typically used for performing Insert operation)
        if (index == dgEmployee.Items.Count-1)
        {
            MessageBox.Show("This row-index cannot be used for Drop Operations");
            return;
        }

        EmployeeCollection myEmps = Resources["EmpDs"] as EmployeeCollection;

        Employee movedEmps = myEmps[prevRowIndex];
        myEmps.RemoveAt(prevRowIndex);

        myEmps.Insert(index, movedEmps);
    }

    void dgEmployee_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        prevRowIndex = GetDataGridItemCurrentRowIndex(e.GetPosition);

        if (prevRowIndex < 0)
            return;
        dgEmployee.SelectedIndex = prevRowIndex;

        Employee selectedEmp = dgEmployee.Items[prevRowIndex] as Employee;

        if (selectedEmp == null)
            return;

        //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(dgEmployee, selectedEmp, dragdropeffects) 
                            != DragDropEffects.None)
        {
            //Now This Item will be dropped at new location and so the new Selected Item
            dgEmployee.SelectedItem = selectedEmp;
        }
    }

   private bool IsTheMouseOnTargetRow(Visual theTarget, GetDragDropPosition pos)
    {
        Rect posBounds = VisualTreeHelper.GetDescendantBounds(theTarget);
        Point theMousePos = pos((IInputElement)theTarget);
        return posBounds.Contains(theMousePos);
    }

 private DataGridRow GetDataGridRowItem(int index)
    {
        if (dgEmployee.ItemContainerGenerator.Status 
                != GeneratorStatus.ContainersGenerated)
            return null;

        return dgEmployee.ItemContainerGenerator.ContainerFromIndex(index) 
                                                        as DataGridRow;
    }

private int GetDataGridItemCurrentRowIndex(GetDragDropPosition pos)
    {
        int curIndex = -1;
        for (int i = 0; i < dgEmployee.Items.Count; i++)
        {
            DataGridRow itm = GetDataGridRowItem(i);
            if (IsTheMouseOnTargetRow(itm, pos))
            {
                curIndex = i;
                break;
            }
        }
        return curIndex;
    }
}
}

VB Code:

  Public Delegate Function GetDragDropPosition(ByRef element As IInputElement) As Point

public partial class MainWindow : Window

 Dim prevRowIndex As Integer = -1    
 public Sub MainWindow()

    InitializeComponent()
       AddHandler datagridRoll.PreviewMouseLeftButtonDown, AddressOf datagridRoll_PreviewMouseLeftButtonDown
    AddHandler datagridRoll.Drop, AddressOf datagridRoll_Drop   
End Sub

 Private Sub datagridRoll_Drop(sender As Object, e As System.Windows.DragEventArgs)
    If prevRowIndex < 0 Then
        Return
    End If


    Dim index As Integer = GetDataGridItemCurrentRowIndex(e.GetPosition(datagridRoll))
       If (index < 0) Then
        Return
    End If


    If (index = prevRowIndex) Then
        Return
    End If

           If (index = datagridRoll.Items.Count - 1) Then

        MessageBox.Show("This row-index cannot be used for Drop Operations")
        Return

    End If

End Sub

Private Sub datagridRoll_PreviewMouseLeftButtonDown(sender As Object, e As MouseButtonEventArgs)
    prevRowIndex = GetDataGridItemCurrentRowIndex(e.GetPosition(datagridRoll))
    prevRowIndex = datagridRoll.SelectedIndex
    If (prevRowIndex < 0) Then
        Return
    End If
    datagridRoll.SelectedIndex = prevRowIndex

    Dim selectedEmp As DataGridRow = TryCast(datagridRoll.ItemContainerGenerator.ContainerFromIndex(prevRowIndex), DataGridRow)

    If (selectedEmp Is Nothing) Then
        Return
    End If

    Dim DragDropEffects As DragDropEffects = DragDropEffects.Move

    If (DragDrop.DoDragDrop(datagridRoll, selectedEmp, DragDropEffects) <> DragDropEffects.None) Then

                datagridRoll.SelectedItem = selectedEmp

    End If
End Sub

 Public Function IsTheMouseOnTargetRow(theTarget As Visual, pos As GetDragDropPosition) As Boolean
    Dim posBounds As Rect = VisualTreeHelper.GetDescendantBounds(theTarget)
    posBounds = VisualTreeHelper.GetContentBounds(theTarget)


             Dim theMousePos As Point = pos(DirectCast(theTarget, IInputElement))
    Return posBounds.Contains(theMousePos )
End Function

Public Function GetDataGridRowItem(index As Integer) As DataGridRow
    If datagridRoll.ItemContainerGenerator.Status <> GeneratorStatus.ContainersGenerated Then
        Return Nothing
    End If

    Return TryCast(datagridRoll.ItemContainerGenerator.ContainerFromIndex(index), DataGridRow)

       End Function
Public Function GetDataGridItemCurrentRowIndex(pos As Point) As Integer
    Dim curIndex As Integer = -1
    For i As Integer = 0 To datagridRoll.Items.Count - 1 - 26
        Dim itm As DataGridRow = GetDataGridRowItem(i)
        If IsTheMouseOnTargetRow(itm, pos) Then
            curIndex = i
            Exit For
        End If
    Next
    Return curIndex
End Function
    End Class

Now, at Line prevRowIndex = GetDataGridItemCurrentRowIndex(e.GetPosition(datagridRoll)) I am getting an error like -> Error Value of type 'System.Windows.Point' cannot be converted to 'MyappWPF.GetDragDropPosition'. I guess it has something to do with Type of delegate GetDragDropPosition. I am not able to figure out what is wrong.

There are a few mistakes in the conversion:

  1. You are making the delegate parameter 'ByRef' for no apparent reason - it should be:

    Public Delegate Function GetDragDropPosition(ByVal theElement As IInputElement) As Point

  2. You are not specifying the base class correctly - it should be:

    Partial Public Class MainWindow
    Inherits Window

  3. Your 'For' loop is subtracting 26 - again for no apparent reason - it should be:

    For i As Integer = 0 To dgEmployee.Items.Count - 1

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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