Prevent taps from passing through buttons in XAML/WPF - wpf

In my project, I have a large container with a handler for taps. Inside this container, I also have a button. My goal is to handle all taps on the background container UNLESS the user clicks on the button. Unfortunately, when I click on the button, it fires both the click handler on the button AND the tap handler for the container.
Here's some example XAML:
<Grid Width="250" Height="250" Fill="Red" Tapped="Container_Tapped">
<Button Click="Button_Clicked">
<Rectangle Width="20" Height="20" Fill="Blue" />
</Button>
</Grid>
Is there a way to handle the tap event on the button to prevent it from bubbling to the container? Any other ideas?

In your Container_Tapped event handler you could check the RoutedEventArgs.OriginalSource Property. If e.OriginalSource is a descendant of your button do nothing.
For that Visual.IsDescendantOf Method could be helpful.

Here's a dynamic way to do it in Win RT, without needing to know the exact name of the button (useful if you have a pile of buttons to work with, such as when databinding!)
' Verify that the sender is not a button (or one of its children)
If Not e.OriginalSource.Equals(sender) Then
Dim parentObj = VisualTreeHelper.GetParent(e.OriginalSource)
Do While Not parentObj.Equals(sender)
If TypeOf parentObj Is Button Then Return
parentObj = VisualTreeHelper.GetParent(parentObj)
Loop
End If

Related

WPF and MVVM. Display and hide a label with a timeout

in my MVVM application, I wish to create an auto-closing popup to notify some information to the users (for example "data changes saved successfully").
so, I placed a label into the form, bound to a VM property. Then, I wish to set my message and cancel it after a delay (1 second). But it seems not to work. the app just wait some time, and shows the final status (ie: when the user push "save" button, the app "waits" for one second, and then the label is empty).
any ideas to get it? thanks
Why can't you use normal popup in WPF
<Popup Margin="10,10,0,13" Name="Popup1" HorizontalAlignment="Left" VerticalAlignment="Top" Width="194" Height="200" IsOpen="True">
<StackPanel>
<TextBlock Name="McTextBlock"
Background="LightBlue" >
This is popup text
</TextBlock>
<Button Content="This is button on a Pupup" />
</StackPanel>
public void show()
{
Popup1.IsOpen = true;
Thread t = new Thread(hide);
t.Start();
}
private void hide() {
Thread.Sleep(5000);
Popup1.IsOpen = false;
}
call show function when you want to show popup

WPF how to make button icon spin only when mouse over

I am using mahapps iconpacks and I come across this method "spin" but I have no idea how to bind it to a mouse over event
<Button x:Name="btnRefresh"
Content="{iconPacks:PackIconMaterial Kind=Refresh, Spin=True}">
I want the icon to spin only when the mouse cursor is over the button and stop from spinning when it's not. Thanks.
If anyone looks for an answer:
<Button x:Name="btnRefreshSpin"
Style="{DynamicResource MetroCircleButtonStyle}">
<iconPacks:PackIconModern Kind="Refresh" Spin="{Binding Spin}" />
</Button>
and Spin is a simple method from the view model which returns true or false. A mouse over event can be linked to the same property

WPF, what kind of controls will handle MouseLeftButtonDown event?

I have a DataGridControl,and its cell's DataTemplate overwritten to TextBoxs,by clicking outside the cells but still on the DataGrid, I want the TextBox to lose Keyboard focus so that it can Commit the change, but it seems the DataGrid won't handle the MouseLeftButtonDown event, so I have to manually add a handler to the Grid,and in the handler:
e.Handled = true;
Keyboard.Focus( sender as UIElement );
to make the parent panel "focusable".
By using Snoop, I notice that controls like TextBox, Button are capable of handle MosueLeftButtonDown event, while Panels are not,event if set "Focusable" property to "True". Does anyone know the reason behind this, Thanks.
To simplify the situation: suppose we have a TextBox and a Button on a Grid:
<Grid Background="AliceBlue">
<TextBox Height="25" Margin="50" Text="abcd"/>
<Button Height="25" Margin="50,100,50,0"></Button>
</Grid>
when I click on the TextBox, it gets KeyBoard focus, when I click the blank area of the Grid, I want the TextBox to lose focus, the problem is Grid is not focusable compared with TextBoxes and Buttons.
The documentation for Panel shows that Panel can handle mouse events:
https://msdn.microsoft.com/en-us/library/system.windows.controls.panel_events(v=vs.110).aspx

Try to catch mouse event in HierarchicalDataTemplate

I'm fairly new to wpf and this website. Please give me some mercy if I show some mistakes.
My HierarchicalDataTemplate ,which is my treeview item, consists of multiple components: two textblocks , image , and checkbox with some stack panels for the layout. My MouseEventHandler, which is to catch when user click on textboxes, image , or checkbox , is TreeViewItem.Selected. But when I click on the tiny space between those components, it doesn't trigger TreeViewItem.Selected.
My first initial thought was that I might need to specify event handler on the stack panel which was for the layout of my HierarchicalDataTemplate . However, it didn't rise the event ,even though I made event handler on stack panel specifically.
Could you give me some guidance?
ps. I used binding for IsSelected property but it never notified to change its property
Set Background="Transparent" for topmost layout container inside your HierarchicalDataTemplate.
The following Grid doesn't raise MouseLeftButtonDown event:
<Grid MouseLeftButtonDown="handler" Width="200" Height="200">
</Grid>
But the following does:
<Grid MouseLeftButtonDown="handler" Width="200" Height="200" Background="Transparent">
</Grid>
This is because in the 1st case it doesn't have background and there's nothing to raise MouseLeftButtonDown event. So the event will be raised only if user clicks on some element inside that Grid.

Why does WPF toggle button pulse once unchecked

Within a Desktop app I have a toggle button:
<ToggleButton x:Name="CFStglBtn" Checked="cfsCBox_Checked"
Unchecked="cfsCBox_Unchecked"
IsChecked="True" HorizontalAlignment="Left" Margin="5,0,0,0">
<StackPanel Orientation="Horizontal">
<Image Source="assets\telephone.png" Margin="3,0,0,0" />
<TextBlock Text="CFS" FontSize="10" Margin="5,5,5,0"
Foreground="DarkSlateGray"/>
</StackPanel>
</ToggleButton>
For the Checked event I am setting a value and then executing a method FilterView();
//ommitting code
Unchecked state is just the opposite. resets a variable and executed the method again
The question I have is I noticed when I uncheck the toggle button the button continues to pulse or flash ( going from blue to chrome) as if it still has focus. The button will stay like this until another button is clicked.
Is there a way to remove this focus so that when the button is unchecked the button goes back to a unchecked state without the flashing / pulsing color.
As you can see from above this is a standard toggle button no styles or custom
I tested this on just a regular button and I found the same occured when clicked the button will continue to pulse / flash until another button is clicked.
How do you work around this or prevent this effect from happening.
Thank you
Set the Button Focusable="False".
This is happening because of the button chrome built into the default template for the control. Your only workaround is to re-template the Button. This article should get you started.

Resources