Search code examples
wpftreeviewselectionitemscontrol

WPF ItemsControl get container from data object (TreeView, Multiselect)


How can I get the Container for an object in WPF ItemsControl.

I am writing a multiselect treeview with bindable SelectedItem und SelectedItems Dependency Properties. So long everything works just fine. The only thing is, when I click on an item in the tree with pressed ctrl a second time this item should not be selected but the last previous selected item. The TreeView contains a private Method called ChangeSelection. As far as i understand the first parameter is the Container, the second is the TreeViewItem and the last wherether the item shall be selected or not.

I implement the multiselection with catching the SelectedItemChanged event.

This code works for the new selected item

private void OnSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
    var view = ItemContainerGenerator.ContainerFromItem(e.NewValue) as TreeViewItem;
    // ...
}

BUT if i want to get the TreeViewItem from an item saved in an ObservableCollection... it will not work.

EDIT: Ok, as i found out. The code above works only for the first level of items...


Solution

  • EDIT: The solution for this problem isn't trivial. It is possible to find the selected treeview item by using a viewmodel (f.e. an interface which provides basics like: IsSelected, IsExpanded, IsEnabled and Parent). You can search the TreeViewItem like this:

    if (treeViewItem.ItemContainerGenerator.Status != GeneratorStatus.ContainersGenerated)
    {
        EventHandler eventHandler = null;
    
        eventHandler = delegate
        {
            treeViewItem.ItemContainerGenerator.StatusChanged -= eventHandler;
            // Call the search function recursive XYZ(tree, treeViewItem.ItemContainerGenerator.ContainerFromItem(nextLevelItem) as TreeViewItem);
        };
    
        // wait for the containers to be generated
        treeViewItem.ItemContainerGenerator.StatusChanged += eventHandler;
    }
    else
    {
        // Call the search function recursive XYZ(tree, treeViewItem.ItemContainerGenerator.ContainerFromItem(nextLevelItem) as TreeViewItem);
    }