簡體   English   中英

在圖片框上拖動字符串-C#

[英]Drag string on picturebox - C#

我有一個圖片框,並通過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);
    }
}

對於這樣的任務,使用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;
}

更新 :對於使用透明的backColor Label :需要注意的是,在設計時將標簽拖放到pictureBox上時,標簽的Parent將是pictureBox容器而不是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上繪制要糟糕得多(由閃爍引起),就像之前的代碼一樣。 您應該考慮自己選擇它們,前面的代碼似乎有點復雜(但如果您理解的話,實際上並不太復雜)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM