2016-06-10 88 views
0

所以我一直在尝试实现在vb.net的WPF数据网格的拖放功能。我发现这个教程也是这样做的。对我来说唯一的问题是 - 教程和代码是用C#编写的。拖放DataGrid WPF代码转换从C#到VB.NET的行

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有关。 我无法弄清楚什么是错的。

+0

为什么你不只是使用'prevRowIndex = GetDataGridItemCurrentRowIndex(e.GetPosition)'? – Ian

+0

我已经试过了。它给了我这个错误:**没有为'Public Function GetPosition(relativeTo As System.Windows.IInputElement)'的参数'relativeTo'指定的参数作为System.Windows.Point'.' ** – ubergeek

回答

0

有在转换了几个错误:

  1. 您正在委托参数为“ByRef”没有明显的原因 - 它应该是:

    公共委托功能GetDragDropPosition(BYVAL theElement作为IInputElement)作为点

  2. 你是不是正确,指定的基类 - 它应该是:

    面值TiAl金属公共类主窗口
    继承窗口

  3. 你的 'for' 循环中减去26 - 无明显原因再次 - 它应该是:

    对于i为整数= 0要dgEmployee.Items.Count - 1

+0

Point no 2. and 3 。哪里有更多的错别字。我将Delegate参数从'ByRef'更改为ByVal,而不再发生该错误。谢谢。 – ubergeek