我有一个图片框,我在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);
}
}
答案 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上绘制更糟糕(由闪烁引起),就像之前的代码一样。您应该考虑自己在它们之间进行选择,之前的代码看起来有点复杂(但如果您理解它,则不是真的。)