C# 刷新picturebox会停止需要重新绘制的其他控件
因此,我有这个方向盘控件,当我用鼠标旋转它并刷新图像时,它会阻止我的另一个面板控件绘制其图形,使其无法更新/重画。下面是旋转和重画方向盘的代码C# 刷新picturebox会停止需要重新绘制的其他控件,c#,rotation,C#,Rotation,因此,我有这个方向盘控件,当我用鼠标旋转它并刷新图像时,它会阻止我的另一个面板控件绘制其图形,使其无法更新/重画。下面是旋转和重画方向盘的代码 private readonly Bitmap _originalHelmImage; private Bitmap _newHelmImage; private void HelmPb_MouseDown(object sender, MouseEventArgs e) { if (e.Button != MouseButto
private readonly Bitmap _originalHelmImage;
private Bitmap _newHelmImage;
private void HelmPb_MouseDown(object sender, MouseEventArgs e)
{
if (e.Button != MouseButtons.Left) return;
PictureBox p = (PictureBox) sender;
Bitmap bmp = (Bitmap) p.Image;
//GetPixel works on initial image, not stretched one.
double ratio = (double) p.Image.Width/p.Width;
//Ignore the non-helm portion of the helm.
Color trans = bmp.GetPixel(Convert.ToInt32(ratio*e.X), Convert.ToInt32(ratio*e.Y));
if (trans.A.Equals(0))
{
_dontTurn = true;
return;
}
_offsetAngle = OffsetAngle() - _lastAngleTurn;
_lastAngleTurn = 0;
_dontTurn = false;
}
private double OffsetAngle()
{
int helmXMid = HelmPb.PointToScreen(Point.Empty).X + (HelmPb.Width / 2);
int helmYMid = HelmPb.PointToScreen(Point.Empty).Y + (HelmPb.Height / 2);
double angle = AngleFromPoints(MousePosition, new Point(helmXMid, helmYMid));
return angle;
}
private void HelmPb_MouseMove(object sender, MouseEventArgs e)
{
if ((e.Button != MouseButtons.Left) || _dontTurn) return;
double angle = OffsetAngle();
float degrees = Convert.ToSingle(angle - _offsetAngle);
//float diff = ((360 - degrees) - _deltaHelmTurn%360)%360;
//float diff = (_lastAngleTurn - (degrees - 360)) % 360;
double diff = 90 - angle;
_deltaHelmTurn += Convert.ToSingle(diff - _lastAngleTurn);
if (Math.Abs(_deltaHelmTurn) >= (_maxHelmTurn*360.0))
{
_deltaHelmTurn = Convert.ToSingle(_maxHelmTurn*360.0);
degrees = 0;
}
_lastAngleTurn = Convert.ToSingle(degrees);
_newHelmImage = RotateImage(_originalHelmImage, -degrees);
HelmPb.Image.Dispose();
HelmPb.Image = _newHelmImage;
WaterDepthPlot.Invalidate();
HelmPb.Refresh();
}
double AngleFromPoints(Point pt1, Point pt2)
{
Point p = new Point(pt1.X - pt2.X, pt1.Y - pt2.Y);
double alpha;
if (p.Y == 0) alpha = p.X > 0 ? 0d : 180d;
else
{
double f = 1d * p.X / (Math.Sqrt(p.X * p.X + p.Y * p.Y));
alpha = Math.Acos(f) * 180d / Math.PI;
if (p.Y > 0) alpha = 360d - alpha;
}
return alpha;
}
private Bitmap RotateImage(Bitmap b, float angle)
{
//Create a new empty bitmap to hold rotated image.
Bitmap returnBitmap = new Bitmap(b.Width, b.Height);
//Make a graphics object from the empty bitmap.
Graphics g = Graphics.FromImage(returnBitmap);
//move rotation point to center of image.
g.InterpolationMode = InterpolationMode.HighQualityBicubic;
g.TranslateTransform(b.Width/2F, b.Height/2F);
//Rotate.
g.RotateTransform(angle);
//Move image back.
g.TranslateTransform(-b.Width/2F, -b.Height/2F);
//Draw passed in image onto graphics object.
g.DrawImage(b, new PointF(0.0F, 0.0F));
return returnBitmap;
}
下面是更新我的图表的代码。当方向盘移动时,它永远不会运行。一旦用户停止移动,它就会更新。有没有一种方法可以让它不断更新?我尝试在mousemove事件中抛出面板的刷新/失效,因此每当轮子刷新时,图形也是如此;不走运。有什么建议吗
private void WaterDepthPlot_Paint(object sender, PaintEventArgs e)
{
Pen pen = new Pen(Color.FromArgb(70, 75, 80));
int xOffset = WaterDepthPlot.Location.X;
e.Graphics.DrawLine(pen, new Point(0, 0), new Point(WaterDepthPlot.Width, 0));
e.Graphics.DrawLine(pen, new Point(0, (WaterDepthPlot.Height/5)),
new Point(WaterDepthPlot.Width, (WaterDepthPlot.Height/5)));
e.Graphics.DrawLine(pen, new Point(0, (2*WaterDepthPlot.Height/5)),
new Point(WaterDepthPlot.Width, (2*WaterDepthPlot.Height/5)));
e.Graphics.DrawLine(pen, new Point(0, (3*WaterDepthPlot.Height/5)),
new Point(WaterDepthPlot.Width, (3*WaterDepthPlot.Height/5)));
e.Graphics.DrawLine(pen, new Point(0, (4*WaterDepthPlot.Height/5)),
new Point(WaterDepthPlot.Width, (4*WaterDepthPlot.Height/5)));
e.Graphics.DrawLine(pen, new Point((ThirdXScaleUnit.Location.X - xOffset), 0),
new Point((ThirdXScaleUnit.Location.X - xOffset),
(WaterDepthPlot.Height + WaterDepthPlot.Location.Y)));
e.Graphics.DrawLine(pen, new Point((SecondXScaleUnit.Location.X - xOffset), 0),
new Point((SecondXScaleUnit.Location.X - xOffset),
(WaterDepthPlot.Height + WaterDepthPlot.Location.Y)));
e.Graphics.DrawLine(pen, new Point((FirstXScaleUnit.Location.X - xOffset), 0),
new Point((FirstXScaleUnit.Location.X - xOffset),
(WaterDepthPlot.Height + WaterDepthPlot.Location.Y)));
pen = new Pen(Color.Firebrick);
pen.DashStyle = DashStyle.Dash;
float[] dash = {3, 3};
pen.DashPattern = dash;
double diff = (double) WaterDepthPlot.Height/(5*_depthYScale);
int alertDiff = (int)(_alertDepth * diff);
e.Graphics.DrawLine(pen, new Point(0, alertDiff), new Point(WaterDepthPlot.Width, alertDiff));
pen = new Pen(Color.White);
GraphicsPath gp = new GraphicsPath();
if (_depthCurve.Count < 2) return;
gp.AddCurve(_depthCurve.ToArray());
e.Graphics.DrawPath(pen, gp);
}
private void WaterDepthPlot\u Paint(对象发送器,PaintEventArgs e)
{
钢笔=新钢笔(颜色为argb(70,75,80));
int xOffset=WaterDepthPlot.Location.X;
e、 绘图线(画笔,新点(0,0),新点(WaterDepthPlot.Width,0));
e、 图形.绘图线(钢笔,新点(0,(水深图.高度/5)),
新点(WaterDepthPlot.Width,(WaterDepthPlot.Height/5));
e、 图形.绘图线(钢笔,新点(0,(2*WaterDepthPlot.Height/5)),
新点(WaterDepthPlot.Width,(2*WaterDepthPlot.Height/5));
e、 图形.绘图线(钢笔,新点(0,(3*WaterDepthPlot.Height/5)),
新点(WaterDepthPlot.Width,(3*WaterDepthPlot.Height/5));
e、 图形.绘图线(钢笔,新点(0,(4*WaterDepthPlot.Height/5)),
新点(WaterDepthPlot.Width,(4*WaterDepthPlot.Height/5));
e、 图形.绘图线(钢笔,新点((ThirdXScaleUnit.Location.X-xOffset),0),
新点((ThirdXScaleUnit.Location.X-xOffset),
(WaterDepthPlot.Height+WaterDepthPlot.Location.Y));
e、 绘图线(笔,新点((SecondXScaleUnit.Location.X-xOffset),0),
新点((SecondXScaleUnit.Location.X-xOffset),
(WaterDepthPlot.Height+WaterDepthPlot.Location.Y));
e、 绘图线(笔,新点((FirstXScaleUnit.Location.X-xOffset),0),
新点((FirstXScaleUnit.Location.X-xOffset),
(WaterDepthPlot.Height+WaterDepthPlot.Location.Y));
笔=新笔(颜色:Firebrick);
pen.DashStyle=DashStyle.Dash;
float[]dash={3,3};
pen.DashPattern=破折号;
双差=(双)水深绘图高度/(5*深度刻度);
int-alertDiff=(int)(_-alertDepth*diff);
e、 绘图线(画笔,新点(0,alertDiff),新点(WaterDepthPlot.Width,alertDiff));
钢笔=新钢笔(颜色为白色);
GraphicsPath gp=新的GraphicsPath();
如果(_depthCurve.Count<2)返回;
gp.AddCurve(_depthCurve.ToArray());
e、 图形.绘图路径(笔,总成);
}
您应该处理图形对象。每次鼠标移动都要创建新的位图是很昂贵的——试着只使用一个位图并在上面绘制。没错,我制作了一个全局位图,每次只更新一次。没有解决这个问题,但我明白你的意思@Larstech你也应该发布AngleFromPoints函数,但除非我遗漏了什么,否则这些新位图才是你的问题。我编辑/发布了它。也可通过位图更改进行编辑@但是,你仍然在创建图像<代码>使用(位图bmp=新位图(Properties.Resources.Helm))看起来没有必要。只需在构造函数中加载一次,然后每次都使用该映像。RotateImage可能是下一个你没有发布代码的罪魁祸首,但它可能也在创建一个新的图像。这些图片到底有多大?