0

Donc, j'ai un listview et je le veux quand un élément est créé pour faire défiler vers cet élément (en bas). Parce que j'utilise MVVM, j'ai trouvé une très bonne explication sur la façon de créer un nouveau contrôle héritant de listview qui défile vers le bas. Le problème est que this answer (the third) fait référence à WPF il y a 6 ans. Je crée une application UWP, j'ai donc copié le code et essayé de le mettre en forme selon mes besoins. Le code suivant ne donne aucune erreur ou exception mais à la place il charge le "ChatListView" comme je l'appelle parfaitement et puis ne fait rien. Les commentaires sont seulement un peu modifiés par rapport au code original.UWP Custom ListView pour faire défiler vers le bas

Que puis-je faire? Merci d'avance!

public class ChatListView : ListView 
{ 
    //Define the AutoScroll property. If enabled, causes the ListBox to scroll to 
    //the last item whenever a new item is added. 
    public static readonly DependencyProperty AutoScrollProperty = 
     DependencyProperty.Register(
      "AutoScroll", 
      typeof(Boolean), 
      typeof(ChatListView), 
      new PropertyMetadata(
       true, //Default value. 
       new PropertyChangedCallback(AutoScroll_PropertyChanged))); 

    //Gets or sets whether or not the list should scroll to the last item 
    //when a new item is added. 
    public bool AutoScroll 
    { 
     get { return (bool)GetValue(AutoScrollProperty); } 
     set { SetValue(AutoScrollProperty, value); } 
    } 

    //Event handler for when the AutoScroll property is changed. 
    //This delegates the call to SubscribeToAutoScroll_ItemsCollectionChanged(). 
    //d = The DependencyObject whose property was changed.</param> 
    //e = Change event args.</param> 
    private static void AutoScroll_PropertyChanged(
     DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     SubscribeToAutoScroll_ItemsCollectionChanged(
      (ChatListView)d, 
      (bool)e.NewValue); 
    } 

    //Subscribes to the list items' collection changed event if AutoScroll is enabled. 
    //Otherwise, it unsubscribes from that event. 
    //For this to work, the underlying list must implement INotifyCollectionChanged. 
    // 
    //(This function was only creative for brevity) 

    //listBox = The list box containing the items collection. 
    //subscribe = Subscribe to the collection changed event? 
    private static void SubscribeToAutoScroll_ItemsCollectionChanged(
     ChatListView listView, bool subscribe) 
    { 
     INotifyCollectionChanged notifyCollection = 
      listView as INotifyCollectionChanged; 
     if (notifyCollection != null) 
     { 
      if (subscribe) 
      { 
       //AutoScroll is turned on, subscribe to collection changed events. 
       notifyCollection.CollectionChanged += 
        listView.AutoScroll_ItemsCollectionChanged; 
      } 
      else 
      { 
       //AutoScroll is turned off, unsubscribe from collection changed events. 
       notifyCollection.CollectionChanged -= 
        listView.AutoScroll_ItemsCollectionChanged; 
      } 
     } 
    } 

    //Event handler called only when the ItemCollection changes 
    //and if AutoScroll is enabled. 

    //sender = The ItemCollection. 
    //e = Change event args. 
    private void AutoScroll_ItemsCollectionChanged(
     object sender, NotifyCollectionChangedEventArgs e) 
    { 
     if (e.Action == NotifyCollectionChangedAction.Add) 
     { 
      int count = Items.Count; 
      ScrollIntoView(Items[count - 1]); 
     } 
    } 

    //Constructor a new ChatListView. 
    public ChatListView() 
    { 
     //Subscribe to the AutoScroll property's items collection 
     //changed handler by default if AutoScroll is enabled by default. 
     SubscribeToAutoScroll_ItemsCollectionChanged(
      this, (bool)AutoScrollProperty.GetMetadata(typeof(ChatListView)).DefaultValue); 
    } 
} 

Répondre

4

Si vous souhaitez créer une application de chat, vous pouvez utiliser la ItemsUpdatingScrollMode propriété particulière de ItemsStackPanel à KeepLastItemInView valeur pour faire défiler le dernier élément.

Utilisation:

<ListView> 
    <ListView.ItemsPanel> 
     <ItemsPanelTemplate> 
      <ItemsStackPanel ItemsUpdatingScrollMode="KeepLastItemInView" /> 
     </ItemsPanelTemplate> 
    </ListView.ItemsPanel> 
</ListView> 

Note: KeepLastItemInView membre enum a été introduit dans le SDK 14393.

Lien connexe: https://docs.microsoft.com/en-us/uwp/api/Windows.UI.Xaml.Controls.ItemsStackPanel#properties_

+2

qui est encore plus que ce que je demandais ... Il ne défile pas seulement vers le bas lorsque vous ajoutez quelque chose sur la liste, mais aussi si vous n'êtes pas à la visualisation le dernier élément (par exemple si vous voulez regarder les messages précédents), il ne défile pas vers le bas. Parfait!!! – KonKarapas

1

La réponse acceptée est assez agréable. Cependant, il y a une chose qu'il ne fera pas (du moins si je copie et collez simplement le XAML ci-dessus): il ne fera pas son scrolling intentionnel si, disons, l'utilisateur était absent de cette page pendant que de nouveaux éléments étaient ajoutés, et alors ils ont navigué à la page.

Pour que je devais accrocher dans

protected override void OnNavigatedTo(NavigationEventArgs e) 
{ 
    base.OnNavigatedTo(e); 

    if (MyListView.Items.Count == 0) 
     return; 

    object lastItem = MyListView.Items[MyListView.Items.Count - 1]; 
    MyListView.ScrollIntoView(lastItem); 
}