DataGrid; erste sichbare Zeile ermitteln

  • WPF
  • .NET (FX) 4.5–4.8

Es gibt 2 Antworten in diesem Thema. Der letzte Beitrag () ist von eichseinet.

    DataGrid; erste sichbare Zeile ermitteln

    Hallo Leute.

    In einem DataGrid soll die erste sichtbare / angezeigte Zeile ermittelt werden. NICHT das CurrentItem! Das kann längst aus dem sichtbaren Bereich gescrollt oder gar nicht erst gesetzt sein.
    Warum will man das wissen?
    Mein Programm enthält ein Datagrid dessen ItemsCollection ich mir hole. Dann startet eine Suche und das passende Item wird per ScrollIntoView ins Bild geholt. Soweit funktioniert es.
    Je nachdem ob das Item nun einen höhern oder niedriegeren Index als die sichtbaren Items hat, liegt es nach dem ScrollIntoView ganz oben oder ganz unten am Rand des DataGrids.
    Wenn ich die Position kenne, dann lässt sich vor dem ScrollIntoView ein Offset aufschlagen; negativ oder positiv. Dann läge das Item übersichtlich in der Mitte.

    VB.NET-Quellcode

    1. Dim DG As DataGrid = DirectCast(LogicalTreeHelper.FindLogicalNode(Current.MainWindow, "Alle_Timer_einzeln_DataGrid"), DataGrid)
    2. Dim View = DG.Items
    3. For i = View.Count - 1 To 0 Step -1
    4. Dim Item = DirectCast(View(i), Timer_einzeln_Klasse)
    5. If Item.PC_Name.ToLower = Name Then
    6. DG.ScrollIntoView(View(i))
    7. Exit For
    8. End If
    9. Next


    Die Suche im Netz hat da nicht wirklich etwas ergeben...
    Hat einer ne Idee?

    Gruß
    eddi
    Zuerst hatte ich die Idee, dass du dich auf das Scroll-Event subscriben könntest. Dann könntest du zumindest immer mitbekommen, wenn da was passiert ist.

    Dann habe ich das hier gefunden: github.com/DevExpress-Examples…in-rows-visible-on-screen

    Scheint genau das zu sein, was du suchst, mit Beispielen in C# und VB.
    Quellcode lizensiert unter CC by SA 2.0 (Creative Commons Share-Alike)

    Meine Firma: Procyon Systems
    Meine Privatwebseite: SimonC.eu

    Bitte nicht wundern, wenn meine Aktivitäten im Forum etwas langsamer sind, ich baue gerade mein Nebengewerbe zum Vollgewerbe aus.
    Ich versuche auf euch zurückzukommen :)
    Vielen Dank erstmal. Leider funktioniert das Projekt nicht. Im XAML gibt's Fehler, dass die Controls in WPF nicht existieren.
    Außerdem hab ich selbst weiter nach einer Lösung gesucht. Der gefunden Code funktionierte leider auch nihct, hat mich aber auf folgende Idee gebracht:
    (nur der erste Versuchsaubau, da fehlt noch was..)

    VB.NET-Quellcode

    1. Dim Hoehe As Double = 0
    2. Dim Zaehler As Integer = 0
    3. Dim DG As DataGrid = DirectCast(LogicalTreeHelper.FindLogicalNode(Current.MainWindow, "Alle_Timer_einzeln_DataGrid"), DataGrid)
    4. For i = 0 To Coll_ALLE.Count - 1
    5. Dim Row = CType(DG.ItemContainerGenerator.ContainerFromItem(Coll_ALLE(i)), DataGridRow)
    6. If Row IsNot Nothing Then
    7. Hoehe += Row.ActualHeight
    8. Zaehler += 1
    9. End If
    10. Next
    11. Dim Diff As Double = Hoehe - DG.ActualHeight
    12. Dim Drin As Double = (DG.ActualHeight - 30) / (Hoehe / Zaehler) '30 ist die eingestellte ColumnHeaderHeight


    So lässt sich ermitteln wie viele Items in das DataGrid passen. Wenn man den ersten und letzten Index der gerenderten Items noch erfasst lässt sich auch ermitteln, wo das Sprungziel im Verhältnis dazu liegt. Damit lässt sich dann der passende Offset ermittlen.
    Zu beachten ist auch die Tatsache, dass die gerenderten Items nicht gleich den sichtbaren sind! Durch die Virtualisierung werden Items über und unter dem sichtbaren Breich gerendert.
    Für heute langt es aber...