WP7:获取数据绑定Pivot的当前PivotItem

时间:2011-01-25 00:51:30

标签: windows-phone-7

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

当进行逻辑删除时,我通常从当前的PivotItem获取ScrollViewer并保存当前位置,这样如果用户导航回我的应用程序,我可以回滚到正确的位置。如果我在我的XAML中对PivotItem进行硬编码,这样可以正常工作。

我的问题是当Pivot使用ItemsSource绑定到我的数据对象集合时,SelectedItem返回我的一个数据对象 - 而不是PivotItem。我看不到如何到达当前的PivotItem(或从我的ItemTemplate生成的UI元素)。我注意到受保护的成员从ItemsSource项目转到相应的容器 - 也许我需要从Pivot派生来使用它们?

谢谢!

达米安

4 个答案:

答案 0 :(得分:4)

此处描述了获取数据透视表项的另一种方法 - http://bea.stollnitz.com/blog/?p=7

获取Pivot控件的参考,然后您可以使用Pivot.ItemContainerGenerator.ContainerFromIndex(index)tp获取PivotItem或者您可以使用Pivot.ItemContainerGenerator.ContainerFromItem(dataobject)

答案 1 :(得分:3)

我赞成Derek的答案,因为它让我朝着正确的方向前进。他建议的扩展方法只有一个层次,所以我想出了以下适用于我的递归扩展方法:

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 item = pivot.FindVisualChild<PivotItem>(
                          elt => elt.DataContext == pivot.SelectedItem);

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

答案 2 :(得分:2)

如果由于某种原因,您需要实际的当前PivotItem而不是与之关联的数据,那么我认为您需要遍历可视化树来查找它。我使用以下方法来帮助解决这个问题:

        /// <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);
            }
        }

所以你会按如下方式使用它:

var selectedPivotItem = this._pivot
    .GetVisualChildren()
    .Select(p => p.DataContext == this._pivot.SelectedItem)
    .FirstOrDefault();

答案 3 :(得分:1)

为什么不使用SelectedIndex属性?