Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"MouseLeftButtonDown" Event not raised in TreeViewItem, why?

Tags:

c#

wpf

treeview

I have a TreeView in WPF application. as the following.

<TreeView x:Name="documentOutlinePanel">
    <TreeView.ItemContainerStyle>
         <Style TargetType="{x:Type TreeViewItem}">
             <EventSetter Event="TreeViewItem.MouseLeftButtonDown" Handler="TreeViewItem_MouseLeftButtonDown"/>
           </Style>
     </TreeView.ItemContainerStyle>
</TreeView>

here is the handler of the event , which exist in the Code Behind file

private void TreeViewItem_MouseLeftButtonDown(object sender,   MouseButtonEventArgs e)
{
    // some code.
}

I am also handling two HierarchicalDataTemplate for the item that can be in the TreeView control.

The items of the TreeView is bounded, by setting ItemsSource property of the TreeView.

Problem
The handler of the MouseLeftButtonDown is not executed at all.
I set a breakpoint in the beginning of handler of this method, and the breakpoint does NOT hit at all.

But, just for notice. the PreviewMouseLeftButtonDown is triggering and I can handle it (this event does not important for me)

Can any one explain to me why the MouseLeftButtonDown is not fired?
any suggestion to make it fire ?

Update: This question is NOT duplicated of MouseLeftButtonDown is not fired on TreeViewItem

I saw that question and its answer, and it did not fit me. here is the differences

  1. That question is for SliverLigth and mine for the WPF.
  2. that question is Handling the TreeView.MouseLeftButtonDown and mine Handle the TreeViewItem.MouseLeftButtonDown.
  3. I read the answer of that question and it did not help me in any way
like image 254
Hakan Fıstık Avatar asked Mar 16 '23 00:03

Hakan Fıstık


2 Answers

thank you @qqww2, your answer may be useful, although I did not try it because I found a more pretty solution.
I read TreeViewItem.OnMouseLeftButtonDown source code and I figured that this event is marked as handled in this method if the TreeViewItem success to get the Focus.
So I made the TreeViewItem object as UnFocusable.

<TreeView x:Name="documentOutlinePanel">
    <TreeView.ItemContainerStyle>
      <Style TargetType="{x:Type TreeViewItem}">
          <Setter Property="Focusable" Value="False"/>
          <EventSetter Event="TreeViewItem.MouseLeftButtonDown" Handler="TreeViewItem_MouseLeftButtonDown"/>
      </Style>
   </TreeView.ItemContainerStyle>
</TreeView>

This makes the MouseLeftButtonDown Event fire. And inside the handler of this event, I set the Focus to it like this

private void TreeViewItem_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
    TreeViewItem item = (TreeViewItem)sender;
    // do what i want.

    item.Focusable = true;
    item.Focus();
    item.Focusable = false;
    e.Handled = true;
}

The e.Handled is set to true, because I noticed that this event occur twice, one for the TreeViewItem and one for its Parent TreeViewItem. (because this event is bubbling event) so at the end the always the Parent TreeViewItem is selected.

This worked for me in case of anyone face the same problem

like image 108
Hakan Fıstık Avatar answered Mar 31 '23 11:03

Hakan Fıstık


Actually you have the same problem in that question. In TreeViewItem.OnMouseLeftButtonDown the event is marked as handled, therefore it does not bubble up anymore.

You can overcome this by calling the code below once and registering yourself to MouseDownEvent for TreeViewItem. However be aware that this code redirects events for all TreeViewItem's in your application. This may or may not be suitable for you. Also this event is fired for all mouse buttons, but you can easily check whether the clicked button is Left or not.

EventManager.RegisterClassHandler(typeof(TreeViewItem), Mouse.MouseDownEvent, new MouseButtonEventHandler(OnMouseButtonDown), true);
like image 33
Yusuf Tarık Günaydın Avatar answered Mar 31 '23 11:03

Yusuf Tarık Günaydın