none
Problem mit Event-Reihenfolge (WPF) RRS feed

  • Frage

  • Hallo zusammen,

    also ich habe auf meinem Fenster ein DataGrid-Steuerelement und habe ein Fenster, dass sich öffnen soll, sobald man Rechts auf eine Zeile klickt. Also habe ich das MouseLeftButtonUp-Event benutzt von meinem DataGrid. Das Problem ist nur, dass wenn ich beim geöffneten Fenster im konstruktor die aktuell ausgewählte Zeile abfrage mit SelectedIndex, dann bekomme ich den Index von der zuvor ausgewählten Zeile.
    Gibt's irgendeine Methode in DataGrid, die den SelectedIndex aktualisiert?

    Ach ja und UpdateLayout() hab ich schon probiert, hat aber leider nicht funtkioniert :(

    EDIT: Ich meine das MouseRightButtonUp_Event meines Fensters ("MainWindow")... da fragt ich mich, was ich für einen Müll schreibe >.<
    • Bearbeitet MaSch0212 Sonntag, 22. Juli 2012 16:51
    Samstag, 21. Juli 2012 17:18

Antworten

  • Danke für deine Lösung...

    Ich habe heute noch etwas herumgeguckt und habe auch eine Lösung gefunden, kurz bevor du das geschrieben hast ^^

    Ich kann ja auch mal meine Lösung hier Posten :)

    Also ich habe Zuerst ein Event hinzugefügt, dass ausgelöst wird, wenn eine Zeile zum DataGrid hinzugefügt wird...

    dgDataGrid.LoadingRow += dgDataGrid_LoadingRow;

    In der Methode "dgDataGrid_LoadingRow" (Sorry das ist Visual Studio 2012... da braucht man dieses "new ...Delegate(...)" nicht mehr :D)

            

    public int selectedRowIndex = -1;

    void dgDataGrid_LoadingRow(object sender, DataGridRowEventArgs e) { e.Row.PreviewMouseRightButtonUp += Row_PreviewMouseRightButtonUp; }

    Die Variable "selectedRowIndex" habe ich noch hinzugefügt, damit mann abfragen kann, welche Zeile ausgewählt ist.

    dann die Methode Row_PreviewMouseRightButtonUp:

            void Row_PreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
            {
                selectedRowIndex = ((DataGridRow)sender).GetIndex();
            }

    So wenn ich jetzt das Event MouseRightButtonUp von dem Window benutze, kann ich ganz einfach die Variable selectedRowIndex abfragen :D

    • Als Antwort markiert MaSch0212 Montag, 23. Juli 2012 14:31
    Montag, 23. Juli 2012 14:31

