Windows phone 7 WP7:获取数据绑定透视的当前透视项

Windows phone 7 WP7:获取数据绑定透视的当前透视项,windows-phone-7,Windows Phone 7,我有一个Pivot,其ItemsSource设置为数据对象的集合,我使用ItemTemplate将项目转换为UI内容,我还使用HeaderTemplate 在进行逻辑删除时,我通常从当前数据透视项获取ScrollViewer并保存当前位置,这样,如果用户导航回我的应用程序,我就可以滚动回正确的位置。如果我在我的XAML中硬编码数据透视项,这就可以了 我的问题是,当使用ItemsSource将数据透视绑定到我的数据对象集合时,SelectedItem会返回我的一个数据对象,而不是数据透视项。我看不

我有一个Pivot,其ItemsSource设置为数据对象的集合,我使用ItemTemplate将项目转换为UI内容,我还使用HeaderTemplate

在进行逻辑删除时,我通常从当前数据透视项获取ScrollViewer并保存当前位置,这样,如果用户导航回我的应用程序,我就可以滚动回正确的位置。如果我在我的XAML中硬编码数据透视项,这就可以了

我的问题是,当使用ItemsSource将数据透视绑定到我的数据对象集合时,SelectedItem会返回我的一个数据对象,而不是数据透视项。我看不到如何访问当前数据透视项或从ItemTemplate生成的UI元素。我注意到受保护的成员从ItemsSource项转到其相应的容器-也许我需要从Pivot派生来利用这些

谢谢


Damian

为什么不使用SelectedIndex属性?

如果出于某种原因,您需要的是实际的当前数据透视项,而不是与之关联的数据,那么我认为您需要遍历可视化树才能找到它。我使用以下方法对此有所帮助:

        /// <summary>
        /// Gets the visual children of type T.
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="target"></param>
        /// <returns></returns>
        public static IEnumerable<T> GetVisualChildren<T>(this DependencyObject target)
            where T : DependencyObject
        {
            return GetVisualChildren(target).Where(child => child is T).Cast<T>();
        }


        /// <summary>
        /// Get the visual tree children of an element.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <returns>The visual tree children of an element.</returns>
        /// <exception cref="T:System.ArgumentNullException">
        /// <paramref name="element"/> is null.
        /// </exception>
        public static IEnumerable<DependencyObject> GetVisualChildren(this DependencyObject element)
        {
            if (element == null)
            {
                throw new ArgumentNullException("element");
            }

            return GetVisualChildrenAndSelfIterator(element).Skip(1);
        }

        /// <summary>
        /// Get the visual tree children of an element and the element itself.
        /// </summary>
        /// <param name="element">The element.</param>
        /// <returns>
        /// The visual tree children of an element and the element itself.
        /// </returns>
        private static IEnumerable<DependencyObject> GetVisualChildrenAndSelfIterator(this DependencyObject element)
        {
            Debug.Assert(element != null, "element should not be null!");

            yield return element;

            int count = VisualTreeHelper.GetChildrenCount(element);
            for (int i = 0; i < count; i++)
            {
                yield return VisualTreeHelper.GetChild(element, i);
            }
        }

我对德里克的回答投了更高的票,因为它让我走上了正确的方向。他建议的扩展方法只深入了一个层次,因此我提出了以下适合我的递归扩展方法:

internal static T FindVisualChild<T>(this DependencyObject parent,
                                    Func<T, bool> filter)
                                    where T : DependencyObject
{
    var childCount = VisualTreeHelper.GetChildrenCount(parent);
    for (var i = 0; i < childCount; i++)
    {
        var elt = VisualTreeHelper.GetChild(parent, i);
        if (elt is T && filter((T)elt)) return (T)elt;
        var result = FindVisualChild(elt, filter);
        if (result != null) return result;
    }
    return null;
}
然后我使用它如下:

var selectedPivotItem = this._pivot
    .GetVisualChildren()
    .Select(p => p.DataContext == this._pivot.SelectedItem)
    .FirstOrDefault();
var item = pivot.FindVisualChild<PivotItem>(
                          elt => elt.DataContext == pivot.SelectedItem);

这种方法只是对德里克的一种改进——对他来说都是荣誉。

另一种获得关键项目的方法在这里描述-


获取对Pivot控件的引用,然后可以使用Pivot.ItemContainerGenerator.ContainerFromIndexindex tp获取PivotItem,或者可以使用Pivot.ItemContainerGenerator.ContainerFromItemdataobject

在XAML中指定PivotItems时起作用,但如果将ItemsSource绑定到数据集合,然后,Items集合包含您的数据对象,而不是PivotItems。这看起来很完美,感谢-我没有想到遍历可视化树以查找其数据上下文包含所选项的对象。当我运行它时,它不太起作用-PivotItems不是可视化树中Pivot的第一级子项。我已经把你的建议作为一个单独的答案贴了出来,非常感谢你为我指明了正确的方向。[顺便说一句,我认为您使用了Select而不是Where,尽管您可以将过滤器放在FirstOrDefault-.GetVisualChildren.FirstOrDefaultp=>p.DataContext==this.\u pivot.SelectedItem]-1中,因为虽然这通常是正确的,但您必须注意,从WPF的一开始,ItemsControl倾向于具有ItemContainerGenerator属性,该属性仅用于dataitemlogicalindexvisualitem映射!!我相信在Silverlight工具包中可以找到所有这样的扩展方法,如果我没记错的话,它们在WP7下也能像charm一样工作。这些不仅仅是寻找孩子或祖先。我也看过一些linq到可视化树的兄弟项目,你可能想看看!Pivot.ItemContainerGenerator.ContainerFromIndex0出于某种奇怪的原因为我返回null。。。