I'm working with GMap in c#. When I click on the map I whant to get the location on the screen from where I'm clicking.
I have a map controller that is called myMap. When I click on the map an event is triggered called myMap_Click(object sender, MouseEventArgs e). If I place an object, in my case a custom form, on the location e.X, e.Y it wont be placed where I click on the screen.
My goal is to desplay a form where I click on the map. I dont care if it follows coordinate if I pan the map or zoom. For now I just want a custom form on the position I click.
How can I get the screen location when I click on the map contoll?
Regards!
It's actually pretty simple!
private void myMap_Click(object sender, MouseEventArgs e)
{
using (Form customForm = new Form())
{
customForm.StartPosition = FormStartPosition.Manual;
customForm.DesktopLocation = MainMap.PointToScreen(e.Location);
customForm.ShowDialog();
}
}
Obviously replace "Form customForm" parts with your equivalents.
Well you can use this also
gMapControl1.MouseClick += new MouseEventHandler(map_mouseCLick);
private void map_mouseCLick(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
var point = gMapControl1.FromLocalToLatLng(e.X, e.Y);
double lat = point.Lat;
double lon = point.Lng;
//this the the values of latitude in double when you click
double newPointLat = lat;
//this the the values of longitude in double when you click
double newPointLong = lon;
}
}
Related
I am making little Windows Forms Application.
I have PictureBox (parent) and Label (child) in it.
The Parent's Mouse Events are working perfectly, but Mouse events generated by child elements are not reflected on the Parent. The Cursor also changes back to its default (arrow).
Is it possible to pass events generated by child Controls, e.g., the MouseEnter event, to the Parent Control?
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
Card.MouseEnter += new EventHandler(Card_MouseEnter);
Card.MouseLeave += new EventHandler(Card_MouseLeave);
Card.MouseDown += new MouseEventHandler(this.Card_MouseDown);
Card.MouseUp += new MouseEventHandler(this.Card_MouseUp);
}
void Card_MouseLeave(object sender, EventArgs e)
{
this.Card.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.card_bg));
this.Rename("Running!");
}
void Card_MouseEnter(object sender, EventArgs e)
{
this.Card.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.card_hover_bg));
}
private void Card_MouseDown(object sender, EventArgs e)
{
this.Card.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.card_click_bg));
}
private void Card_MouseUp(object sender, EventArgs e)
{
this.Card.BackgroundImage = ((System.Drawing.Image)(Properties.Resources.card_hover_bg));
this.Rename("Please Wait...");
}
private void CardName_MouseDown(object sender, MouseEventArgs e)
{
}
void Rename(string args)
{
this.CardName.Text = args;
}
private void CardName_Click(object sender, EventArgs e)
{
}
}
This is what I have This is what I want to achieve
The first animation represents what I have now, the second is what I need to achieve :)
When I'm making pictureBox1.Controls.Add(label1) label1 is
disappearing and I tried bring to front and change color but couldn't
do it. Please if you will have any idea show me in provided code by me
to be understandable for me. Thank you all again and again :)
You'd use code like this, maybe in the Load() event of the Form:
private void Form1_Load(object sender, EventArgs e)
{
Point pt = CardName.Parent.PointToScreen(CardName.Location);
Card.Controls.Add(CardName);
CardName.Location = Card.PointToClient(pt);
}
This keeps the label in the same position as it was, but makes the picturebox the parent.
Not sure where you're going wrong. Here's an example showing it in action. Both the PictureBox (Card) and Label (CardName) are inside a Panel (panel1). Clicking on button2 toggles the visibility of the Card. Clicking on button1 makes Card the Parent of CardName. You can see that at first, only the Card toggles visibility, but after clicking on button1 and setting the Parent, both toggle visibility together since CardName is a Child of Card (it also changes its BackColor to match that of its new Parent):
Code:
public partial class Form1 : Form
{
private void button1_Click(object sender, EventArgs e)
{
Point pt = CardName.Parent.PointToScreen(CardName.Location);
Card.Controls.Add(CardName);
CardName.Location = Card.PointToClient(pt);
}
private void button2_Click(object sender, EventArgs e)
{
Card.Visible = !Card.Visible;
}
}
When I move mouse over label, panel thinks mouse left it and rises
MouseLeave event
Here is how you can tell if the cursor has actually left the BOUNDS of the Panel, as opposed to simply enter a child control within the Panel:
private void panel1_MouseEnter(object sender, EventArgs e)
{
panel1.BackColor = Color.Red;
}
private void panel1_MouseLeave(object sender, EventArgs e)
{
Point pt = panel1.PointToClient(Cursor.Position);
if (!panel1.ClientRectangle.Contains(pt))
{
// we only get in here when the cursor leaves the BOUNDS of panel1
panel1.BackColor = Control.DefaultBackColor;
}
}
First of all, you should build a UserControl as a container for all your objects: it'd make everything simpler (the one I'm using here is actually a UserControl, modified to comply with your current setup).
When a Control other than the PictureBox is interacted with, you can decide whether you want to trigger a similar action on the main Control or perform a different action based on what event has been generated.
▶ When the Mouse Pointer enters you assembled Control, you want to change the default Cursor: then, when one of the Labels raises the Enter event, call the method of the main Control that handles this. An event handler is a method, you can call it.
▶ When a Label is clicked, you don't want to trigger the related action of the main Control: in this case, there's nothing to do, just handle this event and perform the required action.
▶ The Label should be child of the main Control. You're using a PictureBox, which is not a ContainerControl. You can add child controls to it anyway. You need to do this in code, since - as mentioned - the PictureBox is not designed to host Controls, thus you cannot drop one inside it: the Control you drop will be parented with the Container that hosts the PictureBox (your Form, here).
When you set the parent in code, you need to remember that the Location of the child control is relative to the old Parent, so you have to re-define it's position.
E.g: PictureBox.Bounds = (100, 100, 100, 200) / Label.Bounds = (100, 250, 100, 50)
When the PictureBox becomes Parent of your Label, the Label.Location is still (100, 250): so, now, it will be hidden, since it's outside the visible bounds of its new Parent. You have to reposition it in relation to the new host: its new Location should be (0, 150), to keep the previous relative position.
PictureBox.Control.Add(Label);
//[...]
Label.Location = new Point(Label.Left - PictureBox.Left, Label.Top - PictureBox.Top);
=> Label.Location = (100 - 100, 250 - 100) => (0, 150)
Or, centered horizontally:
Label.Location = new Point((PictureBox.Width - Label.Width) / 2, Label.Top - PictureBox.Top);
=> Label.Location = ((100 - 100) / 2, 250 - 100) => (0, 150) // <- Since both have the same Width
Or, using positions relative to the Screen:
var p = Label.PointToScreen(Point.Empty); // Relative to the ClientRectangle (Top/Left = (0, 0))
PictureBox.Controls.Add(Label);
Label.Location = PictureBox.PointToClient(p);
In any case, call BringToFront() after, to ensure that the new child Control is brought on top and anchor the Control, so it will keep its position and its Width will be bound to the Parent Width:
Label.BringToFront();
Label.Anchor = AnchorStyles.Left | AnchorStyles.Bottom | AnchorStyles.Right;
Now, assuming you want to change the Cursor to Cursors.Hand when the Mouse enters your combined Control and reset to default when it leaves it:
▶ You want the Cursor to change shape in any case.
▶ You want to generate different actions when the PictureBox is clicked and when one of the Labels is clicked.
▶ Both Labels can have distinct actions when clicked.
→ In the visual sample, the Label above the PictureBox is named lblTitle, the Label inside the PictureBox, at the bottom, is named lblFooter.
→ The PictureBox is named ImageView.
Setup the handlers:
NOTE: With a UserControl, the events handling, e.g., in relation to MouseEnter, changes in:
// The Parent's MouseEnter calls OnMouseEnter
protected override void OnMouseEnter(EventArgs e)
{
base.OnMouseEnter(e);
this.Cursor = Cursors.Hand;
}
// Child Controls just call the same method
private void Labels_MouseEnter(object sender, EventArgs e) => OnMouseEnter(e);
public Form1()
{
InitializeComponent();
Point p = lblFooter.PointToScreen(Point.Empty);
ImageView.Controls.Add(lblFooter);
lblFooter.Location = ImageView.PointToClient(p);
ImageView_MouseEnter += ImageView_MouseEnter;
ImageView_MouseLeave += ImageView_MouseLeave;
// Not added in the code here, do whatever is needed with this handler
ImageView_Click += ImageView_Click;
lblFooter.MouseEnter += Labels_MouseEnter;
lblFooter.MouseLeave += Labels_MouseLeave;
lblFooter.MouseClick += lblFooter_MouseClick;
lblTitle.MouseEnter += Labels_MouseEnter;
lblTitle.MouseLeave += Labels_MouseLeave;
lblTitle.MouseDown += lblTitle_MouseDown;
lblTitle.MouseUp += lblTitle_MouseUp;
}
private void ImageView_MouseEnter(object sender, EventArgs e) => this.Cursor = Cursors.Hand;
private void ImageView_MouseLeave(object sender, EventArgs e) => this.Cursor = Cursors.Default;
private void Labels_MouseEnter(object sender, EventArgs e)
{
ImageView_MouseEnter(ImageView, e);
// [...]
// Do stuff related to the Labels Enter event
}
private void Labels_MouseLeave(object sender, EventArgs e) {
ImageView_MouseLeave(ImageView, e);
}
private void lblTitle_MouseDown(object sender, MouseEventArgs e) {
// Perform actions when the Mouse button is held down lblTitle
}
private void lblTitle_MouseUp(object sender, MouseEventArgs e) {
// Perform actions when the Mouse button is released
}
private void lblFooter_MouseClick(object sender, MouseEventArgs e) {
// Perform actions on a Mouse Click event on lblFooter
}
I want to allow the user to be able to click and drag on the graph to select the points in that area.
I thought a good way to do this would be to use ZoomEvent, because the newState parameter gives the area of the zoom, and I can simply select the points in that area. Is there a way I can access the values in newState and then cancel the zoom? Can I force it to go back to oldState?
private void trendGraphControl_ZoomEvent(ZedGraphControl sender, ZoomState oldState, ZoomState newState)
{
if (newState.Type == ZoomState.StateType.Zoom) {
selectPointsInArea(newState);
// How can I disable this zoom??
}
}
Actually, the zoom area info that I needed in newState was private. The solution was to save the previous zoom values on mouse down, and then check the new zoom values in the zoom event, before resetting them to the previous values.
double last_x_max, last_x_min, last_y_max, last_y_min;
private bool trendGraphControl_MouseDownEvent(ZedGraphControl sender, MouseEventArgs e)
{
// Save the zoom values
last_x_max = sender.GraphPane.XAxis.Scale.Max;
last_x_min = sender.GraphPane.XAxis.Scale.Min;
last_y_max = sender.GraphPane.YAxis.Scale.Max;
last_y_min = sender.GraphPane.YAxis.Scale.Min;
return false;
}
private void trendGraphControl_ZoomEvent(ZedGraphControl sender, ZoomState oldState, ZoomState newState)
{
if (newState.Type == ZoomState.StateType.Zoom) {
double new_x_max = sender.GraphPane.XAxis.Scale.Max;
double new_x_min = sender.GraphPane.XAxis.Scale.Min;
double new_y_max = sender.GraphPane.YAxis.Scale.Max;
double new_y_min = sender.GraphPane.YAxis.Scale.Min;
selectPointsInArea(new_x_max, new_x_min, new_y_max, new_y_min);
sender.GraphPane.XAxis.Scale.Max = last_x_max;
sender.GraphPane.XAxis.Scale.Min = last_x_min;
sender.GraphPane.YAxis.Scale.Max = last_y_max;
sender.GraphPane.YAxis.Scale.Min = last_y_min;
}
}
Thanks for Ramankingdom's comment for sending me in the right direction.
I have a form that contains a panel. The idea is that when the mouse is hovered over the panel it displays the OpenHand cursor. You can then drag the panel which causes the cursor to change to the Grab cursor. Upon mouse release the Grab cursor should change back to the OpenHand cursor.
Unfortunately, I'm having an issue that if I drag and release my panel (with the mouse within the bounds of the panel), eventually (usually on the second or third go) the Grab cursor will not change back into the OpenHand cursor.
This remains the case even when you move the mouse out of the panel and back in and try dragging and releasing.
Here is my Panel class:
public class MapPanel : Panel
{
private Point MouseDownLocation;
private Cursor OpenHand = new Cursor(Properties.Resources.hand.Handle);
private Cursor Grab = new Cursor(Properties.Resources.punch.Handle);
public MapPanel()
{
MouseDown += new MouseEventHandler(mapPanel_MouseDown);
MouseUp += new MouseEventHandler(mapPanel_MouseUp);
MouseMove += new MouseEventHandler(mapPanel_MouseMove);
}
private void mapPanel_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Cursor = Grab;
MouseDownLocation = e.Location;
}
}
private void mapPanel_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Cursor = OpenHand;
}
}
private void mapPanel_MouseMove(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
{
Left = e.X + Left - MouseDownLocation.X;
Top = e.Y + Top - MouseDownLocation.Y;
}
}
}
Interestingly there are no issues if I don't include the MouseMove handler, however the Cursor = OpenHand; statement inside the MouseUp method does still get called with the MouseMove handler included. It just doesn't take effect.
Hopefully someone can shed some light on this. Any help would be very much appreciated!
I have a Picture Box with a picture loaded and I want to read the location (as in x,y inside the Picture Box) when I click the image; is this possible ? Even more, can i read these coordinates (Points) when i mouse over ?
I know i have to use the events given (Mouse Click and Mouse Over) but don't know how to read the coordinates where the mouse pointer happens to be.
Though other answers are correct let me add my point to it.
You've pointed that you need to hook up MouseClick or MouseOver events for this purpose. Actually that is no need to hook those events to get Coordinates, you can get the Coordinates in just Click event itself.
private void pictureBox1_Click(object sender, EventArgs e)
{
MouseEventArgs me = (MouseEventArgs)e;
Point coordinates = me.Location;
}
The above code works since Click event's e argument wraps MouseEventArgs you can just cast it and make use of it.
You can get the X and Y coordinates as follows,
this.Cursor = new Cursor(Cursor.Current.Handle);
int xCoordinate = Cursor.Position.X;
int yCoordinate = Cursor.Position.Y;
If you want to get the coordinate within the picture box, use the following code,
private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
{
int xCoordinate = e.X;
int yCoordinate = e.Y;
}
i'll just sum up the answers:
in MouseClick, MouseUp and a lot of other events you have the MouseEventArgs which contains Location of the mouse.
in MouseHover however you don't have MouseEventArgs and therefor, if you need the cursor's location, use Coder example:
private void Form1_MouseHover(object sender, EventArgs e)
{
this.Cursor = new Cursor(Cursor.Current.Handle);
int xCoordinate = Cursor.Position.X;
int yCoordinate = Cursor.Position.Y;
}
What about hooking up the MouseUp event and then getting the location from the MouseEventArgs?
Like this:
private void pictureBox_MouseUp(object sender, MouseEventArgs e)
{
Point mousePointerLocation = e.Location;
}
my program has a picturebox, and I want, apon a mouse click, or on ContextMenuStrip choice, to make something appear at the same spot of the click.
as seen in the picture, i would like to add some kind of a note on the specific clicked date area (probably add a user control)
How do i go at it ? how can i send the click cordinates (x,y) and make something appear at these same coordinates ?
Thanks !
I would create a class which would provide menu items and capture x,y coordinates to have them ready when the item is clicked. Or you can capture these coordinates in an anonymous delegate.
Something like this:
public Form1()
{
InitializeComponent();
MouseClick += new MouseEventHandler(Form1_MouseClick);
}
private void Form1_MouseClick (object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Right)
{
ContextMenuStrip ctxMenu = new ContextMenuStrip();
// following line creates an anonymous delegate
// and captures the "e" MouseEventArgs from
// this method
ctxMenu.Items.Add(new ToolStripMenuItem(
"Insert info", null, (s, args) => InsertInfoPoint(e.Location)));
ctxMenu.Show(this, e.Location);
}
}
private void InsertInfoPoint(Point location)
{
// insert actual "info point"
Label lbl = new Label()
{
Text = "new label",
BorderStyle = BorderStyle.FixedSingle,
Left = location.X, Top = location.Y
};
this.Controls.Add(lbl);
}
An sample code for your requirement, In my below code i am adding button control on mouse click. You can modify the code as per ur need.
int xValue=0, yValue=0;
private void Form1_MouseClick(object sender, MouseEventArgs e)
{
xValue = e.X;
yValue = e.Y;
Button btn = new Button();
btn.Name = "Sample Button";
this.Controls.Add(btn);
btn.Location = new Point(xValue, yValue);
}
you can use either tool tip or use mousemove event. this event will provide you current xy postion of mouse and then you can show your content by either visible true/false at that place or take a label and set its text and then set its xy position according to xy of mouse. and then on mouseleave event move that label to off screen or hide