はじめに
WPFでListBoxをログ表示などに使っているとき、BindingしているItemsSource
に新しいアイテムが追加されたら、その行を表示する方法です。
簡単な説明
基本的にビューの動きだけの問題なので、ViewのXAMLとコードビハインドだけでやります。
リストボックスを特定のアイテムの位置までスクロールさせるにはListBox.ScrollIntoView(object)
を使います。引数には画面上に表示したいリストボックスのアイテムを指定します。
まず、ItemsSource
にバインドするコレクションはObservableCollection(T)
クラス(INotifyCollectionChanged
インターフェースを実装しているクラス)を利用します。
BindingするときにNotifyOnTargetUpdated
をTrue
にし、TargetUpdated
イベントにハンドラを設定します。
このイベントはあくまでItemsSource
が更新されたときに発生するものなので、その中身が変化したときには発生しません。
そのため、TargetUpdated
でItemsSource
のコレクションのCollectionChanged
イベントに対してハンドラを設定し、そこでListBox.ScrollIntoView(object)
を呼び出しています。
ソースコード
XAML
<ListBox x:Name="listBox" ItemsSource="{Binding Items, Mode=OneWay, UpdateSourceTrigger=PropertyChanged, NotifyOnTargetUpdated=True}" TargetUpdated="ListBox_TargetUpdated"/>
Code Behind (C#)
private void ListBox_TargetUpdated(object sender, DataTransferEventArgs e)
{
(listBox.ItemsSource as INotifyCollectionChanged).CollectionChanged += new NotifyCollectionChangedEventHandler(listBox_CollectionChanged);
}
void listBox_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
this.listBox.ScrollIntoView(this.listBox.Items[this.listBox.Items.Count - 1]);
}