views:

586

answers:

1

Hello All,

Summarized Question:
In the WPF TreeView, how can I force the selected event on an item that is currently the selected item?

Detailed Info:
I am trying to add functionality to my WPF TreeView by adding multiselect using shift(for a range) and control(for toggling selection of an item). I've implemented my own SelectedItems collection since the TreeView only has a selected item. I still use the SelectedItem of the TreeView so that it does not break keyboard functionality, however I do overwrite the existing ItemContainerStyle so that even though an item is selected, it does not give the appearance that it is selected. I wouldn't have needed to do this however, I needed to only highlight the background of the textblock of my selected treeview items, rather than the entire width of the item, so I handle the foreground and background color changes on my own.

+1  A: 

Implementing a WPF treeview uses lots of XAML, so this answer contains just fragments of code.

My goal was to click a selected treeview item in a left pane and refresh items in a right pane (like Windows Explorer).

To make selecting a selected treeview item work, I implemented two events in the following XAML example in my ViewModel:

  • OnItemSelected using event TreeViewItem.Selected
  • MouseLeftButtonUp using event TreeViewItem.MouseLeftButtonUp

When my MouseLeftButtonUp event fires I make sure to indicate I handled the event using:

  • args.Handled = true;

Here is the XAML

<TreeView Name="MyTreeView" 
    ItemsSource="{Binding Collections}" 
    Margin="0"                           
    Grid.Row="0"
    TreeViewItem.Selected="OnItemSelected"
    TreeViewItem.Unselected="OnItemUnSelected">
    <TreeView.ItemContainerStyle>
        <Style TargetType="{x:Type TreeViewItem}">
            <EventSetter Event="TreeViewItem.MouseLeftButtonUp" Handler="MouseLeftButtonUp"/>
            <Setter Property="IsExpanded" Value="{Binding IsExpanded, Mode=TwoWay}" />
            <Setter Property="IsSelected" Value="{Binding IsSelected, Mode=TwoWay}" />
        </Style>
    </TreeView.ItemContainerStyle>

    <!-- other XAML removed for this answer-->

</TreeView>

Here are the event handlers

private void OnItemSelected(object sender, RoutedEventArgs e)
{
     // do something...
}


// additional info: cannot detect mouse down events; preview mouse events also work
private void MouseLeftButtonUp(object sender, MouseButtonEventArgs args)
{
   TreeViewItem tvi = sender as TreeViewItem;
   if (tvi != null)
   {
      // process folder items
      MyViewModel fvm = tvi.Header as MyViewModel;
      if (fvm != null)
      {
         // only process selected treeview items
         if (fvm.IsSelected)
         {
            fvm.IsSelected = true;

            // prevent bubbling once we find the  selected tree view item
            args.Handled = true;
         }
      }
}
Zamboni