如何判断ItemsRepeater中已实现(非虚拟化)的项?是否仅能使用TryGetElement?
确定ItemsRepeater中已实现(非虚拟化)项的方案
你提到的遍历索引并调用ItemsRepeater.TryGetElement判断返回值是可行的,但并非唯一方案,根据使用场景不同,还有更高效的实现方式:
方案1:遍历+TryGetElement(单次查询场景)
逻辑简单直接,适合只需要一次性获取已实现项的场景:
- 遍历
ItemsSourceView的所有索引 - 对每个索引调用
TryGetElement,返回非null的元素即为已实现项 - 收集后取最后一个元素(最右侧)执行聚焦
var realizedItems = new List<UIElement>(); var itemsView = myItemsRepeater.ItemsSourceView; for (int i = 0; i < itemsView.Count; i++) { if (myItemsRepeater.TryGetElement(i, out var element)) { realizedItems.Add(element); } } // 聚焦最右侧已实现项 if (realizedItems.Any()) { realizedItems.Last().Focus(FocusState.Programmatic); }
方案2:事件维护实时集合(频繁查询场景)
如果需要多次获取已实现项,通过订阅ItemsRepeater的生命周期事件维护集合,能避免重复遍历,效率更高:
- 订阅
ElementPrepared:项被虚拟化加载时加入集合 - 订阅
ElementCleared:项被虚拟化回收时移除集合 - 随时从集合中取最后一个元素聚焦
private readonly List<UIElement> _realizedElements = new List<UIElement>(); // 初始化时绑定事件 myItemsRepeater.ElementPrepared += (s, e) => _realizedElements.Add(e.Element); myItemsRepeater.ElementCleared += (s, e) => _realizedElements.Remove(e.Element); // 聚焦最右侧项的方法 private void FocusRightmostRealizedItem() { if (_realizedElements.Any()) { _realizedElements.Last().Focus(FocusState.Programmatic); } }
注意事项
- 若使用横向布局(如
StackLayout设置Orientation="Horizontal"),集合的最后一个元素就是视觉上的最右侧项;如果是复杂布局,可能需要根据元素的实际坐标排序后再选取。 - 调用
Focus时,确保元素处于可聚焦状态(如设置IsTabStop="True")。
内容的提问来源于stack exchange,提问作者citelao
相关产品推荐
相关产品推荐

