virtualizingstackpanel が、可視アイテムの周りにアイテムを視覚化することを決定する際に考慮する要因は何ですか?
例: リストビューがある場合、アイテム 7 を表示すると、アイテム 6 と 8 も表示されますが、表示されません。
視覚化されたアイテムのみが視覚化されるように、視覚化されたアイテムを制限するにはどうすればよいですか?
virtualizingstackpanel が、可視アイテムの周りにアイテムを視覚化することを決定する際に考慮する要因は何ですか?
例: リストビューがある場合、アイテム 7 を表示すると、アイテム 6 と 8 も表示されますが、表示されません。
視覚化されたアイテムのみが視覚化されるように、視覚化されたアイテムを制限するにはどうすればよいですか?
仮想化は非常に複雑なテーマですが、それについて詳しく説明している本があります。さらに、この本では、目標を達成するために実装する必要があるカスタム仮想化を実装する方法についても説明します。幸いなことに、誰かがこの本の PDF をオンラインに投稿していることがわかりました。このリンクをクリックすると、それを見つけることができます。
仮想化のセクションは 129 ページから始まりますが、非常に興味深い内容が含まれているため、残りの部分も読む価値があります。
関数をオーバーライドすることで問題を解決しMeasureOverride
ました。仮想化の章に応じて、シェリダンが彼の回答で言及した本をすでに購入しました。拡張するクラスに対して行ったことは次のVirtualizingStackPanel
とおりです。
private ItemsControl ItemsOwner { get; set; }
private int StartIndex { get; set; }
private int EndIndex { get; set; }
protected override void OnInitialized(EventArgs e)
{
ItemsOwner = ItemsControl.GetItemsOwner(this) as ItemsControl;
}
protected override Size MeasureOverride(Size availableSize)
{
ItemsControl itemsControl = ItemsControl.GetItemsOwner(this);
// we can set StartIndex& EndIndex to mimic
// VirtualizingStackPanel.CacheSize in .Net 4.5
// for my problem, I just fixed them at the index of item to be shown
StartIndex = PagesView.Instance.SelectedIndex;
EndIndex = StartIndex;
// Virtualize items
IItemContainerGenerator generator = ItemsOwner.ItemContainerGenerator;
GeneratorPosition startPos = generator.GeneratorPositionFromIndex(StartIndex);
int childIndex = startPos.Offset == 0 ? startPos.Index : startPos.Index + 1;
using (generator.StartAt(startPos, GeneratorDirection.Forward, true))
{
for (int i = StartIndex; i <= EndIndex; i++, childIndex++)
{
bool isNewlyRealized;
UIElement child = generator.GenerateNext(out isNewlyRealized) as UIElement;
if (isNewlyRealized)
{
if (childIndex >= InternalChildren.Count)
{
AddInternalChild(child);
}
else
{
InsertInternalChild(childIndex, child);
}
generator.PrepareItemContainer(child);
}
}
}
//DumpGeneratorContent();
// Measure
foreach (UIElement child in InternalChildren)
{
child.Measure(availableSize);
}
// Clean up
CleanupItems();
return availableSize;
}
private void CleanupItems()
{
IItemContainerGenerator generator = ItemsOwner.ItemContainerGenerator;
for (int i = InternalChildren.Count - 1; i >= 0; i--)
{
GeneratorPosition position = new GeneratorPosition(i, 0);
int itemIndex = generator.IndexFromGeneratorPosition(position);
if (itemIndex < StartIndex || itemIndex > EndIndex)
{
generator.Remove(position, 1);
RemoveInternalChildRange(i, 1);
}
}
}