所以我一直在尝试为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有关。 我无法弄清楚出了什么问题。
答案 0 :(得分:1)
转换中存在一些错误:
你正在制作委托参数'ByRef'没有明显的理由 - 它应该是:
Public Delegate Function GetDragDropPosition(ByVal theElement As IInputElement)As Point
您没有正确指定基类 - 它应该是:
部分公共类MainWindow
继承窗口
你的'For'循环减去26 - 再次没有明显的原因 - 它应该是:
for i As Integer = 0 to dgEmployee.Items.Count - 1