所以我一直在嘗試實現在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有關。 我無法弄清楚什麼是錯的。
爲什麼你不只是使用'prevRowIndex = GetDataGridItemCurrentRowIndex(e.GetPosition)'? – Ian
我已經試過了。它給了我這個錯誤:**沒有爲'Public Function GetPosition(relativeTo As System.Windows.IInputElement)'的參數'relativeTo'指定的參數作爲System.Windows.Point'.' ** – ubergeek