1

To demostrate the problem I have this Xaml:

    <DockPanel MouseLeftButtonDown="DockPanel_MouseLeftButtonDown"  MouseLeftButtonUp="DockPanel_MouseLeftButtonUp">
        <ListView>
            <ListViewItem>ListViewItem</ListViewItem>
        </ListView>
        <TextBlock>TextBlock</TextBlock>
    </DockPanel>

and the event handlers are :

    private void DockPanel_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        Console.WriteLine("DockPanel_MouseLeftButtonDown");
    }


    private void DockPanel_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        Console.WriteLine("DockPanel_MouseLeftButtonUp");
    }

When you run the app and click on the words TextBlock you get MouseDown fired followed by MouseUp. So far so good. But when you click on the words ListViewItem only MouseUp is fired. Same problem for ScrollViewer (List view includes it so I am guessing it's the same problem). Does anybody know why and if this can be fixed. By fixed I mean get it to fire not try to use another event or another mechanism all together.

ILIA BROUDNO
  • 1,539
  • 17
  • 24

2 Answers2

4

First the problem: As suspected the problem is in ScrollViewer: http://referencesource.microsoft.com/#PresentationFramework/Framework/System/Windows/Controls/ScrollViewer.cs,488ab4a977a015eb

    protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
    {
        if (Focus())
            e.Handled = true;
        base.OnMouseLeftButtonDown(e);
    }

As you can see it sets MouseButtonEventArgs.Handled to true which stops the bubbling of the event.

Now the solution - it is in the way you add the handler:

        MyListView.AddHandler(
            ListView.MouseLeftButtonDownEvent, 
            new MouseButtonEventHandler(ListView_MouseLeftButtonDown),
            true);

Note the last parameter (true) it causes the handler to be invoked even if the EventArgs.Hanlded was set to true. Then you can reset it:

    private void ListView_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        e.Handled = false;
    }
ILIA BROUDNO
  • 1,539
  • 17
  • 24
0

I had somewhat similar situation when ScrollViewer was blocking my MouseLeftButtonDown event. I had a content control wrapped into ScrollViewer:

<ScrollViewer VerticalScrollBarVisibility="Auto">
     <ContentControl x:Name="Details"  />
 </ScrollViewer>

and this was inside of Popup which had a drag/drop behavior. So, because my behavior was not receiving this event, it did not work. When I added IsHitTestVisible="True" to ScrollViewer, my behavior started to work, but of course my ContentControl was not responding to any clicks. Then I saw this:

protected override void OnMouseLeftButtonDown(MouseButtonEventArgs e)
{
    if (Focus())
        e.Handled = true;
    base.OnMouseLeftButtonDown(e);
}

and tried to add Focusable="False" to exclude ScrollViewer from my click - it works. My behavior works and controls inside of ContentControl are getting all mouse events.

 <ScrollViewer VerticalScrollBarVisibility="Auto" Focusable="False">
     <ContentControl x:Name="Details"  />
 </ScrollViewer>

Hope it will help somebody.

Victor
  • 31
  • 2