I'm trying to create User Control which will work like a rich button.
It's supposed to have an effect on hover - I turn border on on MouseEnter and off again at MouseLeave.
BUT, when I hover over label in my control, it fires Control.MouseLeave.
Is there any way to prevent this?
First, focus Enter and Leave are different events than MouseEnter and MouseLeave. Focus deals with keyboard input. MouseEnter and MouseLeave deals with where the mouse is right now.
Entering a nested control fires MouseLeave on the parent control. You can capture the mouse by setting the control's Capture property to true, but you may find that doesn't behave like you'd expect.
You might look at my post here. I had the same issue with nested controls. I opted to create a .NET equivalent of a mouse hook by calling Application.AddMessageFilter.
Another option would be to remove the inner label control and draw the text manually it in the button's OnPaint.
Related
I have a UWP app in which I have several buttons. Once the app starts to run, I set the focus in my code to the first button using a code like this:
firstButton.Focus(FocusState.Programmatic);
After this point, what I am interested in is that once the user use the mouse wheel, the UWP app automatically scroll to second, third, fourth, ... button(exactly like when we use tab key on keyboard to move between buttons).
However, when I use mouse wheel, nothing happens in the app.
I should also say that in firstbutton xaml, I use pointerwheelchanged event listener to change the focus to second button. However, this event handler does not work with mouse wheel UNTIL I MOVE THE MOUSE CURSOR INSIDE THE AREA OF FIRST BUTTON. What I am interested in is that this scrolling using mouse wheel becomes automatic exactly like the tab key of keyboard.
Any suggestions?
Place the event on the container control (like the Grid). If it's a control that already processes the event, use the AddHandler method with handledEventsToo set to true.
Screen of my user control
I have an user control (black rectangle) that contains some controls.
When the mouse is hover the user control, I want to show the two images in the red rectangle.
At the moment I have implemented the mouseEnter (show the images) and mouseLeave (hide the images) events from the user control.
The problem is that when the mouse is hover another control (a label for instance), the mouseLeave event from the user control is fired and the images disappear.
I could implement the mouse enter / mouse leave events for all the controls but it seems a waste of time, lots of code deduplication and a poor usage of memory.
I also thought about disable events for the other controls, but not sure how to do it and it seems to be more of a hack than anything. Il tried to disable the controls but the color changes and again, a dirty hack.
Maybe I can prevent the user control mouseLeave event to be fired if the mouse is hover one of its control ?
I'm sure there is a proper way to do it, but cannot figure it out.
If anyone thinks about a better title, I will change it.
Thank you for your help,
Regards
Thank you very much both of you.
You pointed me to the right direction.
I ended up to simply register the ControlUser.MouseEnter event to all controls by doing :
foreach (Control control in Controls)
{
control.MouseEnter += new EventHandler(this.MyUserControl_MouseEnter);
}
Simple and efficient, this is perfect.
I have a custom TreeView-like control in a panel in my application. As you click on items they receive keyboard focus.
It's possible to select a set of items in the tree and cut or remove them by pressing Ctrl-X or Delete. When the tree items are removed, keyboard focus reverts to the main window.
This leads to trouble - if I Undo my cut, I get my elements back but keyboard focus is no longer on my panel so I can't (for example) go cut-undo-cut-undo-cut.
What determines where the keyboard focus moves when an element is removed? I quickly tried making my panel have IsFocusScope="True" but that didn't seem to have any effect, and the Focus Overview doesn't mention how to control where focus goes when an element is removed.
I guess your best bet might be setting the focus manually after undo/redo (maybe encapsulating this in a behavior which listens to the events FocusManager sends?)
See also Set focus on textbox in WPF
I have a custom ZoomBox control based on ScrollableControl which controls its scrollbars through AutoscrollMinSize property.
I would like to be able to handle WM_MOUSEWHEEL events to adjust control's Zoom.
I made necessary steps to make sure that the control receives the mouse events even when it is not in focus, by filtering them on the parent form.
It seems though that the events only reach the OnMouseWheel method if the control does not have its scrollbars active. If it does, it appears that the mousewheel events are being redirected to the scrollbars which handle them (by scrolling).
I would like the scrollbars to be there but only be controlled in a "traditional way", i.e. by dragging the slider or clicking on arrows etc. and handle the wheel myself. Is it possible to achieve that?
Inherit from the ScrollableControl in question and override OnMouseWheel(). In that method don't call base.OnMouseWheel().
As far as I can tell there's no other way to stop ScrollableControl from scrolling if the scroll bars are present.
A side effect is that you will no longer get MouseWheel events. Fixing that is another question. Conceptually you want to call base.base.OnMouseWheel().
In our application we have white buttons on a white form. When the mouse hovers the button we want to show a light-blue transparant rectangle over the button.
I want to create this user control, but I don't know how to do this. I've tried google, but I didn;t found anything that could help me, so I hope you guys can point me at the right direction.
You can just derive your own WinForms control from a Button and override the OnPaint event. In the event handler you'll have an PaintEventArg parameter that contains the property called Graphics. You can use this property to draw anything you want directly where you control is located.
Here is an example directly from MSDN: http://msdn.microsoft.com/en-us/library/system.windows.forms.control.onpaint.aspx
Added: just re-read your question and found that I didn't not reply it correctly.
Basically, you have to override two events and add one property showing whether your control should be painted with an overlayed rectangle or not, let's say IsDrawRectangle. As soon as the OnMouseEnter event is triggered you check if IsDrawRectangle is set and if not you set it to true and invoke this.Invalidate(). The Invalidate() method will force the control to be re-drawn and then in your OnPaint event you just again check the value of your IsDrawRectangle property and draw the rectangle if needed.
You also have to override OnMouseLeave to set the property back to false and force the repaint to remove the rectangle.
Added: if you need to re-draw more than just a single control (in case if your rectangle covers some other controls that need to be re-drawn) then put everything you want to be re-drawn in one container and call the Parent.Invalidate() method in your event handlers.