【问题标题】:Drag and Drop rows of Datagrid WPF Code convertion from C# to VB.NET从 C# 到 VB.NET 的 Datagrid WPF 代码转换的拖放行
【发布时间】:2016-10-11 05:06:38
【问题描述】:

所以我一直在尝试在 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)) 我收到类似的错误 -> “System.Windows.Point”类型的错误值无法转换为“MyappWPF.GetDragDropPosition”。 我想这与委托 GetDragDropPosition 的类型有关。 我无法弄清楚出了什么问题。

【问题讨论】:

  • 你为什么不只使用prevRowIndex = GetDataGridItemCurrentRowIndex(e.GetPosition)
  • 我已经试过了。它给了我这个错误:Argument not specified for parameter 'relativeTo' of 'Public Function GetPosition(relativeTo As System.Windows.IInputElement) As System.Windows.Point'.

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


【解决方案1】:

转换有几个错误:

  1. 您无缘无故地制作委托参数“ByRef” - 它应该是:

    公共委托函数GetDragDropPosition(ByVal theElement As IInputElement) As Point

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

    部分公共类 MainWindow
    继承窗口

  3. 您的“For”循环正在减去 26 - 又一次没有明显的原因 - 它应该是:

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

【讨论】:

  • 第 2 点和第 3 点有更多错别字。我将 Delegate 参数从“ByRef”更改为 ByVal,不再出现该错误。谢谢。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-12-17
相关资源
最近更新 更多