如何解决在用户控件闪烁 [英] How to fix the flickering in User controls

查看:217
本文介绍了如何解决在用户控件闪烁的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用我不断地从一个控件移动到另一个。我已经没有创建。用户控件,但在导航过程中我得到控制闪烁。它需要1或2秒更新。我试图设置此

In my application i am constantly moving from one control to another. I have created no. of user controls, but during navigation my controls gets flicker. it takes 1 or 2 sec to update. I tried to set this

SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
or
SetStyle(ControlStyles.UserPaint, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true); 
SetStyle(ControlStyles.DoubleBuffer, true);

但它并没有帮助不同的控制......每个控件都有相同的背景图像。
那么,什么是它的解决方案..
结果谢谢。

but it didn't help... Each control has same background image with different controls. So what is the solution for it..
Thanks.

推荐答案

这是不是那种闪烁的双缓冲就可以解决。也不是的BeginUpdate或SuspendLayout。你有太多的控制,和backgroundImage可以使一个的很多的差。

It is not the kind of flicker that double-buffering can solve. Nor BeginUpdate or SuspendLayout. You've got too many controls, the BackgroundImage can make it a lot worse.

在启动时用户控件油漆本身。它绘制的BackgroundImage,留洞那里的孩子控制窗口去。然后,每个子控件获得的消息油漆本身,他们将填补其窗口内容的洞。当你有很多的控制,这些孔给用户一段时间可见。他们通常是白色的,用的BackgroundImage对比不好当它是黑暗的。或者,他们可以是黑色,如果窗体上有其不透明度或TransparencyKey属性集,以公正的东西对立得很厉害。

It starts when the UserControl paints itself. It draws the BackgroundImage, leaving holes where the child control windows go. Each child control then gets a message to paint itself, they'll fill in the hole with their window content. When you have a lot of controls, those holes are visible to the user for a while. They are normally white, contrasting badly with the BackgroundImage when it is dark. Or they can be black if the form has its Opacity or TransparencyKey property set, contrasting badly with just about anything.

这是Windows窗体的pretty根本的限制,被卡住的Windows窗口呈现的方式。通过WPF固定顺便说一句,它不使用窗口的子控件。什么你想要为双缓冲整个窗体,包括子控件。这是可能的,检查我的code在<一个href=\"http://social.msdn.microsoft.com/forums/en-US/winforms/thread/aaed00ce-4bc9-424e-8c05-c30213171c2c/\">this螺纹的解决方案。它具有副作用,虽然,实际上并不增加绘画速度。在code是简单,粘贴在你的形式(而不是用户控件):

This is a pretty fundamental limitation of Windows Forms, it is stuck with the way Windows renders windows. Fixed by WPF btw, it doesn't use windows for child controls. What you'd want is double-buffering the entire form, including the child controls. That's possible, check my code in this thread for the solution. It has side-effects though, and doesn't actually increase painting speed. The code is simple, paste this in your form (not the user control):

protected override CreateParams CreateParams {
  get {
    CreateParams cp = base.CreateParams;
    cp.ExStyle |= 0x02000000;  // Turn on WS_EX_COMPOSITED
    return cp;
  }
} 

有很多事情可以做,以提高绘画速度,闪烁已并不明显了点。通过解决和backgroundImage启动。他们可以的真正的当源图像较大,需要缩水以适应控件昂贵。更改BackgroundImageLayout属性为瓷砖。如果给出了一个明显的加速,回到你的绘画程序,并调整图片的大小要与典型的控制大小更好的匹配。或在UC的onResize受到()方法写code创建图像的适当大小的副本,以便它不会每次都被调整控制重绘。使用Format32bppPArgb像素格式为副本,它呈现比其他像素格式快约10倍。

There are many things you can do to improve painting speed, to the point that the flicker isn't noticeable anymore. Start by tackling the BackgroundImage. They can be really expensive when the source image is large and needs to be shrunk to fit the control. Change the BackgroundImageLayout property to "Tile". If that gives a noticeable speed-up, go back to your painting program and resize the image to be a better match with the typical control size. Or write code in the UC's OnResize() method to create a properly sized copy of the image so that it doesn't have to be resized every time the control repaints. Use the Format32bppPArgb pixel format for that copy, it renders about 10 times faster than any other pixel format.

您可以做的下一件事是prevent从如此明显,与图像对比严重的漏洞。可以turn关闭的UC,即prevents加州大学从在子控件去的区域画标志WS_CLIPCHILDREN样式标志。在该用户的code粘贴此code:

Next thing you can do is prevent the holes from being so noticeable and contrasting badly with the image. You can turn off the WS_CLIPCHILDREN style flag for the UC, the flag that prevents the UC from painting in the area where the child controls go. Paste this code in the UserControl's code:

protected override CreateParams CreateParams {
  get {
    var parms = base.CreateParams;
    parms.Style &= ~0x02000000;  // Turn off WS_CLIPCHILDREN
    return parms;
  }
}

子控件现在将自己绘制的背景图像的顶部。你可能还会看到他们自己画一个接一个,但丑陋的中间白色或黑洞是不可见的。

The child controls will now paint themselves on top of the background image. You might still see them painting themselves one by one, but the ugly intermediate white or black hole won't be visible.

最后但并非最不重要的,降低子控件的数量总是要解决速度慢的问题画一个不错的办法。覆盖UC的的OnPaint()事件和画什么,现在是一个孩子所示。特定标签,图片框是的非常的浪费。方便点,然后单击但它们的重量轻替代(绘制字符串或图像)只需要code一行在你的OnPaint()方法。

Last but not least, reducing the number of child controls is always a good approach to solve slow painting problems. Override the UC's OnPaint() event and draw what is now shown in a child. Particular Label and PictureBox are very wasteful. Convenient for point and click but their light-weight alternative (drawing a string or an image) takes only a single line of code in your OnPaint() method.

这篇关于如何解决在用户控件闪烁的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