拖动图片框上的字符串 - C#

时间:2013-12-01 13:50:38

标签: c# c#-3.0

我有一个图片框,我在DrawString()上画了一个字符串。我通过滚动TrackBar来改变字符串的位置。但我想通过直接单击字符串然后拖动来移动字符串。对任何用户来说都会更容易。任何人都可以帮我实现这个目标吗?

修改:我已经移动了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);
    }
}

1 个答案:

答案 0 :(得分:2)

使用DrawString对于此类任务来说不是很方便,您必须在字符串周围保存Rectangle,根据鼠标移动更新该矩形...如果我们需要完全点击< strong>在字符串曲线上移动字符串,使用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;
}

更新:使用透明的backColor Label:有一个注意事项,当您在设计时将标签拖放到pictureBox上时,Parent的label是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上绘制更糟糕(由闪烁引起),就像之前的代码一样。您应该考虑自己在它们之间进行选择,之前的代码看起来有点复杂(但如果您理解它,则不是真的。)