将Datagrid WPF代码转换行从C#拖放到VB.NET

时间:2016-06-10 09:29:14

标签: c# .net wpf vb.net datagrid

所以我一直在尝试为vb.net中的WPF数据网格实现拖放功能。我发现这个教程也在做同样的事情。对我来说唯一的问题是 - 教程和代码是在C#中。

C#代码:

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代码:

  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

现在,在线          prevRowIndex = GetDataGridItemCurrentRowIndex(e.GetPosition(datagridRoll)) 我收到的错误如 - &gt;         类型&#39; System.Windows.Point&#39;的错误值无法转换为&#39; MyappWPF.GetDragDropPosition&#39;。 我想它与委托类型GetDragDropPosition有关。 我无法弄清楚出了什么问题。

1 个答案:

答案 0 :(得分:1)

转换中存在一些错误:

  1. 你正在制作委托参数'ByRef'没有明显的理由 - 它应该是:

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

  2. 您没有正确指定基类 - 它应该是:

    部分公共类MainWindow
            继承窗口

  3. 你的'For'循环减去26 - 再次没有明显的原因 - 它应该是:

    for i As Integer = 0 to dgEmployee.Items.Count - 1