在ClientSizeChanged之后重绘面板内容

时间:2014-01-10 12:44:36

标签: c# .net winforms

所以我的应用程序在固定大小的窗口和全屏运行。我面临的问题是如何在调整窗口大小时正确缩放面板的当前内容(这取决于应用程序的使用)。这是我目前的代码:

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(),则会清除绘制的内容(面板重绘为空)。我错过了什么?

3 个答案:

答案 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的答案,因为它提供了一个有效的替代方案并且是完整的。