2013-12-01 3 views
1

У меня есть окно с изображением, и я рисую на нем строку DrawString(). Я меняю положение строки, прокручивая TrackBar. Но я хочу переместить строку, просто нажав на строку, а затем перетащив ее. Это будет проще для любого пользователя. Может ли кто-нибудь помочь мне достичь этого?Перетащите строку на картинке - C#

Edit: Я уже пошевелить pictureBox1 мою мышь:

private void pictureBox1_Paint(object sender, PaintEventArgs e) 
{ 
    e.Graphics.DrawImage(img, 0, 0); 
    e.Graphics.DrawString(str, font, new SolidBrush(color), new PointF(NinjaClass.NINJA.pointX, NinjaClass.NINJA.pointY)); 
} 
private void pictureBox1_MouseDown(object sender, MouseEventArgs e) 
{ 
    if (e.Button == MouseButtons.Left) 
    { 
     x = e.X; 
     y = e.Y; 
    } 
} 
private void pictureBox1_MouseMove(object sender, MouseEventArgs e) 
{ 
    if (e.Button == MouseButtons.Left) 
    { 
     pictureBox1.Left += (e.X - x); 
     pictureBox1.Top += (e.Y - y); 
    } 
} 
+0

Нет простого механизма перемещения пикселей. Вы можете легко перемещать ярлык. Проверьте [этот ответ] (http://stackoverflow.com/a/9387562/17034) для следующего вопроса. –

ответ

2

Использованием 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, как это делал предыдущий код. Вы должны сами выбирать между собой, предыдущий код кажется немного сложным (но не совсем, если вы его понимаете).

+0

Кажется замечательным кодом. Lemme протестируйте это ... –

+0

См. Мой обновленный вопрос. Ваш код конфликтует с моим кодом, я имею в виду, что строка не перемещается правильно. Не могли бы вы обновить свой код, чтобы оба изображения и строку можно было перемещать мышью, перетаскивая мышью по каждому из них? –

+0

@CoolBrain удалить весь ваш код, просто используйте мой код, я надеюсь, что вы правильно зарегистрировали обработчики событий, здесь задействован только ваш pictureBox, никакого другого элемента управления. –

Смежные вопросы