所以我的应用程序在固定大小的窗口和全屏运行。我面临的问题是如何在调整窗口大小时正确缩放面板的当前内容(这取决于应用程序的使用)。这是我目前的代码:
private void Form1_ClientSizeChanged(object sender, EventArgs e)
{
System.Drawing.Drawing2D.Matrix transformMatrix = new System.Drawing.Drawing2D.Matrix();
float px = panel2.Width;
float py = panel2.Height;
panel2.Width = this.Width / 2;
panel2.Height = panel2.Width;
panel2.Location = new Point(this.Width - panel2.Width - 30, 30);
transformMatrix.Scale(panel2.Width / px, panel2.Height / py);
panel2.Region.Transform(transformMatrix);
//Rest of the code
}
但是绘制的内容不会缩放,如果我使用Invalidate()
或Refresh()
,则会清除绘制的内容(面板重绘为空)。我错过了什么?
答案 0 :(得分:1)
.NET不记得在面板上绘制的内容,就像那样简单。只要有任何东西使Windows位图缓冲区无效(导致WM_PAINT),它就会再次重新绘制。因此,您必须使用Paint
事件(或重写OnPaint)绘制您想要绘制的内容。
但是,还有另一种方法可能更容易实现 - 不要绘制到Panel中。相反,绘制到PictureBox(或者更确切地说,分配给PictureBox的Image属性的Bitmap)。当图片框无效(和重绘)时,将重复使用位图,因此不会丢失任何内容。通过使用PictureBox.ScaleMode,您可以定义图片框如何缩放位图,并且它将尽可能地这样做。
在任何情况下,转换Region
属性都不起作用 - 您只是更改区域,而不是对绘图本身做任何事情。要使用2D转换矩阵,您希望在绘图期间将其应用于Graphics
对象(在Paint
处理程序或OnPaint
覆盖中) - 在Graphics
对象上绘制任何内容然后转换你想要绘制的所有东西,在你的情况下意味着缩放绘画。
所以你必须决定:你是想用绘制的图像缩放存储的位图,还是想从头开始重绘(这也意味着你可以选择任何级别的细节)? / p>
答案 1 :(得分:0)
我认为您误解了Region
属性的含义。根据{{3}}(empasis mine,在阅读时将'window'替换为'control'):
窗口区域是窗口中操作系统允许绘制的像素集合。操作系统不显示位于窗口区域之外的窗口的任何部分。控件区域的坐标相对于控件的左上角,而不是控件的客户区域。
你正在做的就是改变操作系统允许绘画的区域,这就解释了为什么你没有看到任何东西。我认为您应该在调整表单大小时调整控件的大小,可以通过Anchor
,也可以通过我的Dock
首选项来控制,或者使用 panel ,例如{{} 3}}它将为你处理缩放和相对大小调整。
答案 2 :(得分:0)
感谢您的回答,但我编写了自己的功能和逻辑,以满足此应用程序的需求。基本上该函数检查应用程序变量的状态,并调用最初绘制内容的相应函数,并且由于这些函数使用面板宽度和高度作为参数,因此它们适当地缩放绘制的内容并保留绘图合成。
P.S。我会接受Luaan的答案,因为它提供了一个有效的替代方案并且是完整的。