J’alimente un contrôle ListBox avec un UserControl qui affiche une conversation, comme illustré sur la figure suivante :
L’idée c’est d’avoir 0% de code dans la vue, j’utilise donc le modèle MVVM mais le soucis c’est que lorsque le nombre d’éléments dépasse l’espace d’affichage de ma ListBox, aucun défilement automatique n’est effectué pour afficher le dernier élément.
Pour contourner ce problème est n’avoir toujours aucun code derrière ma vue, je suis parti sur la solution qui consiste à créer une ListBox personnalisée (qui dérive de la ListBox standard), d’implémenter une DependencyProperty qui appellera automatiquement la méthode ScrollIntoView de la ListBox .
{
publicstaticreadonlyDependencyProperty ScrollViewFromIndexProperty =
DependencyProperty.Register(
"ScrollViewFromIndex",
typeof(int),
typeof(CustomListBox), newPropertyMetadata(0, newPropertyChangedCallback(OnNewItemAdded))
);
public CustomListBox()
{
this.DefaultStyleKey = typeof(CustomListBox);
}
publicint ScrollViewFromIndex
{
get { return (int)GetValue(ScrollViewFromIndexProperty); }
set {
SetValue(ScrollViewFromIndexProperty, (int)value);
}
}
privatestaticvoid OnNewItemAdded(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
int CurrentIndex =(int)e.NewValue;
ListBox CurrentList = d asListBox;
if (CurrentList!=null)
{
CurrentList.SelectedIndex=CurrentIndex;
CurrentList.UpdateLayout();
CurrentList.ScrollIntoView(CurrentList.SelectedItem);
}
}
}
Je Bind la DependencyProperty ScrollViewFromIndexà BINDING_PROP_CURRENT_INDEX qui est elle même mis à jour à chaque fois qu’un nouvel élément est ajouté en tant que source de la ListBox.
ScrollViewFromIndex="{Binding BINDING_PROP_CURRENT_INDEX}"
publicint BINDING_PROP_CURRENT_INDEX
{
get { return m_CurrentIndex; }
set
{
this.SetProperty(ref m_CurrentIndex, value);
}
}
ObservableCollection<UserControl> m_ListMessages;
publicObservableCollection<UserControl> BINDING_PROP_LISTMESSAGES
{
get { return m_ListMessages; }
set
{
this.SetProperty(ref m_ListMessages, value);
BINDING_PROP_CURRENT_INDEX = m_ListMessages.Count - 1;
}
}
Sans doute les puristes vont râler, mais bon pour les autres une petite solution simple et rapide à mettre en œuvre et qui fonctionne également pour Windows Phone.
Eric