James Joshua Street
James Joshua Street

Reputation: 3409

WPF how do i get the selected treeviewitem on selecteditemchanged event?

The sender of the event is the object inside the treeviewitem. However, it's not a dependencyobject so I don't think I can use ItemFromContainer to get the actual TreeViewItem. What should I do to get the actual treeviewitem that is selected?

i see that everyone is as confused by my question as I am by my problem.

according to the linked site, I can get my treeviewitem from the selecteditem property. However, when I attempt to do this I get null because the sender is a SignalViewModel object instead of a TreeViewItem.

TreeViewItem treeViewItem = this.AvailableSignalsTreeView.SelectedItem as TreeViewItem;

this returns null for me but the debugger shows that the selected item is of type SignalViewModel.

All I'm trying to do is get multiselect capability for a treeview, which I was going to do using an example I saw that just toggles the treeviewitems.

 <TreeView
        Grid.Row="0"
        Background="Blue"
        Foreground="Orange"
        x:Name="AvailableSignalsTreeView"
        SelectedItemChanged="AvailableSignalsTreeView_SelectedItemChanged"
        ItemsSource="{Binding Source={StaticResource available_signals_source}}"
        >

        <TreeView.CommandBindings>
          <CommandBinding Command="ApplicationCommands.SelectAll"
                          Executed="AvailableSignalsTreeView_SelectAll"
                          CanExecute="AvailableSignalsTreeView_SelectAllCanExecute"/>
        </TreeView.CommandBindings>
        <TreeView.InputBindings>
          <KeyBinding
            Command="ApplicationCommands.SelectAll"
            Modifiers="Ctrl"
            Key="A"
            />
        </TreeView.InputBindings>
        <TreeView.ItemTemplate>
          <HierarchicalDataTemplate ItemsSource ="{Binding Path = bits}" >
            <TextBlock
                Text="{Binding Path = SignalName}" 
                />
            <HierarchicalDataTemplate.ItemTemplate>
                      <DataTemplate>
                        <TextBlock
                          Text="{Binding Path = BitNumber}" 
                          />
                      </DataTemplate>
                    </HierarchicalDataTemplate.ItemTemplate>
          </HierarchicalDataTemplate>
        </TreeView.ItemTemplate>
        <TreeView.ContextMenu>
          <ContextMenu>
            <MenuItem Header="Add Bits to Signal" Click="AddBitToSignal" />
          </ContextMenu>
        </TreeView.ContextMenu>
      </TreeView>

Upvotes: 0

Views: 2600

Answers (2)

James Joshua Street
James Joshua Street

Reputation: 3409

I think what I was thinking of is this. Basically the selected item isn't a dependency object so I can't traverse the tree using them, and I have to instead get the container using the itemcontainer generator.

I thought I tried this yesterday, not sure why it wasn't working.

TreeViewItem tvi = tv.ItemContainerGenerator.ContainerFromItem(tv.SelectedItem) as TreeViewItem;  

Upvotes: 0

Marius Bancila
Marius Bancila

Reputation: 16318

Try this:

// Helper to search up the VisualTree
private static T FindAnchestor<T>(DependencyObject current)
    where T : DependencyObject
{
   do
   {
      if (current is T)
      {
         return (T)current;
      }
      current = VisualTreeHelper.GetParent(current);
   }
   while (current != null);
   return null;
}

private void AvailableSignalsTreeView_SelectedItemChanged(
    object sender,
    RoutedPropertyChangedEventArgs<Object> e)
{
    var treeViewItem = FindAnchestor<TreeViewItem>((DependencyObject)e.OriginalSource);
}

Upvotes: 1

Related Questions