WP7: получить текущий PivotItem для Pivot с привязкой к данным - PullRequest
2 голосов
/ 25 января 2011

У меня есть Pivot, у которого ItemsSource установлен набор объектов данных, и я использую ItemTemplate для преобразования элементов в содержимое пользовательского интерфейса (я также использую HeaderTemplate).

При надгробии я обычнополучите ScrollViewer из текущего PivotItem и сохраните текущую позицию, чтобы я мог прокрутить назад в нужную позицию, если пользователь переместится обратно в мое приложение.Это прекрасно работает, если я жестко кодирую PivotItems в своем XAML.

Моя проблема в том, что когда Pivot привязан к моей коллекции объектов данных с помощью ItemsSource, SelectedItem возвращает один из моих объектов данных, а не PivotItem.Я не вижу, как добраться до текущего PivotItem (или элементов пользовательского интерфейса, сгенерированных из моего ItemTemplate).Я заметил, что защищенные члены переходят от элемента ItemsSource к соответствующему контейнеру - возможно, мне нужно извлечь из Pivot, чтобы использовать их?

Спасибо!

Дамиан

Ответы [ 4 ]

4 голосов
/ 12 мая 2011

Другой способ получения предмета Pivot описан здесь - http://bea.stollnitz.com/blog/?p=7

Получите ссылку на элемент управления Pivot, и затем вы можете использовать Pivot.ItemContainerGenerator.ContainerFromIndex (index), чтобы получить PivotItem, или вы можете использовать Pivot.ItemContainerGenerator.ContainerFromItem (dataobject)

3 голосов
/ 25 января 2011

Я проголосовал за ответ Дерека, так как он направил меня в правильном направлении. Метод расширения, который он предложил, углубился только на один уровень, поэтому я нашел следующий рекурсивный метод расширения, который мне подходит:

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 голосов
/ 25 января 2011

Если по какой-то причине вам нужен фактический ток 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();
1 голос
/ 25 января 2011

Почему бы не использовать свойство SelectedIndex?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...