public Form1()
{
InitializeComponent();
this.imgRoom.Click += new EventHandler(this.pictureBox1_Click);
}
private void pictureBox1_Click(object sender, EventArgs e)
{
var label1 = new LabelControl();
label1.Location = MousePosition;
label1.BackColor = Color.Red;
label1.Parent = imgRoom;
label1.Text = "Point";
imgRoom.Controls.Add(label1);
}
When I click in place, which you can see on the attached screen, point appear in another place. How to solve this problem?
MousePosition is in screen coordinates. You need to convert it to client coordinates.
private void pictureBox1_Click(object sender, EventArgs e)
{
var label1 = new LabelControl();
label1.Location = imgRoom.PointToClient(MousePosition); // changed here.
label1.BackColor = Color.Red;
label1.Parent = imgRoom;
label1.Text = "Point";
imgRoom.Controls.Add(label1);
}
Looks like you have to the mouse position relative to the form not the picture box. Try using the pictureBox 'mouseClick' event and then using the mouseEventArgs 'e.Location' property to set your label's Location property.
see - (https://msdn.microsoft.com/en-us/library/system.windows.forms.control.mouseclick(v=vs.110).aspx)
Related
I'm adding a PictureBox to a Form at runtime in C# and it does work (I think). Only problem is I can't change the properties of the PictureBox from outside nor from inside the method, eg. I can't even change the BackColor.
This is my attempt:
private void Form1_Load(object sender, EventArgs e)
{
PictureBox canvas = new PictureBox();
canvas.Dock = DockStyle.Fill;
canvas.BackColor = Color.Red;
}
The PictureBox should now fill the entire Form and have a red background but it doesn't work.
Also, how do I add the PictureBox "publicly" so I can change the properties from another method?
I tried it like this:
PictureBox canvas = new PictureBox
{
Dock = DockStyle.Fill,
BackColor = Color.Red
};
private void button1_Click(object sender, EventArgs e)
{
canvas.BackColor = Color.Red;
} // Now I can use "canvas" in other methods without any errors but still nothing happens
That's good start:
PictureBox canvas = new PictureBox
{
Dock = DockStyle.Fill,
BackColor = Color.Red
};
private void button1_Click(object sender, EventArgs e)
{
canvas.BackColor = Color.Red;
}
But you have to add that box to your form:
private void Form1_Load(object sender, EventArgs e)
{
this.Controls.Add(canvas);
}
Once it's working as expected, you should call canvas field like that: _canvas as this is private field of this class (form).
I've been searching about this for a while and haven't found what I'm looking for.
I want to be able to have an image in a picturebox that can be positioned to a point by means of a "search box". Basically, mapping locations in pixels to certain phrases or letters that then shift the position on the picturebox.
I tried to set the location using points, however this does not change the picture at all; the location after calculating the code below stubbornly stays at (3,3).
The picture also is large (~3500 x ~3000) and needs scrolls bars to fully view it.
Here's my code
public Form1()
{
InitializeComponent();
flowLayoutPanel1.AutoScroll = true;
pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
flowLayoutPanel1.Controls.Add(pictureBox1);
}
private void button1_Click(object sender, EventArgs e)
{
if (textBox1.Text == "m")
{
pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
pictureBox1.Image = Image.FromFile(#"C:\User\Desktop\map.jpg");
pictureBox1.Location = new Point(700, 200);
// ^ The location does not change and stays at (3,3)
// The picturebox is not set as locked
}
Do I need to do something different? Or is the issue with my picture for not allowing me to change the location?
EDIT I found the Solution thanks to the help below. I had to use a panel and place the picturebox within. Below is the code I used.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
panel1.AutoScroll = true;
panel1.Controls.Add(pictureBox1);
pictureBox1.SizeMode = PictureBoxSizeMode.AutoSize;
pictureBox1.Image = Image.FromFile(#"C:\Desktop\image.jpg");
}
private void button1_Click(object sender, EventArgs e)
{
pictureBox1.Visible = true;
label1.Visible = true;
int Hvalue = panel1.HorizontalScroll.Value;
label1.Text = Hvalue.ToString();
label2.Visible = true;
int Vvalue = panel1.VerticalScroll.Value;
label2.Text = Vvalue.ToString();
if (textBox1.Text == "m")
{
// these are just values that I put in
panel1.HorizontalScroll.Value = 616;
panel1.VerticalScroll.Value = 90;
}
}
I've created my own dragable control. The dragging is very simple:
bool moving = false; Point click = new Point(0, 0);
private void _MouseDown(object sender, MouseButtonEventArgs e)
{
moving = true;
click = Mouse.GetPosition(this);
}
private void _MouseUp(object sender, MouseButtonEventArgs e) { moving = false; }
private void _MouseMove(object sender, MouseEventArgs e)
{
if (moving == true)
{
Point po = Mouse.GetPosition(this);
this.Margin = new Thickness(this.Margin.Left + (po.X - click.X), this.Margin.Top + (po.Y - click.Y), 0, 0);
}
}
My problem is that if I drag too fast the cursor "escapes" my control. It's obvious why, however it's not too obvious how to fix this since I can't easily subscribe to every other control's mousemove in the window, and my control is small (about 35,15 px) so this happends a lot. I think that if I can easily force the mouse cursor to stay in the controll that would be a solution(not ideal, though).
So what is the bast way to fix this? How professinoal controls handle this?
P.S. I'm learning WPF, so I'm probably doing some things wrong
Your cursor leaves the usercontrol on fast moves and the MouseMove event will not be triggered anymore.
As said in the comments from the author in Drag Drop UserControls using the MouseMove event of a surrounding Canvas should help.
I've figured it out, it's very simple, using a timer.
bool moving = false; Point click = new Point(0, 0);
System.Timers.Timer _MOVER = new System.Timers.Timer();
public PersonControl()
{
InitializeComponent();
_MOVER.Elapsed += new System.Timers.ElapsedEventHandler((o, v) => { Dispatcher.Invoke(Move); });
_MOVER.Enabled = true;
_MOVER.Interval = 10;
}
private void _MouseDown(object sender, MouseButtonEventArgs e)
{
moving = true;
click = Mouse.GetPosition(this);
Canvas.SetZIndex(this, 100);
_MOVER.Start();
}
private void _MouseUp(object sender, MouseButtonEventArgs e)
{
moving = false;
Canvas.SetZIndex(this, 0);
_MOVER.Stop();
}
private void Move()
{
if (moving == true)
{
Point po = Mouse.GetPosition(this);
this.Margin = new Thickness(this.Margin.Left + (po.X - click.X), this.Margin.Top + (po.Y - click.Y), 0, 0);
}
}
When is try with code, there appear two label and when move, screen become white from where they move. I want single label move with mouse move.
bool mDown = false;
private void label13_MouseMove(object sender, MouseEventArgs e)
{
if (mDown)
{
label13.Location = e.Location;
}
}
private void label13_MouseDown(object sender, MouseEventArgs e)
{
mDown = true;
}
private void label13_MouseUp(object sender, MouseEventArgs e)
{
mDown = false;
}
The e.Location gives you a mouse position relative to the control that is being clicked. So to fix that, instead of
label13.Location = e.Location;
use
var pos = this.PointToClient(Cursor.Position);
label13.Location = new Point(pos.X - offset.X, pos.Y - offset.Y);`
Create the offset variable as a property of the form (type Point) and initialize it on the mouse down event:
offset = e.Location;
I'm working on a program which draws shapes on a panel. I added a vertical scroll bar to the panel but when scrolling the panel, the shapes stays where they are and don't scroll. How can I make these shapes scroll? I'm using this code in the paint handler to update these shapes:
e.Graphics.FillRectangle(Brushes.Red, selectedRect);
on scrolling you should take care of the actual scroll position of the panel and consider this offset when painting your shapes again.
there are examples like this online (not exactly your case but could help to identify the problem):
private int count;
private ArrayList arrayctl = new ArrayList();
private void button1_Click(object sender, System.EventArgs e)
{
TextBox newtxt = new TextBox();
newtxt.Text = count.ToString();
count++; arrayctl.Add(newtxt);
DrawControls();
}
private void DrawControls()
{
System.Drawing.Point CurrentPoint; CurrentPoint = panel1.AutoScrollPosition;
int i = 0;
panel1.Controls.Clear();
panel1.SuspendLayout();
foreach (TextBox txt in arrayctl)
{
panel1.Controls.Add(txt);
txt.Width = panel1.ClientRectangle.Width;
txt.Top = i; i += txt.Height;
}
panel1.ResumeLayout();
panel1.AutoScrollPosition = new Point(Math.Abs(panel1.AutoScrollPosition.X), Math.Abs(CurrentPoint.Y));
}
I have also found this here in SO: Control position inside Windows.Forms.Panel with autoscroll
Don't add a VerticalScrollBar to the panel. The Panel already handles scrolling itself when you set the AutoScrollMinSize property:
Rectangle selectedRect = new Rectangle(16, 16, 64, 28);
private void Form1_Load(object sender, EventArgs e)
{
panel1.AutoScrollMinSize = new Size(panel1.ClientRectangle.Width - SystemInformation.VerticalScrollBarWidth, 1200);
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
e.Graphics.TranslateTransform(panel1.AutoScrollPosition.X, panel1.AutoScrollPosition.Y);
e.Graphics.FillRectangle(Brushes.Red, selectedRect);
}
private void panel1_Scroll(object sender, ScrollEventArgs e)
{
panel1.Invalidate();
}