Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

wpf: left button click is not recognized

I newly in WPF and when I learn the material I faced with strange issue.

I build a button, contain layers with text block and I want to recognize where the user click on the button itself, on 'first', 'second, or 'third' (I output a message).

enter image description here

All works fine except the button not raise an event when the user clicks with left button (just with middle or right button).

so my question: Why I not received a message box when I press on the button itself with left mouse button (and I receive the msg box with other mouse buttons) ?

XAML:

<Button Margin="145,152,144,102" Padding="5,5,5,5" HorizontalAlignment="Center" VerticalAlignment="Center" MouseDown="Button_MouseDown" Height="57" Width="214">
    <WrapPanel>
        <WrapPanel HorizontalAlignment="Center" VerticalAlignment="Center"></WrapPanel>
        <TextBlock Foreground="Black" FontSize="24" MouseDown="TextBlockFirst_MouseDown" >First  </TextBlock>
        <TextBlock Foreground="Red" FontSize="24"   MouseDown="TextBlockSecond_MouseDown">Second </TextBlock>
        <TextBlock Foreground="Blue" FontSize="24"  MouseDown="TextBlockThird_MouseDown" >Third  </TextBlock>
    </WrapPanel>
</Button>

Code:

private void TextBlockFirst_MouseDown(object sender, MouseButtonEventArgs e)
{
    MessageBox.Show("You click on first");
}

private void TextBlockSecond_MouseDown(object sender, MouseButtonEventArgs e)
{
    MessageBox.Show("You click on second");
}

private void TextBlockThird_MouseDown(object sender, MouseButtonEventArgs e)
{
    MessageBox.Show("You click on third");
}

private void Button_MouseDown(object sender, MouseButtonEventArgs e)
{
    // This event not working good
    // only middle & right mouse buttons are recognized
    MessageBox.Show("You click on the button");
}

Thank you!

like image 1000
AsfK Avatar asked Apr 13 '14 09:04

AsfK


2 Answers

MouseDown event is a bubbling event which bubbles from its originator to its root parent. But Click event eat up the MouseDown event and doesn't allow the event from bubbling upto Button.

You can use PreviewMouseDown event which is a tunnelling event which tunnels from root to its originator. So button will first get this event and then subsequent textBlock.

<Button PreviewMouseDown="Button_MouseDown">
   .......
</Button>

Refer to the snapshot below for the clear picture:

enter image description here


UPDATE

Hook only PreviewMouseDown event on button and remove handlers from individual textBlocks. Check for e.OrignialSource to see if TextBlock is actual original source or button.

private void Button_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    if (!(e.OriginalSource is TextBlock))
    {
        MessageBox.Show("You click on the button");
    }
    else
    {
        switch ((e.OriginalSource as TextBlock).Text)
        {
            case "First":
                MessageBox.Show("You click on first");
                break;
            case "Second":
                MessageBox.Show("You click on second");
                break;
            case "Third":
                MessageBox.Show("You click on third");
                break;
        }
    }
}

XAML

<Button PreviewMouseDown="Button_PreviewMouseDown" Height="57" Width="214">
    <WrapPanel>
        <WrapPanel HorizontalAlignment="Center" VerticalAlignment="Center"/>
        <TextBlock Foreground="Black" FontSize="24">First</TextBlock>
        <TextBlock Foreground="Red" FontSize="24">Second</TextBlock>
        <TextBlock Foreground="Blue" FontSize="24">Third</TextBlock>
    </WrapPanel>
</Button>
like image 128
Rohit Vats Avatar answered Sep 17 '22 08:09

Rohit Vats


It doesn't work, because the first fires is an event at the Button.Click, and when it works, it conflicts with the events like: MouseLeftButtonDown, MouseUp, MouseDown.

To make has worked this event, you need to define an PreviewMouseDown event, because it's a Tunnel event, this means that it will go down of the VisualTree hierarchy, therefore it is triggered before the Bubble events.

Also, as alternative, you can use the Button.Click event for Button.

like image 38
Anatoliy Nikolaev Avatar answered Sep 17 '22 08:09

Anatoliy Nikolaev