I have a Grid with a Button inside. The button has Flyout menu attached.
I implemented an action which opens the flyout menu when the button is tapped/clicked. This is the default behavior which does not require event writing. I also implemented an action when the grid is tapped/clicked.
The problem is that I do not want the grid to react when I tap/click the button. Based on this fine read, it all makes sense, but in my case, I do not have any code behind to add the e.Handled = true; line to.
Is there any way I could stop event bubbling up the tree using XAML only? Thanks!
While I hate to poach Gusdor's points. There is a built an enumeration property to deal with this types of situations called ClickMode which you can override the default mode for Button of Release and set it at the instance as ClickMode="Press" to get the desired effect and allow it to receive HitTestVisibility individually before any parent does.
Hope this helps, cheers.
I believe you will need to write some code but not the code behind you are trying to avoid.
Create an attached behavior that subscribes to, and handles the
bubbling event.
Attach the behaviour to the element where you want
the event bubbling to stop.
There is a Microsoft article about plugging Behaviours into UWP apps https://blogs.windows.com/buildingapps/2015/11/30/xaml-behaviors-open-source-and-on-uwp/
Related
I just have a form, and using this.Controls.Add in the form I have added a container control which basically fills the whole background area of the form (and contains many other controls like datagridviews, comboboxes etc), so I can't click off of it.
Now, in the form class, I want to add some keyboard shortcuts.. Like, F5 saves my work for instance. Anyway, I have hooked up to the control's keydown even in the form class, but, it doesn't seem to fire!
Can anyone tell me why?
Thanks,
Isaac
It would probably have helped if you would have described which control you were adding. You are most likely adding a control that is trying to read the keyboard events. For the form to still get those events, change this property:
this.KeyPreview = True;
I need to fire some event when WPF button is pressed (by mouse, keyboard, touchscreen, etc) and to fire event when WPF buttons is unpressed.
How to do this? It should be easy but I can't find how to do this.
You can derive from Button and override the OnIsPressedChanged method and fire a custom event there.
Or you can bind to the ButtonBase.IsPressed property.
Another option is to use DependencyPropertyDescriptor:
var descriptor = DependencyPropertyDescriptor.FromProperty(Button.IsPressedProperty, typeof(Button));
descriptor.AddValueChanged(this.button, new EventHandler(IsPressedChanged));
If you are using MVVM, you can use event triggers to solve your problem. This way, you can still separate your UI requirements from your application logic.
Example 1
Example 2
I've created a custom panel control and would like to have it respond to a mouse move event, however, when I add an event handler like so:
Private Sub FloatingPanel_MouseMove(ByVal sender As Object,
ByVal e As MouseEventArgs) Handles Me.MouseMove
End Sub
It only responds when I move the mouse over one of the child controls within the panel. I need to have it respond whenever I move the mouse anywhere inside the custom panel.
Update:
I found the following question which gave me a clue:
WPF - how to best implement a panel with draggable/zoomable children?
I can get mouse events on the
GraphCanvas itself only if it has a
background at the point
This led me to simply set the background which appears to have resolved the issue... My question now is, why? Why should I have to set the background in order to receive a mousemove event?
Update 2: The following code is what ultimately solved the problem (See Kent's answer below).
Protected Overrides Function HitTestCore(ByVal hitTestParameters As System.Windows.Media.PointHitTestParameters) As System.Windows.Media.HitTestResult
Return New PointHitTestResult(Me, hitTestParameters.HitPoint)
End Function
Thank you,
Matt
For the purposes of hit testing, WPF's default hit testing logic has two modes of transparency. One is transparent both visually and to hit testing (#00000000 or by not setting a background at all), the other is transparent only visually and does not preclude hit testing (##00ffffff). You want the latter.
I believe you could also override UIElement.HitTestCore in your custom Panel such that there is no dependency on having the background set.
I actually suspected this might have been the issue here; If the background of a control is null and there is no other subcomponent there your mouse is not moving across the control but accross the control behind it, so it makes sense that you do not get a mouse event from that (it is not very expected though because the bounds of the control may envelope the area).
In the View-Model-ViewModel, actions are essentially executed by the viewmodel that is bound to the view. However, where would the "presentation logic" go since the code behind isn't used and the viewmodel has no reference or knowledge of the control that invoked it?
For example, what if I wanted to animate another control when a button is clicked. Would this still go in the code behind?
To expand on Justin Niessner's comment, I'd be using a trigger to achieve this animation as it's all UI bound.
Think about this:
Where would you put code so that when someone mouses over a button it becomes hilighted?
What about code for "depressing" that button when it is clicked?
These and your question are all variations on a theme, so I'd say do it in the GUI.
However, there's one exception to this rule. If the "animation" is a processing animation, then it might be worth tying it to the ViewModel so the ViewModel can control how long the animation runs while it's processing something. Otherwise do it in the GUI.
EDIT: Based on your comment. Ok so the animation should run off a property in the ViewModel, not the button click event. The Click should start the processing in the ViewModel through a command, and the execute code for that command should set a processing flag property on the ViewModel. Then the View can bind to that processing flag and display a progress bar or whatever when that flag is set.
I have a custom UserControl which tries to recreate auto-complete for a textbox. When user types, the text is used to filter a provided collection of items and then a Popup displays a ListBox with items that match what user have typed.
Unfortunately, if user decides to switch away from the application to another window (browser, MSWord, anything!), the Popup remains on top of every other window!
Also, if I move my window (which hosts the custom control) with the popup open, the popup stays in place (and doesn't follow the window)! It's kinda funny but obviously not acceptable behaviour. I've looked around but only found one post about this that went unanswered for two years :(
Actually, I didn't realize that I had StaysOpen property of the Popup set to true.
<Popup StaysOpen="False" />
actually does the trick for me.
I had the same problem in a similar scenario. What I did was I subscribed to all posible "lost focus" events of the control and also got the window which hosts the control and subscribed to its GotMouseCapture and LocationChanged events. Event handlers of all those events are setting the popup's IsOpen property to false.
You can get the hosting window with this:
parentWindow = Window.GetWindow(this);
all other code is simply a lot of subscribing to events to do the same thing.
P.S. I'm not saying it's a pretty or optimal solution, but it works fine for me :)
According to the Popup documentation:
When Popup is displayed on the screen, it does not reposition itself if its parent is repositioned.
So it does not look like it would be a very good candidate for an autocomplete textbox. I think the class is meant more for showing information when you hover over an item.