我的Windows窗体应用程序有一个大的TabControl来选择用户想要做的视图(客户管理,其他特殊列表管理,日志列表等)。每个标签页都没有什么特别的,它只是一堆标准控件,通过TableLayoutPanels和FlowLayoutPanels进行布局。这些是标签,文本框,组合框,列表框等。
当我切换标签页时,我可以直接观看Windows窗体绘制屏幕上的控件。在第一时刻,一些控件的背景似乎被部分绘制,然后是其他区域,然后是文本,以及一些渲染帧,以后所有内容都被绘制和完成。
TabControl上没有事件处理程序,因此没有什么可以延迟切换。标签切换本身很快,它只是一步一步但不是逐步发生的库存控制的呈现。这是用户不应该看到的东西。控件本身也是静态的。我不会在运行时重新安排或动态创建它们。甚至不必是任何内容。我已经可以在我刚设计的新标签页上看到这一点,但尚未填充数据。我从未见过WPF的这种部分更新,它是一个WinForms问题。
这种行为可能是什么原因,我该怎么做才能解决这个问题?是否有可能使用Windows窗体进行原子屏幕更新?
有时我可以使用SuspendLayout和ResumeLayout,但我不会在这里执行任何布局,因此我没有可以将这些调用放入的代码行。它是默认的TabControl行为。
将VS 2010与.NET 4.0一起使用,但这个问题已存在多年。
答案 0 :(得分:0)
您可以明确地看到TableLayoutPanel
和FlowLayoutPanel
的布局流程以及非双缓冲绘画。
首先使用SuspendLayout()
/ ResumeLayout()
轻松解决问题。环绕你的动态控制添加。如果你不改变TableLayoutPanel.Controls集合,那么你可能还需要它来进行第一次绘制(这取决于同谋,太嵌套的容器是有问题的。)
第二个需要一些调整
[System.ComponentModel.DesignerCategory("Code")]
public class XTableLayoutPanel : TableLayoutPanel
{
[DefaultValue(typeof(Color), "Transparent")]
public new Color BackColor
{
get { return base.BackColor; }
set { base.BackColor = value; }
}
public XTableLayoutPanel()
{
// set user paint style
SetStyle(ControlStyles.UserPaint | ControlStyles.ResizeRedraw | ControlStyles.DoubleBuffer | ControlStyles.AllPaintingInWmPaint, true);
BackColor = Color.Transparent;
}
protected override void OnPaint(PaintEventArgs e)
{
// do nothing
}
}
Winform本身就是一个问题,容器(对于可伸缩或可本地化的应用程序来说必不可少)不能很好地适应它的重绘过程。考虑将WPF用于未来的项目,其中布局构建为重绘(如果我可以这样拼写)。