WPF Listview - 「視野」外の項目を選択する
-
25-09-2019 - |
質問
ListView を使用してリスト内の項目を表示しています。ユーザーは自分で項目を選択することも、「事前選択キー」を使用して指定された属性を持つ項目を選択することもできます。
項目を確認するには、次のようなものを使用します。
for(int i;i<MyListView.Items.Count;++i)
{
if( /*... Check if the items should be selected ...*/ )
(MyListView.ItemContainerGenerator.ContainerFromIndex(i) as ListViewItem).IsSelected = true;
}
これは、実行時に表示される項目に対して完全に機能します。ただし、表示されていない項目の場合、ContainerFromIndex() は null を返します。これは仮想化と関係があり、リストは「視野」の上下のアイテムを認識しないと聞きました。しかし、リスト内の選択した項目を手動で選択すると、「視野」の外に項目が表示される可能性があるのはなぜでしょうか?
そして、「視野」の外でアイテムを選択するにはどうすればよいでしょうか?それはきっと可能なはずだと思います。
助けてくれてありがとう、マーク
解決
あなたが述べたように、問題はListViewアイテムの仮想化にあると思います。デフォルトでは、ListView (および ListBox) は VirtualizingStackPanel
パフォーマンスを向上させるために ItemsPanel として使用します。どのように動作するかについての簡単な説明を読むことができます ここ.
ただし、別のパネルを代用することもできます。この場合は、通常の StackPanel を使用してみてください。ListView に大量の項目がある場合、特にそれらが複雑な項目である場合、パフォーマンスが少し低下する可能性があります。
<ListView>
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
</ListView>
編集
説明されている解決策を試すこともできます この同様の質問で, 、モデルによって異なります。ただし、これはおそらくうまくいきません。
他のヒント
は、(それはAPIの他の部分の正しい動作を妨害した場合でも、時には実際には便利な機能です)仮想化を無効にする代わりに、VirtualizingPanel
を見つけて、それを明示的に伝えることですスクロールする。
void ScrollToIndex(ListBox listBox, int index)
{
VirtualizingPanel panel = FindVisualChild<VirtualizingPanel>(listBox);
panel.BringIndexIntoViewPublic(index);
}
static T FindVisualChild<T>(DependencyObject o) where T : class
{
T result = o as T;
if (result != null)
{
return result;
}
int childCount = VisualTreeHelper.GetChildrenCount(o);
for (int i = 0; i < childCount; i++)
{
result = FindVisualChild<T>(VisualTreeHelper.GetChild(o, i));
if (result != null)
{
return result;
}
}
return null;
}
私はパネルを見つけるために、ビジュアルツリーを検索する必要があると非常に満足してないんだけど、仮想パネルを扱うとき、私はそれを得るための他の方法の、また特定のインデックスへのスクロールに対応していませんよます。