NumericUpDown: Fix MouseEnter and MouseLeave Events [duplicate] - c#

This question already has answers here:
Parent Control Mouse Enter/Leave Events With Child Controls
(6 answers)
Closed 4 years ago.
I am currently working on a subclass to the WinForms NumericUpDown Control. But because they built it so it contains multiple sub-controls, it messes up the MouseLeave and MouseEnter event.
When the mouse moves into the controls bounds, MouseEnter will fire followed by MouseExit when the mouse moves over one of the subcontrols (e.g. the Up and Down Arrow Buttons). In addition to that, MouseExit will not fire at all sometimes, especially likely when moving the mouse out of control bounds fast...
How can I get the events to fire properly or work around this problem?
EDIT:
Here's a simple code example:
public class TMNumericUpDownControl : NumericUpDown
{
public TMNumericUpDownControl()
{
MouseEnter += MouseEnterHandler;
MouseLeave += MouseLeaveHandler;
}
private void MouseEnterHandler(object sender, EventArgs e)
{
Debug.WriteLine("entered");
}
private void MouseLeaveHandler(object sender, EventArgs e)
{
Debug.WriteLine("Left");
}
}

Okay I just got it myself.
I noticed I can just access the NumericUpDowns child controls via NumericUpDownName.Controls and assign the event handlers to them as well. Thought this wouldn't be possible before...
That means this is in fact a duplicate Question.

Related

Get Delete Keypress event in Windows Panel control [duplicate]

This question already has answers here:
Panel not getting focus
(6 answers)
Closed 7 years ago.
I have got some controls on the Panel and I am trying to delete them using "Delete" button. I handled KeyPress Event as mentioned in How to get Keypress event in Windows Panel control in C#
and I am getting Event for buttons (A-Z and 1-9) pressed, but not for the Delete, Control/Alt/ Shift or F1, F2.... buttons.
Do we need to do something special for handling these buttons?
Try like this:
private void Window_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Delete)
{
e.Handled = true;
}
}
Also you need to set KeyPreview on.
You can also refer Keyboard.Modifiers Property

Capture KeyDown when event does not reach my control

First: I know that there are literally thousands of answers like: "Add a handler to Keyboard.KeyDownEvent and have fun!". But in my situation this does not work.
I have a custom control CustomControl which derives from Canvas but has no Children. Instead it draws its "children" directly to the DrawingContext in the OnRender. My Control is HitTestVisible, it is tab stop but is not focusable. It is often reused and sometimes in a ScrollViewer.
This CustomControl has a custom implementation for selecting something like text, and should copy that selected text to the ClipBoard on Ctrl+C.
To do this, I added a handler in the constructor:
public CustomControl()
{
//// ... other stuff
AddHandler(Keyboard.KeyDownEvent, (KeyEventHandler)CopyMarkedNucleotidesToClipboard);
}
And here is the Problem: When my control is inside a ScrollViewer, and I hit Ctrl+C, the KeyDownEvent is raised on the ScrollViewer and bubbles up to the window, and therefore never reaches my Control.
What can I do inside my CustomControl to capture every Ctrl+C in the window where it resides?
PS: I already set IsTabStop="False" and Focusable="False". But then the next sibling of the ScrollViewer would raise the event which would still bubble up to the window. And I don't want to go through all controls which are higher in the visual tree and set IsTabStop="False" and Focusable="False" which would be wrong...
I already found this article http://blogs.msdn.com/b/toub/archive/2006/05/03/589423.aspx but I think, that there must be a more wpf-like way!
The suggestion of Sinatr was correct! Thanks!
The solution is to find the parent window in the load and subsribe to his KeyDownEvent.
public CustonControl()
{
Loaded += HookToCtrlC;
}
private void HookToCtrlC(object sender, EventArgs e)
{
var parentWindow = Window.GetWindow(this);
parentWindow.KeyDown += CopySelectedTextToClipboard;
}
private void CopyMarkedNucleotidesToClipboard(object sender, KeyEventArgs e)
{
Clipboard.SetText("Hello World!");
}

Custom Event Triggers in Blend

Hi I have been learning WPF with "Expression Blend 4" last few days and this is what I want to accomplish.
I have a Main Window which has a single custom button in it.
What I want to do is that when the Mouse Cursor is to the left side of the Window, I want the button to start its animation and move to my cursor. Alternatively, when the cursor is at the right side of the window, I want the button to move right.
I have created custom events for this. I already tested them with "MessageBox"s to pop up if I either move left or right. In actual fact I want them to animate left or right. But in order to create an animation timeline, I cant find my custom events on blend. Is there a way to go about this?
Partial Code Below
private event EventHandler MoveRightEvent;
private event EventHandler MoveLeftEvent;
public MainWindow()
{
this.InitializeComponent();
// Insert code required on object creation below this point.
MoveRightEvent += new EventHandler(MainWindow_MoveRightEvent);
MoveLeftEvent += new EventHandler(MainWindow_MoveLeftEvent);
}
void MainWindow_MoveLeftEvent(object sender, EventArgs e)
{
MessageBox.Show("Moved Left!!");
}
void MainWindow_MoveRightEvent(object sender, EventArgs e)
{
MessageBox.Show("Moved Right!!");
}
You question was about EventTrigger (please note that in this case you must use RoutedEvent and not .NET Event) but your question is begging for custom Behavior as in this example: WPF Tutorial: Behaviors

