Daniel Bişar
Daniel Bişar

Reputation: 2773

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...

Upvotes: 2

Views: 5423

Answers (1)

Daniel Bişar
Daniel Bişar

Reputation: 2773

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

Upvotes: 0

Related Questions