私のアプリケーションには、アイテムを含むListBox
があります。アプリケーションはWPFで記述されています。
最後に追加されたアイテムに自動的にスクロールするにはどうすればよいですか?新しいアイテムが追加されたときに、ScrollViewer
をリストの最後に移動する必要があります。
ItemsChanged
のようなイベントはありますか? (SelectionChanged
イベントを使用したくない)
これを試して:
lstBox.SelectedIndex = lstBox.Items.Count -1;
lstBox.ScrollIntoView(lstBox.SelectedItem) ;
MainWindowで、これはリストの最後のアイテムを選択してフォーカスします!
これを行う最も簡単な方法:
if (VisualTreeHelper.GetChildrenCount(listView) > 0)
{
Border border = (Border)VisualTreeHelper.GetChild(listView, 0);
ScrollViewer scrollViewer = (ScrollViewer)VisualTreeHelper.GetChild(border, 0);
scrollViewer.ScrollToBottom();
}
ListViewおよびListBoxコントロールに対して常に機能します。このコードをlistView.Items.SourceCollection.CollectionChanged
イベントに添付すると、完全に自動化された自動スクロールの動作が得られます。
listBox.ScrollIntoView(listBox.Items[listBox.Items.Count - 1]);
は、重複するアイテムがない場合にのみ機能することに注意してください。同じ内容のアイテムがある場合、最初の検索までスクロールダウンします。
ここに私が見つけた解決策があります:
ListBoxAutomationPeer svAutomation = (ListBoxAutomationPeer)ScrollViewerAutomationPeer.CreatePeerForElement(myListBox);
IScrollProvider scrollInterface = (IScrollProvider)svAutomation.GetPattern(PatternInterface.Scroll);
System.Windows.Automation.ScrollAmount scrollVertical = System.Windows.Automation.ScrollAmount.LargeIncrement;
System.Windows.Automation.ScrollAmount scrollHorizontal = System.Windows.Automation.ScrollAmount.NoAmount;
//If the vertical scroller is not available, the operation cannot be performed, which will raise an exception.
if ( scrollInterface.VerticallyScrollable )
scrollInterface.Scroll(scrollHorizontal, scrollVertical);
最善の解決策は、このコレクションがコンテンツビューアー向けに特別に設計されたListBoxコントロール内でItemCollectionオブジェクトを使用することです。最後のアイテムを選択し、カーソル位置の参照を保持するための事前定義されたメソッドがあります。
myListBox.Items.MoveCurrentToLast();
myListBox.ScrollIntoView(myListBox.Items.CurrentItem);
これまでに提示されたアプローチとは少し異なるアプローチ。
ScrollViewer
ScrollChanged
イベントを使用して、ScrollViewer
の内容が大きくなるのを監視できます。
private void ListBox_OnLoaded(object sender, RoutedEventArgs e)
{
var listBox = (ListBox) sender;
var scrollViewer = FindScrollViewer(listBox);
if (scrollViewer != null)
{
scrollViewer.ScrollChanged += (o, args) =>
{
if (args.ExtentHeightChange > 0)
scrollViewer.ScrollToBottom();
};
}
}
これにより、ListBox
ItemsSource
変更へのバインドに関する問題を回避できます。
ScrollViewer
は、ListBox
がデフォルトのコントロールテンプレートを使用していると仮定せずに見つけることもできます。
// Search for ScrollViewer, breadth-first
private static ScrollViewer FindScrollViewer(DependencyObject root)
{
var queue = new Queue<DependencyObject>(new[] {root});
do
{
var item = queue.Dequeue();
if (item is ScrollViewer)
return (ScrollViewer) item;
for (var i = 0; i < VisualTreeHelper.GetChildrenCount(item); i++)
queue.Enqueue(VisualTreeHelper.GetChild(item, i));
} while (queue.Count > 0);
return null;
}
次に、これをListBox
Loaded
イベントに添付します。
<ListBox Loaded="ListBox_OnLoaded" />
これは、より汎用的にするために、添付プロパティに簡単に変更できます。
listBox.ScrollIntoView(listBox.Items [listBox.Items.Count-1]);
私にとって、最も簡単な作業方法はこれでした:(バインドなし)
private void WriteMessage(string message, Brush color, ListView lv)
{
Dispatcher.BeginInvoke(new Action(delegate
{
ListViewItem ls = new ListViewItem
{
Foreground = color,
Content = message
};
lv.Items.Add(ls);
lv.ScrollIntoView(lv.Items[lv.Items.Count - 1]);
}));
}
クラスを作成したり、xamlを変更したりする必要はありません。このメソッドでメッセージを書き込むだけで、自動的にスクロールします。
ただ電話する
myLv.Items.Add(ls);
myLv.ScrollIntoView(lv.Items[lv.Items.Count - 1]);
たとえば、私のために動作しないでください。
ListBox.ScrollIntoView() メソッドを試すことができますが、いくつかのケースでは 問題 があります...
Tamir Khasonの例を次に示します。 WPFの自動スクロールListBox