编写一个包含一些Graphics的WinForms应用程序。要旋转图像,我使用e.Graphics.RotateTransform(角度)方法,然后绘制图像。几行之后,我调用e.Graphics.RotateTransform(0),这样我就不会旋转其他图像,并且应该看起来很正常。然而,事实并非如此,而且我之后绘制的所有内容似乎都受到相同变换的影响。为什么RotateTransform(0)没有重置转换以使页面恢复正常?
注意:这是我代码中_Paint事件的一个影响,但这正是问题发生的地方。我试图包括任何可能与相关的内容
e.Graphics.TranslateTransform(Chute1Rect.Width / 2 + Chute1Rect.X, Chute1Rect.Height / 2 + Chute1Rect.Y);
if (increasing) //Chute is rotating out of the way
{
e.Graphics.RotateTransform(chuteAngle);
e.Graphics.TranslateTransform(-1 * (Chute1Rect.Width / 2 + Chute1Rect.X), -1 * (Chute1Rect.Height / 2 + Chute1Rect.Y));
e.Graphics.DrawImage(ChuteRotating, Chute1Rect);
//These statements do not seem to be resetting the graphics drawing by the time we do the trains
e.Graphics.TranslateTransform(Chute1Rect.Width / 2 + Chute1Rect.X, Chute1Rect.Height / 2 + Chute1Rect.Y);
e.Graphics.RotateTransform(0);
}
else //Chute is rotating into load position
{
if (chuteAngle == 0) //Chute has rotated into load position
{
e.Graphics.TranslateTransform(-1 * (Chute1Rect.Width / 2 + Chute1Rect.X), -1 * (Chute1Rect.Height / 2 + Chute1Rect.Y));
//Getting here means that the chute can be lifted & lowered because we are rotated down
if (lifting) //Chute is lifting out of the way
{
Chute1SlideRect.Y -= chuteDistance;
Chute2SlideRect.Y -= chuteDistance;
e.Graphics.DrawImage(ChuteSlide, Chute1SlideRect);
e.Graphics.DrawImage(ChuteSlide, Chute2SlideRect);
}
else //Chute is lifting into load position
{
Chute1SlideRect.Y -= chuteDistance;
Chute2SlideRect.Y -= chuteDistance;
e.Graphics.DrawImage(ChuteSlide, Chute1SlideRect);
e.Graphics.DrawImage(ChuteSlide, Chute2SlideRect);
}
e.Graphics.DrawImage(ChuteJoint, Chute1JointRect);
e.Graphics.DrawImage(ChuteJoint, Chute2JointRect);
}
else
{
e.Graphics.RotateTransform(chuteAngle);
e.Graphics.TranslateTransform(-1 * (Chute1Rect.Width / 2 + Chute1Rect.X), -1 * (Chute1Rect.Height / 2 + Chute1Rect.Y));
e.Graphics.DrawImage(ChuteRotating, Chute1Rect);
//These statements do not seem to be resetting the graphics drawing by the time we do the trains
e.Graphics.TranslateTransform(Chute1Rect.Width / 2 + Chute1Rect.X, Chute1Rect.Height / 2 + Chute1Rect.Y);
e.Graphics.RotateTransform(0);
}
}
//Down below here is where the trains get drawn
MSDN文档对此并不明确,但RotateTransform
似乎总是修改现有的转换矩阵,在这种情况下,RotateTransform(0)
的意思是"什么都不做",而不是"将旋转设置回0"。请尝试将其旋转与初始角度相反的角度。
编辑:或者使用ResetTransform()
(文档)将事情恢复到您开始的位置并从那里开始。
终于弄明白了,所以我想我应该发布我的解决方案来帮助别人。我构建了4个方法,这些方法采用参数来保持其比例可伸缩性,并且在执行旋转后绘制任何内容之前,必须调用一个方法来基本重置转换网格。以下是我制作的方法:
#region Methods for Transforms on Bunkers
public void SetRotationTransformation(System.Windows.Forms.PaintEventArgs e)
{
e.Graphics.RotateTransform(chuteAngle);
}
public void InvertRotationTransformation(System.Windows.Forms.PaintEventArgs e, int width, int X, int height, int Y)
{
e.Graphics.TranslateTransform(width / 2 + X, height / 2 + Y);
e.Graphics.RotateTransform(-chuteAngle);
e.Graphics.TranslateTransform(-1 * (width / 2 + X), -1 * (height / 2 + Y));
}
public void SetTranslateTransformation(System.Windows.Forms.PaintEventArgs e, int width, int X, int height, int Y)
{
e.Graphics.TranslateTransform(width / 2 + X, height / 2 + Y);
}
public void InvertTranslateTransformation(System.Windows.Forms.PaintEventArgs e, int width, int X, int height, int Y)
{
e.Graphics.TranslateTransform(-1 * (width / 2 + X), -1 * (height / 2 + Y));
}
#endregion
绘制所在的绘制事件:
#region Draw Bunker
e.Graphics.DrawImage(WeighBin, WeighBin1Rect);
e.Graphics.DrawImage(WeighBin, WeighBin2Rect);
e.Graphics.DrawImage(getLargeLoaderGraphic(chuteAngle), SurgeBin1Rect);
e.Graphics.DrawImage(getLargeLoaderGraphic(chuteAngle), SurgeBin2Rect);
e.Graphics.DrawImage(SurgeBinHat, SurgeBinHatRect);
SetTranslateTransformation(e, Chute1Rect.Width, Chute1Rect.X, Chute1Rect.Height, Chute1Rect.Y);
if (increasing) //Chute is rotating out of the way
{
SetRotationTransformation(e);
InvertTranslateTransformation(e, Chute1Rect.Width, Chute1Rect.X, Chute1Rect.Height, Chute1Rect.Y);
e.Graphics.DrawImage(ChuteRotating, Chute1Rect);
}
else //Chute is rotating into load position
{
if (chuteAngle == 0) //Chute has rotated into load position
{
InvertTranslateTransformation(e, Chute1Rect.Width, Chute1Rect.X, Chute1Rect.Height, Chute1Rect.Y);
//Getting here means that the chute can be lifted & lowered because we are rotated down completely
if (lifting) //Chute is lifting out of the way
{
//Calculate Chute Slide position
Chute1SlideRect.Y -= chuteDistance;
Chute2SlideRect.Y -= chuteDistance;
e.Graphics.DrawImage(ChuteSlide, Chute1SlideRect);
e.Graphics.DrawImage(ChuteSlide, Chute2SlideRect);
}
else //Chute is lifting into load position
{
//Calculate Chute Slide position
Chute1SlideRect.Y -= chuteDistance;
Chute2SlideRect.Y -= chuteDistance;
e.Graphics.DrawImage(ChuteSlide, Chute1SlideRect);
e.Graphics.DrawImage(ChuteSlide, Chute2SlideRect);
if (chuteDistance == 0)
{
if (opening) //Chute is in load position - start opening Gate
{
//Draw the Chute's Gate image second to keep it on top of the Chute's Slide
e.Graphics.DrawImage(ChuteSlideOpen, Chute1SlideOpenRect);
e.Graphics.DrawImage(ChuteSlideOpen, Chute2SlideOpenRect);
//Calculate Chute Gate position
Chute1GateRect.X += gateDistance;
Chute2GateRect.X += gateDistance;
e.Graphics.DrawImage(ChuteGate, Chute1GateRect);
e.Graphics.DrawImage(ChuteGate, Chute2GateRect);
}
else //Begin closing Gate
{
//Draw the Chute's Gate image second to keep it on top of the Chute's Slide
e.Graphics.DrawImage(ChuteSlideOpen, Chute1SlideOpenRect);
e.Graphics.DrawImage(ChuteSlideOpen, Chute2SlideOpenRect);
//Calculate Chute Gate position
Chute1GateRect.X += gateDistance;
Chute2GateRect.X += gateDistance;
e.Graphics.DrawImage(ChuteGate, Chute1GateRect);
e.Graphics.DrawImage(ChuteGate, Chute2GateRect);
}
}
}
//Draw the Chute's Joint graphics AFTER the Chute's Slide so it's on top
e.Graphics.DrawImage(ChuteJoint, Chute1JointRect);
e.Graphics.DrawImage(ChuteJoint, Chute2JointRect);
}
else
{
SetRotationTransformation(e);
InvertTranslateTransformation(e, Chute1Rect.Width, Chute1Rect.X, Chute1Rect.Height, Chute1Rect.Y);
e.Graphics.DrawImage(ChuteRotating, Chute1Rect);
}
}
#endregion
#region Progress Bars
//Position progress bar for bunker material levels + (int)(ChuteHeight * 1.04)
System1ProgressBar.Size = new Size(10, 45);
System2ProgressBar.Size = new Size(10, 45);
var progBar1X = -1 * Loader1Pos + (int)(ChuteWidth / 1.201);
var progBar2X = Loader2Pos + (int)(ChuteWidth / 1.28);
var progBarY = -1 * LoaderY - ChuteHeight / 21;
System1ProgressBar.Location = new Point(progBar1X, progBarY);
System2ProgressBar.Location = new Point(progBar2X, progBarY);
System1ProgressBar.Maximum = 100;
System1ProgressBar.Minimum = 0;
System2ProgressBar.Maximum = 100;
System2ProgressBar.Minimum = 0;
if (!toppedOff)
{
if (System1ProgressBar.Value == System1ProgressBar.Maximum)
{
toppedOff = true;
}
else
{
System1ProgressBar.Increment(+2);
System2ProgressBar.Increment(+2);
}
}
else
{
if(System1ProgressBar.Value == System1ProgressBar.Minimum)
{
toppedOff = false;
}
else
{
System1ProgressBar.Increment(-2);
System2ProgressBar.Increment(-2);
}
}
#endregion
InvertRotationTransformation(e, Chute1Rect.Width, Chute1Rect.X, Chute1Rect.Height, Chute1Rect.Y);
//NOW we can start drawing out trains and they don't flip everywhere - the above //method being called in this spot is what corrects that problem