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可能是下一个你没有发布代码的罪魁祸首,但它可能也在创建一个新的图像。这些图片到底有多大?