我有一个Windows窗体(C#.NET 3.5),上面有许多按钮和其他控件,都分配给一个跨越整个窗体的最顶层面板.例如,层次结构为:Form - > Panel - >其他控件.
一旦我将BackgroundImage分配给Panel,控件就会非常缓慢地绘制.如果我使用Form的BackgroundImage属性并将Panel的BackgroundColor设置为"transparent",我会有同样的效果.看起来好像首先绘制了具有背景的窗口,然后在绘制下一个控件之前稍微延迟逐个添加每个控件.换句话说,您实际上可以按照每个控件绘制到窗体的顺序.一旦所有控件都被绘制,一旦此效果不再发生,但表单的响应速度仍然很慢.
在Visual Studio的设计器中,我得到了相同的效果,尤其是在移动控件时.有时表单的绘图完全停止一两秒,这使得在设计器和生成的应用程序中使用BackgroundImage是一个完全的拖拽.
当然,我尝试使用DoubleBuffered = true,我也使用反射在所有控件上设置它,没有任何效果.
此外,这里是加载代码的表单,因为它有点不寻常.它将所有控件从另一个表单复制到当前表单上.这样做是为了能够在共享公共表单和公共代码的基础上使用设计器分别编辑每个屏幕的视觉外观.我预感它可能是减速的原因,但它仍然无法解释为什么减速器已经在设计师中引人注目.
private void LoadControls(Form form)
{
this.SuspendLayout();
this.DoubleBuffered = true;
EnableDoubleBuffering(this.Controls);
this.BackgroundImage = form.BackgroundImage;
this.BackColor = form.BackColor;
this.Controls.Clear();
foreach (Control c in form.Controls)
{
this.Controls.Add(c);
}
this.ResumeLayout();
}
Run Code Online (Sandbox Code Playgroud)
如您所见,SuspendLayout()并ResumeLayout()用于避免不必要的重绘.
尽管如此,一旦使用BackgroundImage,表单就像"地狱一样慢".我甚至尝试将其转换为PNG,JPG和BMP,看看是否有任何区别.此外,图像尺寸为1024x768,但较小的图像具有相同的减速效果(尽管略小).
我该怎么办?
我有一个应用程序,它有很多控件.并且它有大量的闪烁,特别是在启动时.
我将此修复程序应用于它.
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // WS_EX_COMPOSITED
return cp;
}
}
Run Code Online (Sandbox Code Playgroud)
这很有效 - 闪烁的数量减少了令人难以置信的数量.但是,副作用是当我将鼠标移动或单击它们时,窗口右上角的最小化,最大化和关闭按钮不会生成动画(尽管它们仍在工作).这给了应用程序一种感觉.
如何在保留最大化,最小化和关闭按钮的可用性的同时保留WS_EX_COMPOSITED?
这种情况发生在Windows XP上.正如@fallenidol所指出的,这不是Windows 7上的问题.
我目前正在开发一个程序,该程序使用相当复杂的嵌套winform控件结构,当用户进行某些选择时,这些控件会动态更改.有关控件的具体布局的详细信息,请参阅此问题.
在进行选择时,会对由用户控件控制的基础模型进行大量更新.然后,这导致所显示的控件的大小/位置/可见性的一系列相应变化.所有这些变化都会导致屏幕上控件的剧烈闪烁.我需要以某种方式修复此问题,以便每次用户进行选择时,屏幕基本上都会冻结,直到所有控件更新完成.
我试图在许多不同的地方和方式使用Control.SuspendLayout/Control.ResumeLayout方法,我无法消除疯狂的闪烁.我认为在更改期间暂停根控件上的布局会解决问题,但是当更改子控件时,看起来这个SuspendLayout没有帮助.
我是否需要使用其他方法而不是SuspendLayout?有没有办法我可以调试SuspendLayout,看看为什么它似乎没有级联到所有的子控件?
任何人都可以解释它们之间的区别和关系
SetStyle(ControlStyles.UserPaint |
ControlStyles.AllPaintingInWmPaint |
ControlStyles.DoubleBuffer, true)
Run Code Online (Sandbox Code Playgroud)
和
protected override CreateParams CreateParams
{
get
{
CreateParams cp = base.CreateParams;
cp.ExStyle |= 0x02000000; // Turn on WS_EX_COMPOSITED
return cp;
}
}
Run Code Online (Sandbox Code Playgroud)
他们需要减少闪烁,但是何时以及如何正确使用它们?它们可以单独使用,还是必须成对使用,这是什么原因?
谢谢!
积分:
第一个代码片段是从MSDN页面引用的; 在如何修复用户控件中的闪烁中找到第二个代码片段,原始作者是@HansPassant.
在我的应用程序中,我有一个DataGridView控件,显示所选对象的数据.当我选择一个不同的对象(在上面的组合框中)时,我需要更新网格.不幸的是,不同的对象具有完全不同的数据,甚至是不同的列,因此我需要清除所有现有数据和列,创建新列并添加所有行.当这样做时,整个控件可怕地闪烁,需要很长时间.是否有一种通用的方法来使控件处于更新状态,因此它不会重新绘制自身,然后在完成所有更新后重新绘制它?
TreeViews当然可以:
myTreeView.BeginUpdate();
try
{
//do the updates
}
finally
{
myTreeView.EndUpdate();
}
Run Code Online (Sandbox Code Playgroud)
是否有通用的方法与其他控件,特别是DataGridView一起执行此操作?
更新:对不起,我不确定我是否足够清楚.我看到"闪烁",因为在单次编辑后,控件在屏幕上重新绘制,因此您可以看到滚动条缩小等.
这对我来说一直是个问题,我一直试图制作一个透明度好的自定义绘制表单.
这是我现在可以得到的尽可能接近,我在半小时前就开始了..
编辑: 我从头开始制作自定义表单设计和控件,就像我最新的Sunilla http://i.stack.imgur.com/rqvDe.png.我想要在它上面留下一个好的阴影,或者制作另一种看起来有点像窗户的设计.
它将form.opacity设置为0%然后它每隔500毫秒直接抓取一个屏幕图像(屏幕上的任何内容,当前正在运行的程序,桌面等),并将其设置为背景并带来透明度回到100%.所以我可以在上面画任何东西,它看起来很完美!但我得到的唯一问题是当它完成工作时,它会闪烁.是的,我尝试将DoubleBuffering设置为true,没有区别.
听到主要代码:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace TTTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
Opacity = 100;
}
private void button1_Click(object sender, EventArgs e)
{
timer1.Enabled = !timer1.Enabled;
}
private void timer1_Tick(object sender, EventArgs e)
{
Opacity = 0;
Bitmap img = new Bitmap(this.Width, …Run Code Online (Sandbox Code Playgroud) 有没有人知道在调整 datagridview 行和列大小时禁用出现的行的方法。这条线经常闪烁,所以我宁愿自己画一条实线并禁用默认的实线。
我希望通过绘制自己的粗线(我已经完成),它会绘制在默认闪烁的顶部,但不幸的是,两条线都出现了,闪烁的线通常出现在我的实线的右侧或左侧. 我不认为它是相关的,但是用于绘制下面的线的代码。
Private Sub DataGridView1_Paint(sender As Object, e As PaintEventArgs) Handles DataGridView1.Paint
If resizingColumns = True Then
Dim penRed As Pen
penRed = New Pen(color.Red, 3)
Dim cursorPosition As Integer = Me.DataGridView1.PointToClient(New Point(Cursor.Position.X, Cursor.Position.Y)).X
e.Graphics.DrawLine(penRed, cursorPosition, 0, cursorPosition, Me.DataGridView1.Size.Height)
End If
End Sub
Run Code Online (Sandbox Code Playgroud)
我能想到的唯一另一种选择(我真的不想这样做)是将 AllowUserToResizeColumns 设置为 false(这也会隐藏列大小调整线),然后使用鼠标事件以编程方式调整列大小。
任何帮助或指导将不胜感激。
我创建了一个新的Windows窗体应用程序.我将一个按钮拖到表单上.我需要在运行时将此按钮拖放到此表单中的其他位置.任何代码片段或链接都表示赞赏.
我来这里前花了半个小时的时间.
可以通过将"AllPaintingInWmPaint","UserPaint"和"DoubleBuffer"ControlStyles的值设置为"true"(this.SetStyle(ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint | ControlStyles.DoubleBuffer, true))来完成对整个表单的双缓冲.
但是System.Windows.Forms.Panel不会发生这种情况,因为该类不允许我这样做.我找到了一个解决方案:http://bytes.com/topic/c-sharp/answers/267635-double-buffering-panel-control.我也试过这个:Winforms Double Buffering.它是滞后的,即使它用在一个小图纸上,我有一些我在表格中使用的自定义资源和其他东西,因为我不会把整个表格变成一张图纸.第二个似乎会引起问题.还有其他方法吗?
我问这个是因为我不希望在调整表单大小时,面板上的绘图一直闪烁.如果有办法在没有双缓冲的情况下摆脱闪烁,我会很高兴知道.
我有一个填写父表格的小组.
我使用Timer来捕获屏幕,
并将屏幕截图设置为Panel的背景图像.
然而,它会遇到疯狂的闪烁.我该怎么做才能解决它?
//Part of code
public partial class Form1 : Form
{
DxScreenCapture sc = new DxScreenCapture();
public Form1()
{
InitializeComponent();
panelMain.BackgroundImageLayout = ImageLayout.Zoom;
}
private void Form1_Load(object sender, EventArgs e)
{
}
void RefreshScreen()
{
Surface s = sc.CaptureScreen();
DataStream ds = Surface.ToStream(s, ImageFileFormat.Bmp);
panelMain.BackgroundImage = Image.FromStream(ds);
s.Dispose();
}
private void timer1_Tick(object sender, EventArgs e)
{
RefreshScreen();
}
}
Run Code Online (Sandbox Code Playgroud) 我正在做一个大项目。我的表单是form1的mdi容器。form1 加载太慢,我可以看到正在绘制的控件。
每个表单都有一个更新方法,但我仍然有同样的问题。我无法使用任务来创建新表单。
这是我的代码
form1.MdiParent = Me
form1.Show()
Run Code Online (Sandbox Code Playgroud)
我的表单有超过 40 个控件(文本框、标签、网格视图......),是的,它是重用户界面。是否有任何解决方案可以利用并发技术,例如:任务、异步等待?
c# ×9
winforms ×9
.net ×3
flicker ×3
panel ×2
performance ×2
vb.net ×2
createparams ×1
datagridview ×1
layout ×1
refresh ×1
vb.net-2010 ×1