Как получить ListView из ListViewItem?

У меня есть ListViewItem, который добавлен в ListView, но я не знаю, к какому ListView он добавлен.

Я хотел бы (через ListViewItem), чтобы иметь возможность получить ListView из самого элемента.

Я попытался использовать свойство Parent, но по какой-то причине он возвращает StackPanel.

Есть идеи?

4 ответа

Решение

Я получил это для запуска и работы:

private void Window_Loaded(object s, RoutedEventArgs args)
    {
        var collectionview = CollectionViewSource.GetDefaultView(this.listview.Items);
        collectionview.CollectionChanged += (sender, e) =>
        {
            if (e.NewItems != null && e.NewItems.Count > 0)
            {                   
                var added = e.NewItems[0];
                ListViewItem item = added as ListViewItem;
                ListView parent = FindParent<ListView>(item);
            }
        };

    }   
    public static T FindParent<T>(FrameworkElement element) where T : FrameworkElement
    {
        FrameworkElement parent = LogicalTreeHelper.GetParent(element) as FrameworkElement;

        while (parent != null)
        {
            T correctlyTyped = parent as T;
            if (correctlyTyped != null)
                return correctlyTyped;
            else
                return FindParent<T>(parent);
        }

        return null;
    }

Хотя это довольно старый вопрос, он не работает для WinRT

Для WinRT вам нужно пройти по дереву визуалов, используя VisualTreeHelper вместо LogicalTreeHelper, чтобы найти ListView из ListViewItem

Я недавно обнаружил это краткое решение:

ListView listView = ItemsControl.ItemsControlFromItemContainer(listViewItem) as ListView;

Я использую подход, отличный от тех, которые уже были предложены.

У меня есть только несколько элементов управления ListView (два или три), поэтому я могу сделать следующее.

ListViewItem listViewItem = e.OriginalSource as ListViewItem;
if (listViewItem == null)
{
    ...
}
else
{
    if (firstListView.ItemContainerGenerator.IndexFromContainer(listViewItem) >= 0)
    {
        ...
    }
    else if (secondListView.ItemContainerGenerator.IndexFromContainer(listViewItem) >= 0)
    {
        ...
    }
}

Это можно использовать с циклом foreach, но если для итерации используются сотни элементов управления ListView, то поиск родительского ListView объекта ListViewItem, вероятно, более эффективен (как предполагает большинство других ответов). Однако я думаю, что мое решение чище (немного). Надеюсь, это поможет кому-то!

Другие вопросы по тегам