DataGrid Zeilen mit Maus verschieben

  • WPF MVVM

Es gibt 4 Antworten in diesem Thema. Der letzte Beitrag () ist von kafffee.

    DataGrid Zeilen mit Maus verschieben

    Guten Morgen allerseits :-)!

    Ich versuche gerade, die Zeilen eines DataGrid mit der Maus "verschiebbar" zu machen und habe im Internet eine C#-Klasse gefunden, die ich mit einem Online-Übersetzer ins Folgende übersetzt habe:

    Spoiler anzeigen

    VB.NET-Quellcode

    1. Imports System
    2. Imports System.Collections
    3. Imports System.Collections.Generic
    4. Imports System.Linq
    5. Imports System.Text
    6. Imports System.Threading.Tasks
    7. Imports System.Windows
    8. Imports System.Windows.Controls
    9. Imports System.Windows.Input
    10. Imports System.Windows.Media
    11. Namespace DataGridMovableRows
    12. Public Class VisualHelper
    13. Inherits ViewModel.Instrastructure.ViewModelBase
    14. Public Shared ReadOnly EnableRowsMoveProperty As DependencyProperty = DependencyProperty.RegisterAttached("EnableRowsMove", GetType(Boolean), GetType(VisualHelper), New PropertyMetadata(False, AddressOf EnableRowsMoveChanged))
    15. Private Shared ReadOnly DraggedItemProperty As DependencyProperty = DependencyProperty.RegisterAttached("DraggedItem", GetType(Object), GetType(VisualHelper), New PropertyMetadata(Nothing))
    16. Public Shared Function GetEnableRowsMove(ByVal obj As DataGrid) As Boolean
    17. Return CBool(obj.GetValue(EnableRowsMoveProperty))
    18. End Function
    19. Public Shared Sub SetEnableRowsMove(ByVal obj As DataGrid, ByVal value As Boolean)
    20. obj.SetValue(EnableRowsMoveProperty, value)
    21. End Sub
    22. Private Shared Function GetDraggedItem(ByVal obj As DependencyObject) As Object
    23. Return CObj(obj.GetValue(DraggedItemProperty))
    24. End Function
    25. Private Shared Sub SetDraggedItem(ByVal obj As DependencyObject, ByVal value As Object)
    26. obj.SetValue(DraggedItemProperty, value)
    27. End Sub
    28. Private Shared Sub EnableRowsMoveChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
    29. Dim grid = (TryCast(d, DataGrid))
    30. If grid Is Nothing Then Return
    31. If CBool(e.NewValue) Then
    32. grid.PreviewMouseLeftButtonDown += AddressOf OnMouseLeftButtonDown
    33. grid.PreviewMouseLeftButtonUp += AddressOf OnMouseLeftButtonUp
    34. grid.PreviewMouseMove += AddressOf OnMouseMove
    35. Else
    36. grid.PreviewMouseLeftButtonDown -= AddressOf OnMouseLeftButtonDown
    37. grid.PreviewMouseLeftButtonUp -= AddressOf OnMouseLeftButtonUp
    38. grid.PreviewMouseMove -= AddressOf OnMouseMove
    39. End If
    40. End Sub
    41. Private Shared Sub OnMouseLeftButtonDown(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
    42. Dim row = TryFindFromPoint(Of DataGridRow)(CType(sender, UIElement), e.GetPosition((TryCast(sender, DataGrid))))
    43. If row Is Nothing OrElse row.IsEditing Then Return
    44. VisualHelper.SetDraggedItem(TryCast(sender, DataGrid), row.Item)
    45. End Sub
    46. Private Shared Sub OnMouseLeftButtonUp(ByVal sender As Object, ByVal e As MouseButtonEventArgs)
    47. Dim draggeditem = VisualHelper.GetDraggedItem(TryCast(sender, DependencyObject))
    48. If draggeditem Is Nothing Then Return
    49. ExchangeItems(sender, (TryCast(sender, DataGrid)).SelectedItem)
    50. TryCast(sender, DataGrid).SelectedItem = draggeditem
    51. VisualHelper.SetDraggedItem(TryCast(sender, DataGrid), Nothing)
    52. End Sub
    53. Private Shared Sub OnMouseMove(ByVal sender As Object, ByVal e As MouseEventArgs)
    54. Dim draggeditem = VisualHelper.GetDraggedItem(TryCast(sender, DependencyObject))
    55. If draggeditem Is Nothing Then Return
    56. Dim row = TryFindFromPoint(Of DataGridRow)(CType(sender, UIElement), e.GetPosition((TryCast(sender, DataGrid))))
    57. If row Is Nothing OrElse row.IsEditing Then Return
    58. ExchangeItems(sender, row.Item)
    59. End Sub
    60. Private Shared Sub ExchangeItems(ByVal sender As Object, ByVal targetItem As Object)
    61. Dim draggeditem = VisualHelper.GetDraggedItem(TryCast(sender, DependencyObject))
    62. If draggeditem Is Nothing Then Return
    63. If targetItem IsNot Nothing AndAlso Not ReferenceEquals(draggeditem, targetItem) Then
    64. Dim list = TryCast((TryCast(sender, DataGrid)).ItemsSource, IList)
    65. If list Is Nothing Then Throw New ApplicationException("EnableRowsMoveProperty requires the ItemsSource property of DataGrid to be at least IList inherited collection. Use ObservableCollection to have movements reflected in UI.")
    66. Dim targetIndex = list.IndexOf(targetItem)
    67. list.Remove(draggeditem)
    68. list.Insert(targetIndex, draggeditem)
    69. End If
    70. End Sub
    71. Public Shared Function FindVisualParent(Of T As DependencyObject)(ByVal child As DependencyObject) As T
    72. Dim parentObject = VisualTreeHelper.GetParent(child)
    73. If parentObject Is Nothing Then Return Nothing
    74. Dim parent As T = TryCast(parentObject, T)
    75. If parent IsNot Nothing Then
    76. Return parent
    77. Else
    78. Return FindVisualParent(Of T)(parentObject)
    79. End If
    80. End Function
    81. Public Shared Function TryFindFromPoint(Of T As DependencyObject)(ByVal reference As UIElement, ByVal point As Point) As T
    82. Dim element = TryCast(reference.InputHitTest(point), DependencyObject)
    83. If element Is Nothing Then Return Nothing
    84. If TypeOf element Is T Then Return CType(element, T)
    85. Return FindVisualParent(Of T)(element)
    86. End Function
    87. End Class
    88. End Namespace


    Leider gibt es in der Sub EnableRowsMoveChanged rot unterstrichene Fehler, die ich nicht zu beheben weiss:

    VB.NET-Quellcode

    1. Private Shared Sub EnableRowsMoveChanged(ByVal d As DependencyObject, ByVal e As DependencyPropertyChangedEventArgs)
    2. Dim grid = (TryCast(d, DataGrid))
    3. If grid Is Nothing Then Return
    4. If CBool(e.NewValue) Then
    5. grid.PreviewMouseLeftButtonDown += AddressOf OnMouseLeftButtonDown
    6. grid.PreviewMouseLeftButtonUp += AddressOf OnMouseLeftButtonUp
    7. grid.PreviewMouseMove += AddressOf OnMouseMove
    8. Else
    9. grid.PreviewMouseLeftButtonDown -= AddressOf OnMouseLeftButtonDown
    10. grid.PreviewMouseLeftButtonUp -= AddressOf OnMouseLeftButtonUp
    11. grid.PreviewMouseMove -= AddressOf OnMouseMove
    12. End If
    13. End Sub


    Und zwar bei grid.PreviewMouseLeftButtonDown, grid.PreviewMouseLeftButtonUp, usw. kommt die Fehlermeldung:

    "Public Event PreviewMouseLeftButtonDown As MouseButtonEventHandler" ist ein Ereignis und kann nicht direkt aufgerufen werden. Verwenden Sie eine RaiseEvent-Anweisung, um ein Ereignis aufzurufen.

    Wenn ich jetzt aber ein RaiseEvent davorschreibe, kommt: "grid" ist kein Ereignis von "Visual Helper".

    Der XAML sieht folgendermassen aus:

    XML-Quellcode

    1. <DataGrid ItemsSource="{Binding Playlist, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" SelectionMode="Single" Name="productsDataGrid" viewmodel:VisualHelper.EnableRowsMove="True">


    Weiss jemand Abhilfe?
    :huh: Ich dächt, dass solch ein Übersetzungsfehler Dir längst bekannt wäre. Währen man in C# mit Control.Event += new System.EventHandler(DeineEventHandlerMethode) einen EventHandler zuweist, macht man das in VB.NET mit AddHandler Control.Event, AddressOf DeineEventHandlerMethode, also z.B. AddHandler grid.PreviewMouseLeftButtonDown, AddressOf OnMouseLeftButtonDown
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.
    Naja, ich hab's eigentlich immer wieder auch hier im Forum gelesen, dass es da "Übersetzungsprobleme" gibt. Neulich erst wieder bei Bartosz: Code für mehrere PictureBox-Eventhandler zusammenfassen
    Dieser Beitrag wurde bereits 5 mal editiert, zuletzt von „VaporiZed“, mal wieder aus Grammatikgründen.

    Aufgrund spontaner Selbsteintrübung sind all meine Glaskugeln beim Hersteller. Lasst mich daher bitte nicht den Spekulatiusbackmodus wechseln.