ListView ScrollToBottom DependencyProperty

  • WPF

Es gibt 6 Antworten in diesem Thema. Der letzte Beitrag () ist von seh.

    ListView ScrollToBottom DependencyProperty

    Hallo zusammen, hallo @Nofear23m

    ich bin mich aktuell aufgrund meines Projekts mit Dependency- Objects und Properties am rumschlagen.

    Ich versuche gerade eine "AttachedProperty" zu erstellen die sich "AlwaysScrollToBottom" nennt. Das ist meine absolut erste eigene Dependency Property die ich für das ListView erstellen will.
    Und zwar nervt mich aktuell, dass Items die zur ListView mittels DataBinding hinzugefügt werden, immer unten angehängt aber dann die ListView nicht auf das letzten Item scrollt.

    Da dachte ich, dass muss mit einer DependencyProperty zu lösen sein und bin auf einen wahrscheinlich total veralteten Blogeintrag gestoßen an dem ich dann mal etwas getüftelt habe.
    Ich habe mich etwas daran orientiert, stoße aber auf ein Problem. Mein aktuelle Klasse sieht wie folgt aus:

    C#-Quellcode

    1. public class ListViewScrollToBottomBehaviour : DependencyObject
    2. {
    3. public bool AlwaysScrollToBottom
    4. {
    5. get { return (bool)GetValue(AlwaysScrollToBottomProperty); }
    6. set { SetValue(AlwaysScrollToBottomProperty, value); }
    7. }
    8. public static bool GetAlwaysScrollToBottom(ListView listView)
    9. {
    10. return (bool)listView.GetValue(AlwaysScrollToBottomProperty);
    11. }
    12. public static void SetAlwaysScrollToBottom(ListView listView, bool value)
    13. {
    14. listView.SetValue(AlwaysScrollToBottomProperty, value);
    15. }
    16. public static readonly DependencyProperty AlwaysScrollToBottomProperty =
    17. DependencyProperty.RegisterAttached(
    18. "AlwaysScrollToBottom",
    19. typeof(bool),
    20. typeof(ListViewScrollToBottomBehaviour),
    21. new PropertyMetadata(false, AlwaysScrollToBottomPropertyChanged));
    22. private static void AlwaysScrollToBottomPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    23. {
    24. var listview = d as ListView;
    25. if (listview == null || e.NewValue == null) return;
    26. var collection = listview.ItemsSource as INotifyCollectionChanged;
    27. if (collection != null)
    28. {
    29. collection.CollectionChanged += (s, args) =>
    30. {
    31. var scrollViewer = listview.GetFirstDescendantOfType<ScrollViewer>();
    32. scrollViewer.ScrollToVerticalOffset(scrollViewer.ActualHeight);
    33. };
    34. }
    35. }
    36. }


    Ich weiß, dass die Bedingung von ScrollToBottom nocht fehlt, aber das scrollen nach unten ist gerade mein dringenderes Problem.

    In meiner MainWindow.xaml sieht die ListView so aus:

    XML-Quellcode

    1. <ListView Grid.Row="0" Grid.Column="0" ItemsSource="{Binding DataPackets}" SelectedItem="{Binding SelectedDataPacket, Mode=OneWayToSource}" bh:ListViewScrollToBottomBehaviour.AlwaysScrollToBottom="True" >
    2. <ListView.ItemTemplate>
    3. <DataTemplate>
    4. <WrapPanel>
    5. <TextBlock Text="Origin: " />
    6. <TextBlock Text="{Binding Origin}" FontWeight="Bold" />
    7. <TextBlock Text=" Type: " />
    8. <TextBlock Text="{Binding PacketType}" FontWeight="Bold" />
    9. <TextBlock Text=" Cmd: " />
    10. <TextBlock Text="{Binding Cmd}" FontWeight="Bold" />
    11. </WrapPanel>
    12. </DataTemplate>
    13. </ListView.ItemTemplate>
    14. </ListView>


    Leider funktioniert es noch nicht wie ich will. Ich habe dann mal einen Breakpoint gesetzt in die AlwaysScrollToBottomPropertyChanged von meiner Klasse, dort ist die ItemsSource null.
    Kann es sein, dass die ItemsSource DependencyProperty erst nach meiner Property gesetzt wird? Oder habe ich grundsätzlich mit dem DependencyObject etwas falsch verstanden?

    Danke im Voraus
    Hallo seh

    Das hatten wir vor kurzem schon mal.
    Das problem (oder eigentlich nicht Problem, denn das ist ja gut so) die Virtualisierung von Items. Zumindest wenn das Panel der ListBox ein VirtualizingStackPanel ist, was per Default der Fall ist.

    Schau mal hier: Datagrid scrollintoview im viewmodel gesetzt.
    Da habeich das beschrieben. Das kann auch für ein Attached Property angewandt werden.

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Hallo @Nofear23m

    also du hast mir jetzt wahrscheinlich schon das nächste Problem vorweg beschrieben was aufgetreten wäre.
    Ich hatte erstmal Schwierigkeiten zu verstehen, warum die ItemsSource in AlwaysScrollToBottomPropertyChanged null ist, obwohl die im XAML gebunden wird.

    Es ist definitiv die richtige ListView, weil ich ihr testweise mal einen Namen gegeben habe (in XAML) und an dem Übergabeparameter d der Funktion konnte ich dann den exakt gleichen Namen rauslesen.
    Dennoch ist das ItemsSource Property null.
    Ich habe die Befürchtung, dass meine AttachedProperty zuerst getriggert wird und danach erst das ItemsSource gesetzt wird? Aber das wäre ja total ungünstig, gibt es da eine Lösung für?

    Grüße seh
    Hallo

    Achso, OK. Weis schon was du meinst. Erstmal schau dir den Unterschied zweischen ItemsSource und Items an. Ich weis, kann am Anfang verwirrend sein.
    Folgendes sollte klappen:

    C#-Quellcode

    1. private static void AlwaysScrollToBottomPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    2. {
    3. if ((bool)e.NewValue)
    4. {
    5. var listview = d as ListView;
    6. if (listview != null)
    7. {
    8. var collection = (INotifyCollectionChanged)listview.Items;
    9. collection.CollectionChanged += (s, args) =>
    10. {
    11. listview.Items.MoveCurrentToLast();
    12. listview.SelectedItem = listview.Items.CurrentItem;
    13. listview.ScrollIntoView(listview.SelectedItem);
    14. };
    15. }
    16. }
    17. }


    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    Was funzt denn nicht? In welcher Zeile schetert es?

    Falls was nicht funzt poste immer den aktuellen Code inkl. XAML!!

    Grüße
    Sascha
    If _work = worktype.hard Then Me.Drink(Coffee)
    Seht euch auch meine Tutorialreihe <WPF Lernen/> an oder abonniert meinen YouTube Kanal.

    ## Bitte markiere einen Thread als "Erledigt" wenn deine Frage beantwortet wurde. ##

    @Nofear23m

    Ich hab gestern aufgehört, heute PC wieder angemacht, und plötzlich hat es funktioniert ohne das ich nur irgendwelchen Code angefasst habe. Soo komisch..
    Er hat gestern einfach nicht mehr den Breakpoint am Anfang der Callback Funktion erreicht, als würde das Property nie geändert worden sein.
    Heut PC wieder angemacht, und siehe da, Breakpoint wird gehittet und gescrollt wird auch nach unten.

    Läuft jetz soweit erstmal.