[英]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.