Alle Antworten

  • Hi MaSch0212,

    verwende doch das CellClick Bzw Row/Colomne Event.

    Über die Event Args bekommst du dann Raus welche Zeile es war.

    MFG

    Björn

    Samstag, 21. Juli 2012 18:24
  • Hallo Palin

    sorry mein Fehler.. ich habe vergessen den Thread im WPF Forum zu Posten.

    Das was du meinst sind die Events von der DataGridView aus Windows Forms. Ich meine aber das DataGrid aus WPF :/

    Trotzdem danke, dass du geantwortet hast :)

    EDIT: Anscheinend doch nicht mein Fehler :P - Hab's doch im WPF Forum gepostet :)
    • Bearbeitet MaSch0212 Samstag, 21. Juli 2012 18:28
    Samstag, 21. Juli 2012 18:27
  • Hi MaSch02012,

    Sorry mein Fehler.

    Ich denk mal dass Event was du brauchst ist MouseRightButtonDown vom Grid.

    Über Source oder OrginalSource, solltest du dann deine Zeile bekommen.

    Bin hier aber nicht sicher, da ich nicht Täglich mit WPF arbeite.

    MFG

    Björn

    Samstag, 21. Juli 2012 20:16
  • Wenn Du die rechte Spalte auf die gesamte Breite ausdehnst, funktioniert das problemlos. Hier mal eine Demo:

    XAML:

    <Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
        <Grid>
        <DataGrid Name="dg" ItemsSource="{Binding View}" AutoGenerateColumns="False">
          <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding ID}" Width="Auto"/>
            <DataGridTextColumn Binding="{Binding col1}" Width="*"/>
          </DataGrid.Columns>
        </DataGrid>
      </Grid>
    </Window>
    

    Dazu der CodeBehind:

    Imports System.ComponentModel
    Imports System.Data
    
    Class MainWindow
    
      Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
        Me.DataContext = Me
      End Sub
    
      Dim cvs As New CollectionViewSource
      Public ReadOnly Property View As ICollectionView
        Get
          If cvs.View Is Nothing Then
            Dim dt As New DataTable
            With dt
              With .Columns
                With .Add("ID", GetType(Integer))
                  .AutoIncrement = True
                  .AutoIncrementSeed = 1
                  .AutoIncrementStep = 1
                End With
                .Add("col1", GetType(String))
              End With
              For i = 1 To 10
                Dim r = .NewRow
                r(1) = String.Format("Zeile {0:00}", i)
                .Rows.Add(r)
              Next
            End With
            cvs.Source = dt
          End If
          Return cvs.View
        End Get
      End Property
    
      Private Sub dg_MouseLeftButtonUp(sender As Object, e As System.Windows.Input.MouseButtonEventArgs) Handles dg.MouseLeftButtonUp
        MsgBox(CType(cvs.View.CurrentItem, DataRowView)("ID"))
      End Sub
    
    End Class
    

    --
    Viele Gruesse
    Peter

    Sonntag, 22. Juli 2012 11:14
  • Schon mal danke für deine Antwort Peter.

    Ich glaube ich habe mich bei meiner Problembeschreibung nicht richtig bemüht :D

    Mein Event, dass auf das aktuelle Item zugriefen will ist nicht das MouseLeftButtonUp Event der DataGrid, es ist das Event MouseRightButtonUp vom MainWindow.

    Sorry

    Sonntag, 22. Juli 2012 16:49
  • Mit der rechten Maustaste wird aber keine Zeile ausgewählt. Dadurch wird immer die aktuell ausgewählte Zeile ermittelt und nicht die, auf die mit der rechten Maustaste geklickt wurde.
     
    --
    Viele Gruesse
    Peter
    Sonntag, 22. Juli 2012 17:00
  • Das komische ist ja, dass aber wenn ich mit der Rechten Maustaste drücke, dass dann trotzdem die Markierung auf die Zeile unter dem Mauszeiger springt.

    Naja gibt es denn irgendwie die Möglichkeit abzufragen, über welcher Zeile die Maus in dem Moment war, als das Event ausgelöst wurde (also das MainWindow.MouseRightButtonUp Event), oder dann man irgendwie das Event für das DataGrid vorzieht?

    Hm vielleicht könnte man es auch mit einem simulieren Mausklick machen ???

    Sonntag, 22. Juli 2012 18:08
  • Ich habe eine Lösung. Hier mal die Demo dazu:

    XAML:

    <Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
        <Grid>
        <DataGrid Name="dg" ItemsSource="{Binding View}" AutoGenerateColumns="False">
          <DataGrid.Columns>
            <DataGridTextColumn Binding="{Binding ID}" Width="Auto"/>
            <DataGridTextColumn Binding="{Binding col1}" Width="*"/>
          </DataGrid.Columns>
        </DataGrid>
      </Grid>
    </Window>
    

    Dazu der Codebehind. Im Trace wird der Index der angeklickten Zeile ausgegeben:

    Imports System.ComponentModel
    Imports System.Data
    Imports System.Windows.Controls.Primitives
    
    Class MainWindow
    
      Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded
        Me.DataContext = Me
      End Sub
    
      Dim cvs As New CollectionViewSource
      Public ReadOnly Property View As ICollectionView
        Get
          If cvs.View Is Nothing Then
            Dim dt As New DataTable
            With dt
              With .Columns
                With .Add("ID", GetType(Integer))
                  .AutoIncrement = True
                  .AutoIncrementSeed = 1
                  .AutoIncrementStep = 1
                End With
                .Add("col1", GetType(String))
              End With
              For i = 1 To 10
                Dim r = .NewRow
                r(1) = String.Format("Zeile {0:00}", i)
                .Rows.Add(r)
              Next
            End With
            cvs.Source = dt
          End If
          Return cvs.View
        End Get
      End Property
    
      Private Sub dg_MouseRightButtonUp(sender As Object, e As System.Windows.Input.MouseButtonEventArgs) Handles dg.MouseRightButtonUp
        Dim dep = CType(e.OriginalSource, DependencyObject)
    
        ' iterativ durch den visual tree
        While dep IsNot Nothing AndAlso dep.GetType IsNot GetType(DataGridCell)
          dep = VisualTreeHelper.GetParent(dep)
        End While
    
        If dep Is Nothing Then Return
    
        If dep.GetType Is GetType(DataGridCell) Then
          Dim cell = TryCast(dep, DataGridCell)
          ' weiter nach oben im tree
          While dep IsNot Nothing AndAlso dep.GetType IsNot GetType(DataGridRow)
            dep = VisualTreeHelper.GetParent(dep)
          End While
          Dim row = TryCast(dep, DataGridRow)
          Dim index = FindRowIndex(row)
          Trace.WriteLine(String.Format("{0}", index))
        End If
    
      End Sub
    
      Private Function FindRowIndex(row As DataGridRow) As Integer
        If row Is Nothing Then Return -1
        Dim dataGrid = TryCast(ItemsControl.ItemsControlFromItemContainer(row), DataGrid)
        Return dataGrid.ItemContainerGenerator.IndexFromContainer(row)
      End Function
    
    End Class
    

    --
    Viele Gruesse
    Peter

    Montag, 23. Juli 2012 07:54
  • Danke für deine Lösung...

    Ich habe heute noch etwas herumgeguckt und habe auch eine Lösung gefunden, kurz bevor du das geschrieben hast ^^

    Ich kann ja auch mal meine Lösung hier Posten :)

    Also ich habe Zuerst ein Event hinzugefügt, dass ausgelöst wird, wenn eine Zeile zum DataGrid hinzugefügt wird...

    dgDataGrid.LoadingRow += dgDataGrid_LoadingRow;

    In der Methode "dgDataGrid_LoadingRow" (Sorry das ist Visual Studio 2012... da braucht man dieses "new ...Delegate(...)" nicht mehr :D)

            

    public int selectedRowIndex = -1;

    void dgDataGrid_LoadingRow(object sender, DataGridRowEventArgs e) { e.Row.PreviewMouseRightButtonUp += Row_PreviewMouseRightButtonUp; }

    Die Variable "selectedRowIndex" habe ich noch hinzugefügt, damit mann abfragen kann, welche Zeile ausgewählt ist.

    dann die Methode Row_PreviewMouseRightButtonUp:

            void Row_PreviewMouseRightButtonUp(object sender, MouseButtonEventArgs e)
            {
                selectedRowIndex = ((DataGridRow)sender).GetIndex();
            }

    So wenn ich jetzt das Event MouseRightButtonUp von dem Window benutze, kann ich ganz einfach die Variable selectedRowIndex abfragen :D

    • Als Antwort markiert MaSch0212 Montag, 23. Juli 2012 14:31
    Montag, 23. Juli 2012 14:31