Использованием DrawString
не очень удобно для выполнения такой задачи, вы должны сохранить Rectangle
вокруг строки, обновление, прямоугольник, в соответствии с движение мыши ... Если нам нужно щелкнуть точно на строковой кривой, чтобы переместить строку, используя DrawString
не может помочь. В таком случае мы должны использовать GraphicsPath
, который поддерживает небольшую хитрость. Однако в этом случае мы просто разрешаем пользователю нажимать на границы строк, потому что щелчок по строковой кривой с небольшим шрифтом или даже нормальным шрифтом не является простым и очень раздражающим. Попробуйте следующий код:
//your form constructor
public Form1(){
InitializeComponent();
//add string to the GraphicsPath, the string location is initialized with (10,10)
gp.AddString("Your string goes here", Font.FontFamily,
(int)Font.Style, 20, new Point(10, 10), StringFormat.GenericDefault);
}
GraphicsPath gp = new GraphicsPath();
float dx, dy;
//the Paint event handler for your pictureBox1
private void pictureBox1_Paint(object sender, PaintEventArgs e) {
e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
gp.Transform(new Matrix(1, 0, 0, 1, dx, dy));//Translate and paint
e.Graphics.FillPath(Brushes.Red, gp);
gp.Transform(new Matrix(1,0,0,1,-dx,-dy));//translate back (reset to old location)
}
Point downPoint;
bool hitOn;
//MouseDown event handler for your pictureBox1
private void pictureBox1_MouseDown(object sender, MouseEventArgs e){
if(e.Button == MouseButtons.Left){
downPoint = e.Location;
if (gp.GetBounds(new Matrix(1,0,0,1,dx,dy)).Contains(e.Location)) {
gp.Transform(new Matrix(1, 0, 0, 1, dx, dy));
hitOn = true;
}
}
}
//MouseMove event handler for your pictureBox1
private void pictureBox1_MouseMove(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
if(hitOn){
dx = e.X - downPoint.X;
dy = e.Y - downPoint.Y;
pictureBox1.Invalidate();
} else {
pictureBox1.Left += e.X - downPoint.X;
pictureBox1.Top += e.Y - downPoint.Y;
}
}
}
//MouseUp event handler for your pictureBox1
private void pictureBox1_MouseUp(object sender, MouseEventArgs e) {
hitOn = false;
}
Update: Для использования прозрачного BACKCOLOR Label
: Существует примечание, что когда вы перетащите метку на PictureBox во время разработки, то Parent
этикетки будет pictureBox контейнер не PictureBox, это по дизайну, потому что PictureBox
не предназначен для управления. Таким образом, вы должны установить Parent
с помощью кода, для кода перемещения метки, вы так же, как то, что вы делаете с вашим PictureBox
, разница является родителем PictureBox
ваша форма в то время как родитель label
ваш PictureBox:
public Form1(){
InitializeComponent();
label1.BackColor = Color.Transparent;
label1.Parent = pictureBox1;
//try this to prevent a little flicker, but looks like it does not help much
typeof(Control).GetProperty("DoubleBuffered", System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance)
.SetValue(pictureBox1, true, null);
}
Point lblDownPoint;
//MouseDown event handler for your label1
private void label1_MouseDown(object sender, MouseEventArgs e){
if(e.Button == MouseButtons.Left) lblDownPoint = e.Location;
}
//MouseMove event handler for your label1
private void label1_MouseMove(object sender, MouseEventArgs e){
if(e.Button == MouseButtons.Left) {
label1.Left += e.X - lblDownPoint.X;
label2.Top += e.Y - lblDownPoint.Y;
}
}
Однако, попробовав вместо этого использовать прозрачную метку BackColor, я вижу, что это довольно плохо (вызвано мерцанием), чем рисовать непосредственно на pictureBox, как это делал предыдущий код. Вы должны сами выбирать между собой, предыдущий код кажется немного сложным (но не совсем, если вы его понимаете).
Нет простого механизма перемещения пикселей. Вы можете легко перемещать ярлык. Проверьте [этот ответ] (http://stackoverflow.com/a/9387562/17034) для следующего вопроса. –