I want to fetch the position of Control in which click event is performed
for this I have tried following code
Xpos = Cursor.Position.X;
Ypos = Cursor.Position.Y;
but this is giving current position of cursor. then I tried following code
MouseEventArgs m = (MouseEventArgs)e;
Xpos=m.X;
Ypos=m.Y;
but this position is not with respect to whole screen.
How I can get position of control in which click event is performed?
edit
As the link provided for duplicate ,,,,It provides position of point where click action is performed,,,,It does not provide the position of control in which click is performed.
If your project is in WindowsFormApplicaiton then
If your control is button like in screen shot
Then you can access its location wrt to its primary screen also and form screen also
Below is the code
private void button1_Click(object sender, EventArgs e)
{
//This code gives you the location of button1 wrt your primary working screen
Point location = this.PointToScreen(button1.Location);
int x1 = location.X;
int y1 = location.Y;
MessageBox.Show($"X: {x1}, Y: {y1}");
//This code gives you the location of button1 wrt your forms upper-left corner
Point relativeLoc = new Point(location.X - this.Location.X, location.Y - this.Location.Y);
int x2 = relativeLoc.X;
int y2 = relativeLoc.Y;
MessageBox.Show($"X: {x2}, Y: {y2}");
//This code gives you the location of button1 wrt your forms client area
Point relativeLoc1 = new Point(button1.Location.X, button1.Location.Y);
int x3 = relativeLoc1.X;
int y3 = relativeLoc1.Y;
MessageBox.Show($"X: {x3}, Y: {y3}");
}
In above code I used this, you can use any forms object instead as your need
Edit:
If you don't know where your control will be clicked then you have to register one event for all of your controls inside forms like
In below code i used MouseHover event but you can used any event as your need
First of all register MouseHover event for all of your controls inside Form1_Load like
private void Form1_Load(object sender, EventArgs e)
{
foreach (Control c in this.Controls)
c.MouseHover += myMouseHoverEvent;
}
Then your custom MouseHover event is
private void myMouseHoverEvent(object sender, EventArgs e)
{
Control control = sender as Control;
int x = control.Location.X;
int y = control.Location.Y;
MessageBox.Show($"X: {x}, Y: {y}");
}
Try once may it help you
Can you try this? It should return what you're expecting (Left Top Point of the control you click).
XAML:
<TextBlock Text="Sample" Width="100" Height="50"
MouseLeftButtonDown="TextBlock_MouseLeftButtonDown"/>
XAML.cs
private void TextBlock_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
var control = sender as FrameworkElement;
var positionToScreen = control.PointToScreen(new Point(0, 0));
}
This code should solve your problem if you let this event handler handle the MouseClick event of all the controls you are interested in.
If you want to include the position inside the clicked control. Then add the position included in the mouse event args (Se comment in code).
private void control_MouseClick(object sender, MouseEventArgs e)
{
Control control = sender as Control;
int posX = control.Location.X;
int posY = control.Location.Y;
//Add e.X respectivly e.Y if you want to add the mouse position within the control that generated the event.
while (control.Parent != null)
{
control = control.Parent;
posX += control.Location.X;
posY += control.Location.Y;
}
((Label)sender).Text = "X: " + posX + " Y: " + posY;
}
Related
I have a picture in PNG with transparent and normal color.
I use this for one Button:
this.Button1.BackColor = System.Drawing.Color.Transparent;
this.Button1.BackgroundImage = Image;
this.Button1.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.Button1.FlatAppearance.BorderSize = 0;
this.Button1.FlatAppearance.MouseDownBackColor = System.Drawing.Color.Transparent;
this.Button1.FlatAppearance.MouseOverBackColor = System.Drawing.Color.Transparent;
this.Button1.FlatStyle = System.Windows.Forms.FlatStyle.Flat;
this.Button1.Location = new System.Drawing.Point(0, 0);
this.Button1.Margin = new System.Windows.Forms.Padding(0);
this.Button1.Name = "Skin";
this.Button1.Size = new System.Drawing.Size(294, 194);
this.Button1.TabIndex = 7;
this.Button1.UseVisualStyleBackColor = false;
And I when I click at transparent area, it still counts as a click on the Button.
How can I make this Button only call click event when I click at the colored area?
And when I click at the transparent area, I want it to count as a click on the object behind this button.
You have two options:
Use a Button with a Region.
Use a Button with a BackgroundImage and check what the user hits with each Click
Option one is only feasible if you can create a Region, which takes a GraphicsPath, which means that you need to create the shape you need from the Graphics primitves like lines and curves etc..
If you only have a Bitmap with transparency, you are better off not using a Button with a Region.
Instead you can use your Button1 and on every click you check the transparency of the clicked pixel.
If it is transparent you call the click event of the control below it..
private void Button1_MouseClick(object sender, MouseEventArgs e)
{
Size r = Button1.BackgroundImage.Size;
// check that we have hit the image and hit a non-transparent pixel
if ((e.X < r.Width && e.Y < r.Height) &&
((Bitmap)Button1.BackgroundImage).GetPixel(e.X, e.Y).A != 0)
{
Console.WriteLine("BUTTON clicked"); // test
// do or call your click actions here!
}
// else pass the click on..
else
{
// create a valid MouseEventArgs
MouseEventArgs ee = new MouseEventArgs(e.Button, e.Clicks,
e.X + Button1.Left, e.Y + Button1.Top, e.Delta);
// pass it on to the stuff below us
pictureBox1_MouseClick(pictureBox1, ee);
Console.WriteLine("BUTTON NOT clicked"); // test
}
}
Note that the check assumes that you have a normal layout, with the button image at the top left and no scaling. If you need to scale the image you should keep a scaled bitmap to do the checks on.. But if you can use an unscale image you should do so, as this will look better.
Note how I create a correct MouseEventArgs parameter for the control below, so you can access the button or the location of the mouse there as well..
Also note that it is easier to use the MouseClick event instead of the Click event as it has the mouse location already..
If you need/want to use the Click event instead, you can skip creating the EventArgs, as it doesn't have meaningful data; just pass out the e from the click..
Here is how the Click event could start:
private void Button1_Click(object sender, EventArgs e)
{
// we need the location of the clicked pixel:
Point clickLocation = Button1.PointToClient(Control.MousePosition);
// the rest can proceed as above, just with simple EventArgs..
If you want to the check on all mouse clicking event and pass each of them down to the parent you will have to code them all.
First let's look at the order of events on MSDN
MouseDown event.
Click event.
MouseClick
MouseUp event.
So we need to start at the MouseDown. We can do the test in a helper function hitTest, so we can re-use it..:
Button clickedButton = null;
MouseEventArgs ee = null;
void hitTest(Button btn, MouseEventArgs e)
{
Size r = btn.BackgroundImage.Size;
// check that we have hit the image and hit a non-transparent pixel
if ((e.X < r.Width && e.Y < r.Height) &&
((Bitmap)btn.BackgroundImage).GetPixel(e.X, e.Y).A != 0)
{
clickedButton = btn;
ee = new MouseEventArgs(e.Button, e.Clicks, e.X + btn.Left, e.Y + btn.Top, e.Delta);
}
else clickedButton = null;
}
Now we code all four events. We need to call hitTest only once and we pass the simple, unmodified e parameter in the Click event:
private void Button1_MouseDown(object sender, MouseEventArgs e)
{
hitTest(sender as Button, e);
if (sender != clickedButton)
yourParent_MouseDown((sender as Button).Parent, ee);
else // do your stuff
}
private void Button1_Click(object sender, EventArgs e)
{
if (sender != clickedButton)
yourParent_Click((sender as Button).Parent, e);
else // do your stuff
}
private void Button1_MouseClick(object sender, MouseEventArgs e)
{
if (sender != clickedButton)
yourParent_MouseClick((sender as Button).Parent, ee);
else // do your stuff
}
private void Button1_MouseUp(object sender, MouseEventArgs e)
{
if (sender != clickedButton)
yourParent_MouseUp((sender as Button).Parent, ee);
else // do your stuff
}
Of course you need to code all four events for yourParent also..
I'm creating a simple application that draws a horizontal and a vertical line following the mouse.
The form is transparent using TransparencyKey, and the lines are drawn using the Paint event:
private void Form1_Paint(object sender, PaintEventArgs e)
{
Pen pen = new Pen(Color.Lime);
e.Graphics.DrawLine(pen, 0, py, this.Size.Width, py);
e.Graphics.DrawLine(pen, px, 0, px, this.Size.Height);
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
px = e.X; // get cursor X pos
py = e.Y; // get cursor Y pos
Invalidate(); // fire Paint event
}
But the MouseMove event only is fired when the mouse is over the lines drawn. How to make the form catch mouse events when transparent? (Only the mouse move, I want the form still click-through)
As you can read here: http://msdn.microsoft.com/en-us/library/system.windows.forms.form.transparencykey%28v=vs.110%29.aspx - "Any mouse actions, such as the click of the mouse, that are performed on the transparent areas of the form will be transferred to the windows below the transparent area". One way to accomplish your goal is to write your own method, that will check the cursor relative position to the form in a loop, here's what I mean (it worked for me with TransparencyKey, resizing and moving the form):
private void MouseMovedWithTransparency()
{
Point lastCursorPos = new Point(-1, -1); // Starting point.
while (this.Visible)
{
Point currentCursorPos = Cursor.Position;
if (this.ContainsFocus && currentCursorPos.X > this.Left && currentCursorPos.X < this.Left + this.Width &&
currentCursorPos.Y > this.Top && currentCursorPos.Y < this.Top + this.Height)
{
if ((currentCursorPos.X != lastCursorPos.X) || (currentCursorPos.Y != lastCursorPos.Y))
{
// Do actions as in MouseMoved event.
// Save the new position, so it won't be triggered, when user doesn't move the cursor.
lastCursorPos = currentCursorPos;
}
}
Application.DoEvents(); // UI must be kept responsive.
Thread.Sleep(1);
}
}
All you have to do now is to invoke this method from the Shown event - this.Visible has to be true, so it's the easiest way to make it work.
The idea is that in my program i have a button. When i click the button its drawing in the picutreBox1 paint event the point and add it on the pictureBox1 center + 10 pixels randomly around the center.
For example I clicked 5 times in a row and I see now 5 points.
In the button1 click event I also add the button location X,Y to two Lists<>
List<> X have the X location of the button and Y the Y location.
Now in the mouse down event I'm calculating the nearest point to the mouse location when I click the pictureBox1 and I also check if the lowest value distance is lower then 50 so if I click on a point ill be able to drag the point around the pictureBox1 but only if I clicked on the point somewhere between the point center and 5 pixels from the center. That way I know which point I want to drag.
In the mouse down event I also get the index of the lowest value distance and I set a flag movePoint to true and then in the mouse move event I update all the time the selectedIndex so only the selected clicked point will move. in the mouse move event I also check if the flag movePoint is true and then only start the movement.
In the mouse up I update once again the selectedIndex with the mouse location.
And I also set the flag movePoint to false.
The problem is when I'm running the program add one or more points but i don't click with the mouse on a point I click on EMPTY SPACE somewhere in the pictureBox1 and just click on it once or click and try to drag this empty space nothing happens since the flag movePoint is false.
** But in fact for some reason something does happen and if i click and drag empty space in the pictureBox1 area and then i click on one of the points and try to drag them the point jump to the location of where i dragged the empty space before !
I cant figure out why it happen. **
Its like I drag nothing its empty space i also don't see any point move. But then when I try to drag a point its jumping or another point is jumping to the location of where I ended dragging the empty space !!!!
This is the code of the mouse down mouse move mouse up and the paint events:
private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
// find the index that is closest to the current mouse location
float MinDist = float.MaxValue;
for (int idx = 0; idx < Point_X.Count; ++idx)
{
float dx = Point_X[idx] - e.X;
float dy = Point_Y[idx] - e.Y;
float dist = (float)Math.Sqrt(dx * dx + dy * dy);
if (dist < MinDist)
{
MinDist = dist;
selectedIndex = idx;
}
}
if (MinDist < 5)
{
mouseMove = true;
OriginalX = Point_X[(int)selectedIndex];
OriginalY = Point_Y[(int)selectedIndex];
}
}
}
private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
{
if (mouseMove == true)
{
Point NewPoint = e.Location;
Point_X[(int)selectedIndex] = NewPoint.X;
Point_Y[(int)selectedIndex] = NewPoint.Y;
pictureBox1.Refresh();
}
}
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
Point NewPoint = e.Location;
Point_X[(int)selectedIndex] = NewPoint.X;
Point_Y[(int)selectedIndex] = NewPoint.Y;
mouseMove = false;
}
private void pictureBox1_Paint(object sender, System.Windows.Forms.PaintEventArgs e)
{
Graphics g = e.Graphics;
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
SolidBrush brush = new SolidBrush(Color.Red);
for (int idx = 0; idx < Point_X.Count; ++idx)
{
Point dPoint = new Point((int)Point_X[idx], (int)Point_Y[idx]);
dPoint.X = dPoint.X - 5; // was - 2
dPoint.Y = dPoint.Y - 5; // was - 2
Rectangle rect = new Rectangle(dPoint, new Size(10, 10));
g.FillEllipse(brush, rect);
}
}
** I made a small video yesterday that show the problem. look from the beginning but the problem start at second 17-19 thats where i click and drag empty space in the pictureBox1 and then try to drag the points again and cant move them and if i cant move one of them the other points jump to the location of the empty space i dragged.
http://www.youtube.com/watch?v=qZr6wdF8MNA&feature=youtu.be **
The method private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
Should contain the logic
if (mouseMove == true)
{
//Do stuff
}
That should fix the issue.
I want to get the mouse position with respect to the control in which mouse pointer is present. That means when I place the cursor to the starting point (Top-Left corner) of control it should give (0,0). I am using the following code:
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
this.Text = Convert.ToString(Cursor.Position.X + ":" + Cursor.Position.Y);
}
But this gives the position with respect to the screen not to the control.
Code sample will be appreciated.
Use Control.PointToClient to convert a point from screen-relative coords to control-relative coords. If you need to go the other way, use PointToScreen.
You can directly use the Location property of the MouseEventArgs argument passed to your event-handler.
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
Text = e.Location.X + ":" + e.Location.Y;
}
The following will give you mouse coordinates relative to your control. For example, this results in (0,0) if mouse is over top left corner of the control:
var coordinates = yourControl.PointToClient(Cursor.Position);
One can use following methods for getting the relative from absolute and absolute from relative coordinates:
Point Control.PointToClient(Point point);
Point Control.PointToScreen(Point point);
Cursor.Position return Point on Screen, but Control.PointToClient(Cursor.Position) returns point on control (e.g. control -> panel). In your case, you have e.Locate which return point on control.
private void panel1_MouseMove(object sender, MouseEventArgs e)
{
Text = panel1.PointToClient(Cursor.Position).ToString();
}
Simply subtract from the cursor position the Left and Top coordinates of the control:
this.Text = Convert.ToString(
Cursor.Position.X - this.Left + ":" +
Cursor.Position.Y - this.Top);
I use MouseLocation and PointToClient to check. And then use it in a timer!
bool IsMouseHover(Control c, Control container)
{
Point p = Control.MousePosition;
Point p1 = c.PointToClient(p);
Point p2 = container.PointToClient(p);
if (c.DisplayRectangle.Contains(p1) && container.DisplayRectangle.Contains(p2))
{
return true;
}
return false;
}
private void lienzo_MouseLeftButtonDown_1(object sender, MouseButtonEventArgs e)
{
Point coordenadas = new Point();
coordenadas = Mouse.GetPosition(lienzo);
string msg = "Coordenadas mouse :" + coordenadas.X + "," + coordenadas.Y;
MessageBoxResult resultado;
string titulo = "Informacion";
MessageBoxButton botones = MessageBoxButton.OK;
MessageBoxImage icono = MessageBoxImage.Information;
resultado = MessageBox.Show(msg, titulo, botones, icono);
}
Where "lienzo" is my canvas panel
Snippet code as following:
private void Control_MouseMove(object sender, MouseEventArgs e)
{
var btn = sender as Button;
var point = e.Location;
point.X += btn.Location.X;
point.Y += btn.Location.Y;
Control findTarget = btn.Parent.GetChildAtPoint(point, GetChildAtPointSkip.Invisible) as Button;
if (findTarget != null)
{
// TO DO
}
}
Where the button is one of many buttons in a hosting panel.
Create af standard Project C# WinForms
Place 2 Textboxes named X and Y, and a Timer object from the toolbox to the Design page
Press [F7] and replace all code with below.
using System;
using System.Windows.Forms;
namespace MousePos
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
timer1.Start();
}
private void Form1_MouseCaptureChanged(object sender, EventArgs e)
{
X.Text = MousePosition.X.ToString();
Y.Text = MousePosition.Y.ToString();
}
}
}
Set Timer.Tick action to "Form1_MouseCaptureChanged"
[F5] Run - and now you have an MosusePos app.
Hi I have a windows form application which i want to move my mouse then dragdrop will function but i have tried using mousemove mouse event to do it , but seems like dragdrop is very sensitive.So what i'm asking is whether is it possible to detect if the mouse cursor moves at least a certain distance away from the current cursor then it does the dragdrop code.
I understand you have a drag & drop code you want to execute only if the mouse has moved a certain distance. If so:
You can hook to the mouse move event once the user has performed the initial action (mouse down on the item to drag ?). Then compare the mouse coordinates on the mouse move event and trigger the "dragdrop code" once the coordinates difference is higher then the arbitrary value you set.
private int difference = 10;
private int xPosition;
private int yPosition;
private void item_MouseDown(object sender, MouseEventArgs e)
{
this.MouseMove += new MouseEventHandler(Form_MouseMove);
xPosition = e.X;
yPosition = e.Y;
}
private void Form_MouseMove(object sender, MouseEventArgs e)
{
if (e.X < xPosition - difference
|| e.X > xPosition + difference
|| e.Y < yPosition - difference
|| e.Y > yPosition + difference)
{
//Execute "dragdrop" code
this.MouseMove -= Form_MouseMove;
}
}
This would execute dragdrop when the cursor moves out of a virtual 10x10 square.
I do not really get your question and the effect you are trying to acheive.
BTW, if my interpretation is correct, you oare trying to do something only if the "drag distance" is grather than a certain amount.
this code below do not use the drag&drop event, but the mouseup, mousedown and mousemove events.
It keeps track of the distance the mouse travels while the left button is pressed.
When the distance is grater than a fixed amount, it changes the mouseCursor(during the dragaction)
When the mouseButton is released, if the dstance traveled is greater than the minimum offset, we perform our fake drop action.
Create a new windows form project and substitute the Form1 autogenerated Class with the one below
Hope this helps.
public partial class Form1 : Form
{
private bool isDragging; //We use this to keep track that we are FakeDragging
private Point startPosition; //The start position of our "Fake" dragging action
private double dragDistance = 0; //The distance(absolute) from the drag action starting point
private const int MINIMUM_DRAG_DISTANCE = 100; //minimum FakeDrag distance.
private Label label1 = new Label();
public Form1()
{
#region Support form generation code
InitializeComponent();
this.label1 = new System.Windows.Forms.Label();
this.label1.AutoSize = true;
this.label1.Location = new System.Drawing.Point(54, 242);
this.label1.Name = "Distance:";
this.label1.Size = new System.Drawing.Size(35, 13);
this.Controls.Add(label1);
this.MouseUp += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseUp);
this.MouseDown += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseDown);
this.MouseMove += new System.Windows.Forms.MouseEventHandler(this.Form1_MouseMove);
#endregion
}
private void Form1_MouseDown(object sender, MouseEventArgs e)
{
//if the mouse button is pressed then
//there's the chanche a dragAction
//is being performed and we take note
//of the position of the click
//(we will use this later on the mouseMove event
//to calculate the distance mouse has traveled
if (e.Button.Equals(MouseButtons.Left))
startPosition = e.Location;
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
///at the mouse up event we can execute code that does something
if (isDragging && dragDistance > MINIMUM_DRAG_DISTANCE)
{
MessageBox.Show("we have fakedragged!\nDo something useful here");
//Do your Drag & Drop code here.
}
///but WE MUST signal our system that the Fake Drag has ended
///and reset our support variables.
this.Cursor = Cursors.Default;
isDragging = false;
dragDistance = 0;
}
private void Form1_MouseMove(object sender, MouseEventArgs e)
{
///when the mouse moves we control if the mouse button is still pressed.
///if it is so, we surely are FakeDragging and we set our boolean to true
///(it will be useful in the mouseUP event).
///Then we calculate the absolute distance the mouse has traveld since the
///user has pressed the left mouseButton.
Point currentPosition = e.Location;
if (e.Button.Equals(MouseButtons.Left))
{
isDragging = true;
dragDistance =
Math.Abs(
Math.Sqrt(
(
Math.Pow(
(currentPosition.X - startPosition.X), 2)
+
Math.Pow(
(currentPosition.Y - startPosition.Y), 2)
)));
}
//we set the label text displaying the distance we just calculated
label1.Text =
String.Format(
"Distance: {0}",
dragDistance.ToString());
Application.DoEvents();
///At last, if the distance il greater than our offset, we change the
///mouse cursor(this is not required in a real case scenario)
if (dragDistance > MINIMUM_DRAG_DISTANCE)
this.Cursor = Cursors.Hand;
else
this.Cursor = Cursors.Default;
}
}