I have a panel (panel2) inside another panel (panel1). I want to get mouse position of panel1, but when I move my mouse over panel2, the following code stops working.
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
label1.Text = "Offset: " + e.X + " x " + e.Y;
}
How can I get it to read the mouse arguments, even if the mouse is over panel2? Thanks!
EDIT: panel2 is located at center x=100, y=100 of panel1. if I move my mouse on panel2 left top corner it gives me coordinates for example 1x1, where I need to location on panel1 like 101x101
EDIT 2: I'm not trying to drag it, just read the coordinates of original panel (panel1) so I can calculate the offset for zooming the panel2. So I only need mousemove, nothing else. Thanks
If you only need to do this while a mouse button is being held down (for example, because you are tracking a drag and drop operation or a selection) then you can do the following:
In your MouseDown handler, call this.Capture = true;
Now your MouseMove handler will receive mouse move messages even when the mouse is over another control.
In your MouseUp handler, call this.Capture = false; - Note: If you forget to do this, your other controls in the same process will not receive any mouse messages.
Other than that, it's very tricky to get MouseMove messages from other controls without adding mouse handlers to those other controls.
The main thing about this.Capture is that you need a good time to set it to true and another good time to set it back to false. Generally, that's done in MouseDown and MouseUp as I described.
However, you could also convert the coords from Panel2-relative to Panel1-relative like so:
Convert from Panel2 coords to screen coords:
Point screenCoords = panel2.PointToScreen(mouseCoordInPanel2);
Then convert from screen coords to Panel1-relative coords:
Point mouseCoordInPanel1 = panel1.PointToClient(screenCoords);
To do this you would have to have a MouseMove handler in Panel2 where you did this conversion, and Panel2 would need a reference to Panel1 in order to call panel1.PointToClient()
You must also assign to the event of the other panel.
can't you put the event handler in panel2, then use the left/top properties of panel1 and panel2 to offset the mouse position within panel2 to get your desired location in panel1?
I also think that assigning an event to the second panel would be the best thing. When the mouse is on Panel 1, the coordinates would be provided directly; when it is on Panel 2, they would be converted by accounting for the relative positions between both panels (pretty straightforward: variation in X/Y positions; values which do not need to be hardcoded but updated at runtime).
Related
In the UserControl I made it is possible to add Rectangles by clicking. Those rectangles are saved in a List. Now I want to make it possible for the User to move those Rectangles that are drawn.
First I tried to add the MouseDown, MouseMove and MouseUp event to the Rectangle but that doesn't work because Drawing Rectangle is a Struct and not a control. I already did a Testproject and accomplished to move a button I put in in the UserControl by Designer. I tried with the code I got from Drag and Drop Function with Drawing Rectangle C# .net - Forms but this example isn't about Rectangles. It is about Controls and I don't know how to use this idea for Rectangles because
rectangle.MouseDown += delegate(object sender, MouseEventArgs e)
{
//do something
}
doesn't work. Any Ideas how to drag and drop Rectangles that are added dynamically?
You should add the MouseDown event to the UserControl. Then loop through the list and make a method to see if the coordinates are inside of a Rectangle. If it is, then hook and move it.
So you should add a bool value to, which is set to true inside the MouseDown event and set to false inside the MouseUp event. Then in the MouseMove event, check if the mouseDown value is true. If it is and a Rectangle was found, move it's position.
I'm trying to show some movable controls in silverlight. I've a grid, and dynamically I've to add some controls(I'm now trying with Thumb). And user can move those controls within the grid(in the space specified for the grid). I'm not saying about the Drag and Drop controls. Actually the controls are to move as a user press mouse left button on it and starts to drag it.
Please help. Thanks in advance.
What you describe is drag & drop only. You need to implement this.
handle the left mouse click, mouse move & left mouse up events for each of the controls you want to allow to be moved.
in the left mouse click event handler:
set a flag "drag_on" to True
in the mouse move event handler
check if "drag_on" is true, if false, return.
if drag_on is true, then set the control position (x, y) same as the mouse position.
you will get the mouse position from the parameter of the event handler
in the mouse up event, set drag_on to false. Also set the control position to that of mouse position.
Note:
you will need to transform the mouse position to the grid.
Get Absolute Position of element within the window in wpf
instead of setting the control position to the mouse position, you can also try setting the mouse position as the center of the control (homework for you).
I have a form with child controls.
I want when user move mouse over the form, the form will be closed.
So I catch mouse enter and move leave on the form. But if I move mouse on any controls in form, mouse leave event will be also caught.
Please help me to solve this problem. Thanks.
UPDATE:
When the cursor's position is on the form's caption region (this region is called non-client region). I move mouse out of this region, I can't receive the WM_MOUSELEAVE message as well as WM_NCMOUSELEAVE. Please help me in this problem. I want to receive a message when move mouse out of this region. Thanks.
Essentially you want to check if the cursor is in the scope of the control. Here is the solution:
(1) Add a Panel in the form which is the same size as your Form, and move all controls in the form to the panel. It's easy to change: open MyForm.designer.cs, add the panel, and change all statements like this.Controls.Add(myLabel); to this.myPanel.Controls.Add(myLabel);.
(2) Deal with MouseEnter and MouseLeave events of the panel you added.
myPanel.MouseEnter += (sender, e) =>
{
//enter
};
myPanel.MouseLeave += (sender, e) =>
{
if (Cursor.Position.X < myPanel.Location.X
|| Cursor.Position.Y < myPanel.Location.Y
|| Cursor.Position.X > myPanel.Location.X + myPanel.Width
|| Cursor.Position.Y > myPanel.Location.Y + myPanel.Height)
{
//out of scope
}
};
(3) Why not use Form in step 2? Why do we need a Panel with the same size? Try it yourself. The narrow border of the form will make you crazy.
(4) You can make the if statements in step 2 to an extension method, which is helpful to furthur usage.
this is happening because you have gap between your child Controls on leaving from controls the form_mouseEnter event fires automatically
a way you can do like placing controls with no gap
or
If you don't want user to leave your Control you can set boundary of cursor
use this
Cursor.Clip=Control_name.Bounds;
I am using an old ActiveX control in my C# Win App.
it has a MouseUp event that its eventArgs is passing the X and Y of the point that we have clicked but for my scenario I am using its ItemClick event and its eventArgs does not have the info about X and Y.
but I need to know them to show my pop-up... so is there a way I can find out what is the location of X and Y that user has right-clicked so I can pass it to my contextMenuStrip.Show method.
Thanks
The Control class has a static readonly MousePosition property, this gives the mouse coordinates on the screen. You could use this to know where to position the ContextMenu.
From MSDN:
Control.MousePosition Property
Type: System.Drawing.Point
A Point that contains the coordinates of the
mouse cursor relative to the
upper-left corner of the screen.
Cursor.Position will get you the current screen coordinates of the cursor. For most uses this is good enough, even though the mouse can potentially move between the click and the handler being called.
You need to get the cursor position which gets the screen position, then call pointToClient from within the control to get the relevant point to the control. Aka. 0,0 is the top left of the control.
this.PointToClient(Cursor.Position);
+1 to other answers for leading me in the right direction.
I want to show a tooltip when hovering over a button and as long as the mouse is over the button the tooltip should follow the mouse. What is the correct way to achieve that?
When I add a MouseMove event that calls tooltip.Show(...) with the updated mouse position it flickers extremely, and also redraws the tooltip when the mouse rests. And if it is an OwnerDraw tooltip I can see the default system tooltip style "fighting" with the self-drawn tooltip.
Indeed, with .Net 2.0 the ToolTip object has been altered. Before 2.0, there were some inconsistency problems when the ToolTip text was changed while the ToolTip was active, or with some other situations.
Since 2.0, the Tooltip is hidden each time something happens what could affect the currently active Tooltip.
While this solved some problems, it now causes some events being fired right after e.g. a SetToolTip(), even if this function has been called from within this very event, resulting in an endless loop of ToolTip draw/hide until the mouse moves away from the ToolTip area.
My own workaround is to check whether the ToolTip is already the same and omitting the Set ToolTip() if so. (simply omitting the next event by a static flag as suggested above can cause problems as there is no guarantee that there will be a new event right after, e.g. if the mouse has just touched the ToolTip area and moved away already).
Also, using OnMouseHover just to display a Tooltip disables the internal timer functionality of the ToolTip component as well as causing many many unnecessary events and therefore wastes processor time. The Popup Event of the ToolTip component serves well as point of action.
In this special case, however, OnMouse Hover is necessary to track the mouse movement.
Anyways, altering the ToolTip position causes a complete redraw of the Tooltip and therefore flicker. This can be reduced for a motionless mouse by checking whether the mouse position has changed between two events.
Unfortunately, the ToolTip component has no way to change the position of the ToolTip adn is shown always relative to the current mouse position. So the only way to have it follow the mouse is to close and redraw it.
it MAY help to set the UseFading and/or UseAnimation properties to false so the flicker can be further reduced.
OK, this may be complete overkill, and probably not the best solution, but I think a fun little hack nonthless.
Basically, I'm drawing a ListView at the location of the mouse. Some code:
ListView v = new ListView();
public Form1()
{
InitializeComponent();
v.Items.Add("Foo");
v.Height = 30;
v.Width = 50;
this.button1.Controls.Add(v);
v.MouseMove += new MouseEventHandler(v_MouseMove);
v.BackColor = SystemColors.Info;
this.button1.MouseMove += new MouseEventHandler(button1_MouseMove);
}
void v_MouseMove(object sender, MouseEventArgs e)
{
v.Location = new Point(v.Location.X + e.Location.X, v.Location.Y + e.Location.Y);
}
void button1_MouseMove(object sender, MouseEventArgs e)
{
v.Location = e.Location;
}
I've noticed that when manually showing a tooltip with OnMouseHover, OnMouseMove gets called one more time after the tooltip is shown. As a hack, I've ignored the next OnMouseMove call immediately following the tooltip being shown (using a flag). Perhaps a similar phenomenon is occurring?