none
Wie kann man DragDrop-Events in einem ViewModel handeln? RRS feed

  • Frage

  • Hallo zusammen,

    ich habe in einem UserControl 2 Datagrids. Für das UserControl habe ich ein ViewModel mit diversen Properties und den DataContext des UserControls an das ViewModel gebunden. Die Namen der DataGrids habe ich im UserControl an Properties im ViewModel gebunden:

    <DataGrid x:Name="{Binding NameDataGrid1}" 
      .../>
    <DataGrid x:Name="{Binding NameDataGrid2}" 
      .../>

    Ich möchte nun per DragAndDrop Datensätze aus dem einen Datagrid in das andere Datagrid verschieben. Im CodeBehind habe ich bisher die DragDrop-Events ausgewertet:

    private void UserControl_Loaded(object sender, RoutedEventArgs e)
            {
                this.DataGrid1.DragEnter += OnDragEnterEvent;
                this.DataGrid1.DragOver += OnDragOverEvent;
                this.DataGrid1.Drop += OnDropEvent;
                this.DataGrid2.DragEnter += OnDragEnterEvent;
                this.DataGrid2.DragOver += OnDragOverEvent;
                this.DataGrid2.Drop += OnDropEvent;
            }
    
    // Handles the DragEnter event
            void OnDragOverEvent(object sender, DragEventArgs e)
            {
                e.Effects = DragDropEffects.Move;
            }
    
    // Handles the DragEnter event
            void OnDragEnterEvent(object sender, DragEventArgs e)
            {
                e.Effects = DragDropEffects.Move;
                ...
            }
    
    // Handles the Drop event
            void OnDropEvent(object sender, DragEventArgs e)
            {
                if (e.Effects == DragDropEffects.None)
                    return;
                ...
            }

    Die DragDrop-Methoden haben mit dem CodeBehind auch wunderbar funktioniert.

    Wie kann ich nun den Code für die Auswertung der DragDrop-Events in das ViewModel auslagern???

    Gruß Jürgen

    Montag, 9. Mai 2016 09:09

Antworten

  • Hi Jürgen,
    die Idee beim attached behavior ist, eine DependencyProperty hinzuzufügen, die dann im XAML genutzt wird. Bei der Instanziierung des Steuerelementes (z.B. DataGrid) wird diese Eigenschaft auch abgerufen und man kann sich den Verweis auf den "Verursacher" "fangen". An diesen Verweis kann man die Handler für Drag&Drop hängen und genau so arbeiten wie im Codebehind. Für VB.NET habe ich die 3 Grundprinzipien (Eigenschaftsbindung, Befehlsbindung und angehängtes Verhalten) auf meine Homepage dargestellt. Für C#.NET gibt es dazu im Web viele Beiträge.

    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Montag, 9. Mai 2016 15:15

Alle Antworten

  • Zusatz: Eine Idee von mir ist über Event-Trigger:

    <i:Interaction.Triggers>
                                    <i:EventTrigger EventName="DragEnter">
                                        <i:InvokeCommandAction 
                                            Command="{Binding DataGrid1DragEnterCommand}"  
                                            CommandParameter="{Binding ElementName=DataGrid1, Path=DragEnter}"/>
                                    </i:EventTrigger>
                                    <i:EventTrigger EventName="DragOver">
                                        <i:InvokeCommandAction 
                                            Command="{Binding DataGrid1DragOverCommand}"  
                                            CommandParameter="{Binding ElementName=DataGrid1, Path=DragOver}"/>
                                    </i:EventTrigger>
                                    <i:EventTrigger EventName="Drop">
                                        <i:InvokeCommandAction 
                                            Command="{Binding DataGrid1dropCommand}"  
                                            CommandParameter="{Binding ElementName=DataGrid1, Path=Drop}"/>
                                    </i:EventTrigger>
    
                                </i:Interaction.Triggers>
    Liege ich hiemit richtig???

    Montag, 9. Mai 2016 09:21
  • Hallo Jürgen,

    einer der üblichen Wege wäre es über eine Behavior Erweiterung [1] zu machen.

    Kurze Fassung (nicht nur für WPF Light): MVVM Light WPF Drag and Drop

    Ein ausführlicher CodeProject Artikel: WPF Drag and Drop MVVM using Behavior.

    Gruß Elmar

    [1] benötigt eine weitere Assembly: How to add System.Windows.Interactivity to project?.

    Montag, 9. Mai 2016 09:28
  • Hallo Elmar,

    danke für die Links.

    Allerdings hatte ich mir schon einen DragDropManager für Datagrids "gebastelt" und er funktioniert auch, allerdings nur mit den CodeBehind-Methoden, da für den Manager das DataGrid als Type übergeben wird.

    Ich wollte mir mal den Code von dem ausführlichen Artikel ansehen. Leider wird in meinem Browser "MS-Edge" der Download von CodeProject als unsicher blockiert.

    Gruß Jürgen

    Montag, 9. Mai 2016 10:47
  • Hi Jürgen,
    wenn Dein Algorithmus im CodeBehind funktioniert, dann ist es einfach, über attached behavior einen Verweis auf das Objekt (z.B. DataGrid) im ViewModel zu bekommen und den gesamten Code auch dort laufen zu lassen.

    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Montag, 9. Mai 2016 11:29
  • Hallo Peter,

    leider hatte ich mich bisher noch nicht mit attached behavior befasst.

    Kannst du mir da vielleicht mal durch einen Code-Schnipsel auf die Sprünge helfen? (Wie ich im ViewModel einen Verweis auf das Object "Datagrid" hinbekomme)

    Gruß Jürgen

    Montag, 9. Mai 2016 11:58
  • Hi Jürgen,
    die Idee beim attached behavior ist, eine DependencyProperty hinzuzufügen, die dann im XAML genutzt wird. Bei der Instanziierung des Steuerelementes (z.B. DataGrid) wird diese Eigenschaft auch abgerufen und man kann sich den Verweis auf den "Verursacher" "fangen". An diesen Verweis kann man die Handler für Drag&Drop hängen und genau so arbeiten wie im Codebehind. Für VB.NET habe ich die 3 Grundprinzipien (Eigenschaftsbindung, Befehlsbindung und angehängtes Verhalten) auf meine Homepage dargestellt. Für C#.NET gibt es dazu im Web viele Beiträge.

    --
    Viele Grüsse
    Peter Fleischer (MVP, Partner)
    Meine Homepage mit Tipps und Tricks
    Kommas richtig setzen!
    Schüler sagen, Lehrer haben es gut.
    Schüler, sagen Lehrer, haben es gut

    Montag, 9. Mai 2016 15:15