How to capture mouse wheel on panel?

How to capture mouse wheel on panel in C#?
I'm using WinForms
EDIT:
I try to do it on PictureBox now.
My code:
this.pictureBox1.MouseClick += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseClick);
this.pictureBox1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.pictureBox1_MouseClick);
private void pictureBox1_MouseClick(object sender, MouseEventArgs e)
{
MessageBox.Show("Click");
}
Clicking works. Wheelling doesn't.
Why?
If you can't see the "MouseWheel" event on a component, then you need to create it manually. Also, we need to focus that component, otherwise the "MouseWheel" event will not work for that component. I will show you how to create a "MouseWheel" event for "pictureBox1" and how it works.
INSIDE THE CONSTRUCTOR, create a mousewheel event on that component.
InitializeComponent();
this.pictureBox1.MouseWheel += pictureBox1_MouseWheel;
CREATE THE FUNCTION manually. According to my example, call it "pictureBox1_MouseWheel"
private void pictureBox1_MouseWheel(object sender, MouseEventArgs e)
{
//you can do anything here
}
CREATE a MouseHover event on that component (Go to properties in PicureBox1, select event, locate "MouseHover" and double-click the "MouseHover" event).
CALL "Focus()"; method inside that MouseHover event.
pictureBox1.Focus();
Now run the program.
Windows sends the WM_MOUSEWHEEL message to the control that has the focus. That won't be Panel, it is not a control that can get the focus. As soon as you put a control on the panel, say a button, then the button gets the focus and the message.
The button however has no use for the message, it's got nothing to scroll. Windows notices this and sends the message to the parent. That's the panel, now it will scroll.
You'll find code for a custom panel that can get the focus in this answer.
UPDATE: note that this behavior has changed in Windows 10. The new "Scroll inactive windows when I hover over them" option is turned on by default. The makes the mouse wheel behavior more consistent with the way it works in a browser or, say, an Office program. In this specific case the picturebox now will get the event. Watch out for this.
To wire it up manually...
this.panel1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseWheel);
private void panel1_MouseWheel(object sender, System.Windows.Forms.MouseEventArgs e)
{
///process mouse event
}
Easier method is in visual studio click on panel, goto properties viewpanel, select events, locate and double click the "mousewheel" event.
In Winforms, this is achieved using the Control.MouseWheel event
Getting mousewheel events is tricky. The easiest way is using
this.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseWheel);
instead of
this.panel1.MouseWheel += new System.Windows.Forms.MouseEventHandler(this.panel1_MouseWheel);
This way the form gets the event instead of control. This way is easy but has one problem: you can use only one mousewheel event in your form.
If you have more than one control to get mousewheel event the best way is This answer by "Shehan Silva - weltZ"

MouseUp event interrupted?

I'm making a custom control with a panel. I want to be able to drag and drop it so I've implemented that in the MouseDown event of my control. But I want the thing to react when you start drag to give a little feedback to the user. So in the MouseDown even I change the color. Then I want to change it back in the MouseUp event.
My control is not installed into VS2008 but just a class I've written that I instanciate at run time (I don't know in advance how many I need and so on). Now, my control exposes a MouseDown event so as to be able to be dragged. When I subscribe to this event from the parent application to actually perform the drag and drop my control is not repainted on its MouseUp event! In fact, the MouseUp is never invoked. If, on the other hand, I don't subscribe to the event in the parent app it works as intended.
What's going on? Is the parent interrupting the flow so that the MouseUp event never fires in my control? How do I get around this?
I'm not sure if you are using Windows Forms or WPF, but in Windows forms here is what I mean:
public class DerivedPanel : Panel
{
protected override void OnMouseDown(MouseEventArgs e)
{
base.OnMouseDown(e);
Capture = true;
}
protected override void OnMouseUp(MouseEventArgs e)
{
base.OnMouseUp(e);
Capture = false;
// Change your color or whatever here
}
}
In WPF there are two methods, CaptureMouse() and ReleaseMouseCapture() to do the same thing. When the control captures the mouse, it will received mouse events even if the cursor isn't over the control. This could be causing your problem. See MSDN Article
Do you capture the mouse in the custom control on the mousedown event? Try capturing on the mousedown and releasing the capture on the mouseup.

Categories