私の項目がListBox
UI で正しく表示されることを確認したいと思います。これを行う 1 つの方法はListBox
、ビジュアル ツリー内の のすべての子を調べてテキストを取得し、それを期待するテキストと比較することだと考えました。
このアプローチの問題点は、内部的ListBox
に a を使用しVirtualizingStackPanel
てアイテムを表示するため、表示されているアイテムのみが作成されることです。私は最終的にクラスに出くわしましたItemContainerGenerator
。これは、指定された項目のビジュアル ツリーにコントロールを作成するように WPF に強制するように見えます。残念ながら、それは私にいくつかの奇妙な副作用を引き起こしています. のすべてのアイテムを生成するコードは次のListBox
とおりです。
List<string> generatedItems = new List<string>();
IItemContainerGenerator generator = this.ItemsListBox.ItemContainerGenerator;
GeneratorPosition pos = generator.GeneratorPositionFromIndex(-1);
using(generator.StartAt(pos, GeneratorDirection.Forward))
{
bool isNewlyRealized;
for(int i = 0; i < this.ItemsListBox.Items.Count; i++)
{
isNewlyRealized = false;
DependencyObject cntr = generator.GenerateNext(out isNewlyRealized);
if(isNewlyRealized)
{
generator.PrepareItemContainer(cntr);
}
string itemText = GetControlText(cntr);
generatedItems.Add(itemText);
}
}
(必要に応じて のコードを提供できますがGetItemText()
、 が見つかるまでビジュアル ツリーをトラバースするだけTextBlock
です。アイテムにテキストを含める方法は他にもあると思いますが、アイテムを取得したら修正します。世代は正常に動作しています。)
私のアプリでItemsListBox
は、最初に表示される最初の 12 項目で、20 項目が含まれています。最初の 14 項目のテキストは正しいです (それらのコントロールが既に生成されている可能性があります)。ただし、項目 15 ~ 20 については、テキストがまったく表示されません。さらに、一番下までスクロールすると、ItemsListBox
項目 15 ~ 20 のテキストも空白になります。したがって、何らかの方法でコントロールを生成するための WPF の通常のメカニズムに干渉しているようです。
私は何を間違っていますか?ItemsControl
アイテムを強制的にビジュアル ツリーに追加する別の/より良い方法はありますか?
更新:修正方法はわかりませんが、これが発生する理由はわかったと思います。PrepareItemContainer()
への呼び出しにより、アイテムを表示するために必要なコントロールが生成され、コンテナーがビジュアル ツリーの正しい場所に追加されると仮定しました。これらのことのいずれも行っていないことが判明しました。コンテナは、下にスクロールして表示するまで追加されません。ItemsControl
その時点では、コンテナ自体(つまりListBoxItem
)のみが作成されます-その子は作成されません(ここにいくつかのコントロールが追加され、そのうちの1つがアイテムのTextBlock
テキストを表示します)。
結果に渡したコントロールのビジュアル ツリーをトラバースするとPrepareItemContainer()
、結果は同じになります。どちらの場合も、 のみListBoxItem
が作成され、その子は作成されません。
ListBoxItem
をビジュアル ツリーに追加する良い方法が見つかりませんでした。ビジュアル ツリーでを見つけましたVirtualizingStackPanel
が、そのChildren.Add()
結果を で呼び出します ( の項目を生成するため、InvalidOperationException
項目を に直接追加することはできません)。テストとして、リフレクションを使用して呼び出してみましたが(保護されているため)、それも機能しませんでした。ItemPanel
ItemsControl
AddVisualChild()