我正在使用语义缩放控件来显示WinRT应用程序中的联系人列表。当我手动滚动列表时,我想获取视图中的当前项目(视图中将有多个项目,但我想获得最近的视图中的项目)。因此,当用户导航回此联系人列表时,我可以保存滚动位置以将其设置为原样。 有什么建议吗? 我尝试获取当前的选定索引,但在滚动列表时从未更新过:
int lastViewedItem = ((ListViewBase)this.semanticZoom.ZoomedInView).SelectedIndex;
导航回来
(ListViewBase)this.semanticZoom.ZoomedInView).SelectedIndex = lastViewedItem;
((ListViewBase)this.semanticZoom.ZoomedInView).ScrollIntoView(((ListViewBase)this.semanticZoom.ZoomedInView).SelectedItem);
答案 0 :(得分:1)
我已经为我认识here的任何已知ItemsControl
创建了一个扩展程序。
using System;
using System.Collections;
using Windows.Foundation;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
/// <summary>
/// Gets the first visible element.
/// </summary>
/// <param name="itemsControl">The ItemsControl.</param>
/// <returns>The first visible item or null if not found.</returns>
public static object GetFirstVisibleItem(this ItemsControl itemsControl)
{
var index = GetFirstVisibleIndex(itemsControl);
if (index == -1)
{
return null;
}
var list = itemsControl.ItemsSource as IList;
if (itemsControl.ItemsSource != null &&
list != null &&
list.Count > index)
{
return list[index];
}
if (itemsControl.Items != null &&
itemsControl.Items.Count > index)
{
return itemsControl.Items[index];
}
throw new InvalidOperationException();
}
/// <summary>
/// Gets the index of the first visible element.
/// </summary>
/// <param name="itemsControl">The ItemsControl.</param>
/// <returns>The index of the first visible item or -1 if not found.</returns>
public static int GetFirstVisibleIndex(this ItemsControl itemsControl)
{
// First checking if no items source or an empty one is used
if (itemsControl.ItemsSource == null)
{
return -1;
}
var enumItemsSource = itemsControl.ItemsSource as IEnumerable;
if (enumItemsSource != null && !enumItemsSource.GetEnumerator().MoveNext())
{
return -1;
}
// Check if a modern panel is used as an items panel
var sourcePanel = itemsControl.ItemsPanelRoot;
if (sourcePanel == null)
{
throw new InvalidOperationException("Can't get first visible index from an ItemsControl with no ItemsPanel.");
}
var isp = sourcePanel as ItemsStackPanel;
if (isp != null)
{
return isp.FirstVisibleIndex;
}
var iwg = sourcePanel as ItemsWrapGrid;
if (iwg != null)
{
return iwg.FirstVisibleIndex;
}
// Check containers for first one in view
if (sourcePanel.Children.Count == 0)
{
return -1;
}
if (itemsControl.ActualWidth == 0)
{
throw new InvalidOperationException("Can't get first visible index from an ItemsControl that is not loaded or has zero size.");
}
for (int i = 0; i < sourcePanel.Children.Count; i++)
{
var container = (FrameworkElement)sourcePanel.Children[i];
var bounds = container.TransformToVisual(itemsControl).TransformBounds(new Rect(0, 0, container.ActualWidth, container.ActualHeight));
if (bounds.Left < itemsControl.ActualWidth &&
bounds.Top < itemsControl.ActualHeight &&
bounds.Right > 0 &&
bounds.Bottom > 0)
{
return itemsControl.IndexFromContainer(container);
}
}
throw new InvalidOperationException();
}