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).
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!
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:
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>
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With