UserControl and Fliker - Take 2

  • Thread starter Thread starter Martin
  • Start date Start date
M

Martin

Hi everyone !

For those who haven't read my previous post, I have a problem with a
UserControl. When I try to display it on a form, controls seem to
appear one after one. In the following example, it's less visible
because controls don't execute any code... Is someone has an idea of
how I could solve this problem and also improve the method
ShowUserControl. I try to figure out I could flicker effect when I
press the button twice quickly.

Thanks for your help !

----- Form1.cs -----
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication2
{
public class Form1 : Form
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Windows Form Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.splitContainer1 = new
System.Windows.Forms.SplitContainer();
this.button1 = new System.Windows.Forms.Button();
this.splitContainer1.Panel2.SuspendLayout();
this.splitContainer1.SuspendLayout();
this.SuspendLayout();
//
// splitContainer1
//
this.splitContainer1.Dock =
System.Windows.Forms.DockStyle.Fill;
this.splitContainer1.Location = new System.Drawing.Point(0,
0);
this.splitContainer1.Name = "splitContainer1";
//
// splitContainer1.Panel2
//
this.splitContainer1.Panel2.Controls.Add(this.button1);
this.splitContainer1.Size = new System.Drawing.Size(642,
305);
this.splitContainer1.SplitterDistance = 425;
this.splitContainer1.TabIndex = 0;
//
// button1
//
this.button1.Location = new System.Drawing.Point(21, 22);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 0;
this.button1.Text = "button1";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new
System.EventHandler(this.button1_Click);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F,
13F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(642, 305);
this.Controls.Add(this.splitContainer1);
this.Name = "Form1";
this.Text = "Form1";
this.splitContainer1.Panel2.ResumeLayout(false);
this.splitContainer1.ResumeLayout(false);
this.ResumeLayout(false);

}

#endregion

private System.Windows.Forms.SplitContainer splitContainer1;
private System.Windows.Forms.Button button1;


public Form1()
{
InitializeComponent();
}

private void ShowUserControl(UserControl _objUserControl,
Control _objContainer)
{
_objUserControl.Location = new Point(0, 0);
_objUserControl.Size =
new Size(_objContainer.Width, _objContainer.Height);
_objUserControl.Anchor = AnchorStyles.Top |
AnchorStyles.Bottom |
AnchorStyles.Left |
AnchorStyles.Right;

_objContainer.SuspendLayout();

_objContainer.Controls.Clear();
_objContainer.Controls.Add(_objUserControl);

_objContainer.ResumeLayout();
}

private void button1_Click(object sender, EventArgs e)
{
ShowUserControl(new UserControl1(),
splitContainer1.Panel1);
}
}
}

---- UserControl1.cs ----
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace WindowsApplication2
{
public class UserControl1 : UserControl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;

/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be
disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}

#region Component Designer generated code

/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.tableLayoutPanel = new
System.Windows.Forms.TableLayoutPanel();
this.txtStreet = new System.Windows.Forms.TextBox();
this.txtCity = new System.Windows.Forms.TextBox();
this.ddlState = new System.Windows.Forms.ComboBox();
this.ddlCountry = new System.Windows.Forms.ComboBox();
this.txtPostalCode = new System.Windows.Forms.TextBox();
this.lblStreet = new System.Windows.Forms.Label();
this.lblCity = new System.Windows.Forms.Label();
this.lblStateProvince = new System.Windows.Forms.Label();
this.lblPostalCode = new System.Windows.Forms.Label();
this.lblCountry = new System.Windows.Forms.Label();
this.errorProvider = new
System.Windows.Forms.ErrorProvider(this.components);
this.tableLayoutPanel.SuspendLayout();

((System.ComponentModel.ISupportInitialize)(this.errorProvider)).BeginInit();
this.SuspendLayout();
//
// tableLayoutPanel1
//
this.tableLayoutPanel.Anchor =
((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.tableLayoutPanel.ColumnCount = 2;
this.tableLayoutPanel.ColumnStyles.Add(new
System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Absolute,
100F));
this.tableLayoutPanel.ColumnStyles.Add(new
System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent,
100F));
this.tableLayoutPanel.ColumnStyles.Add(new
System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent,
100F));
this.tableLayoutPanel.ColumnStyles.Add(new
System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent,
100F));
this.tableLayoutPanel.ColumnStyles.Add(new
System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent,
100F));
this.tableLayoutPanel.ColumnStyles.Add(new
System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent,
100F));
this.tableLayoutPanel.ColumnStyles.Add(new
System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent,
100F));
this.tableLayoutPanel.ColumnStyles.Add(new
System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent,
100F));
this.tableLayoutPanel.ColumnStyles.Add(new
System.Windows.Forms.ColumnStyle(System.Windows.Forms.SizeType.Percent,
100F));
this.tableLayoutPanel.Controls.Add(this.txtStreet, 1, 2);
this.tableLayoutPanel.Controls.Add(this.txtCity, 1, 3);
this.tableLayoutPanel.Controls.Add(this.ddlState, 1, 4);
this.tableLayoutPanel.Controls.Add(this.ddlCountry, 1, 1);
this.tableLayoutPanel.Controls.Add(this.txtPostalCode, 1,
5);
this.tableLayoutPanel.Controls.Add(this.lblStreet, 0, 2);
this.tableLayoutPanel.Controls.Add(this.lblCity, 0, 3);
this.tableLayoutPanel.Controls.Add(this.lblStateProvince,
0, 4);
this.tableLayoutPanel.Controls.Add(this.lblPostalCode, 0,
5);
this.tableLayoutPanel.Controls.Add(this.lblCountry, 0, 1);
this.tableLayoutPanel.Location = new
System.Drawing.Point(0, 0);
this.tableLayoutPanel.Margin = new
System.Windows.Forms.Padding(0, 3, 0, 3);
this.tableLayoutPanel.Name = "tableLayoutPanel";
this.tableLayoutPanel.RowCount = 6;
this.tableLayoutPanel.RowStyles.Add(new
System.Windows.Forms.RowStyle(System.Windows.Forms.SizeType.Absolute,
15F));
this.tableLayoutPanel.RowStyles.Add(new
System.Windows.Forms.RowStyle());
this.tableLayoutPanel.RowStyles.Add(new
System.Windows.Forms.RowStyle());
this.tableLayoutPanel.RowStyles.Add(new
System.Windows.Forms.RowStyle());
this.tableLayoutPanel.RowStyles.Add(new
System.Windows.Forms.RowStyle());
this.tableLayoutPanel.RowStyles.Add(new
System.Windows.Forms.RowStyle());
this.tableLayoutPanel.Size = new System.Drawing.Size(618,
165);
this.tableLayoutPanel.TabIndex = 0;
//
// txtStreet
//
this.txtStreet.Dock = System.Windows.Forms.DockStyle.Fill;
this.errorProvider.SetIconAlignment(this.txtStreet,
System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
this.txtStreet.Location = new System.Drawing.Point(103,
45);
this.txtStreet.MinimumSize = new System.Drawing.Size(4,
26);
this.txtStreet.Multiline = true;
this.txtStreet.Name = "txtStreet";
this.txtStreet.ScrollBars =
System.Windows.Forms.ScrollBars.Vertical;
this.txtStreet.Size = new System.Drawing.Size(512, 32);
this.txtStreet.TabIndex = 1;
//
// txtCity
//
this.txtCity.Dock = System.Windows.Forms.DockStyle.Fill;
this.errorProvider.SetIconAlignment(this.txtCity,
System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
this.txtCity.Location = new System.Drawing.Point(103, 83);
this.txtCity.Name = "txtCity";
this.txtCity.Size = new System.Drawing.Size(512, 20);
this.txtCity.TabIndex = 2;
//
// ddlState
//
this.ddlState.Dock = System.Windows.Forms.DockStyle.Fill;
this.ddlState.DropDownStyle =
System.Windows.Forms.ComboBoxStyle.DropDownList;
this.ddlState.FormattingEnabled = true;
this.errorProvider.SetIconAlignment(this.ddlState,
System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
this.ddlState.Location = new System.Drawing.Point(103,
109);
this.ddlState.Name = "ddlState";
this.ddlState.Size = new System.Drawing.Size(512, 21);
this.ddlState.TabIndex = 3;
//
// ddlCountry
//
this.ddlCountry.Dock = System.Windows.Forms.DockStyle.Fill;
this.ddlCountry.DropDownStyle =
System.Windows.Forms.ComboBoxStyle.DropDownList;
this.ddlCountry.FormattingEnabled = true;
this.errorProvider.SetIconAlignment(this.ddlCountry,
System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
this.ddlCountry.Location = new System.Drawing.Point(103,
18);
this.ddlCountry.Name = "ddlCountry";
this.ddlCountry.Size = new System.Drawing.Size(512, 21);
this.ddlCountry.TabIndex = 0;
//
// txtPostalCode
//
this.txtPostalCode.Dock =
System.Windows.Forms.DockStyle.Fill;
this.errorProvider.SetIconAlignment(this.txtPostalCode,
System.Windows.Forms.ErrorIconAlignment.MiddleLeft);
this.txtPostalCode.Location = new System.Drawing.Point(103,
136);
this.txtPostalCode.Name = "txtPostalCode";
this.txtPostalCode.Size = new System.Drawing.Size(512, 20);
this.txtPostalCode.TabIndex = 4;
//
// lblStreet
//
this.lblStreet.AutoSize = true;
this.lblStreet.Dock = System.Windows.Forms.DockStyle.Fill;
this.lblStreet.ImeMode =
System.Windows.Forms.ImeMode.NoControl;
this.lblStreet.Location = new System.Drawing.Point(3, 42);
this.lblStreet.Name = "lblStreet";
this.lblStreet.Size = new System.Drawing.Size(94, 38);
this.lblStreet.TabIndex = 0;
this.lblStreet.Text = "lblStreet";
this.lblStreet.TextAlign =
System.Drawing.ContentAlignment.MiddleLeft;
//
// lblCity
//
this.lblCity.AutoSize = true;
this.lblCity.Dock = System.Windows.Forms.DockStyle.Fill;
this.lblCity.ImeMode =
System.Windows.Forms.ImeMode.NoControl;
this.lblCity.Location = new System.Drawing.Point(3, 80);
this.lblCity.Name = "lblCity";
this.lblCity.Size = new System.Drawing.Size(94, 26);
this.lblCity.TabIndex = 0;
this.lblCity.Text = "lblCity";
this.lblCity.TextAlign =
System.Drawing.ContentAlignment.MiddleLeft;
//
// lblStateProvince
//
this.lblStateProvince.AutoSize = true;
this.lblStateProvince.Dock =
System.Windows.Forms.DockStyle.Fill;
this.lblStateProvince.ImeMode =
System.Windows.Forms.ImeMode.NoControl;
this.lblStateProvince.Location = new
System.Drawing.Point(3, 106);
this.lblStateProvince.Name = "lblStateProvince";
this.lblStateProvince.Size = new System.Drawing.Size(94,
27);
this.lblStateProvince.TabIndex = 0;
this.lblStateProvince.Text = "lblStateProvince";
this.lblStateProvince.TextAlign =
System.Drawing.ContentAlignment.MiddleLeft;
//
// lblPostalCode
//
this.lblPostalCode.AutoSize = true;
this.lblPostalCode.Dock =
System.Windows.Forms.DockStyle.Fill;
this.lblPostalCode.ImeMode =
System.Windows.Forms.ImeMode.NoControl;
this.lblPostalCode.Location = new System.Drawing.Point(3,
133);
this.lblPostalCode.Name = "lblPostalCode";
this.lblPostalCode.Size = new System.Drawing.Size(94, 32);
this.lblPostalCode.TabIndex = 0;
this.lblPostalCode.Text = "lblPostalCode";
this.lblPostalCode.TextAlign =
System.Drawing.ContentAlignment.MiddleLeft;
//
// lblCountry
//
this.lblCountry.AutoSize = true;
this.lblCountry.Dock = System.Windows.Forms.DockStyle.Fill;
this.lblCountry.ImeMode =
System.Windows.Forms.ImeMode.NoControl;
this.lblCountry.Location = new System.Drawing.Point(3, 15);
this.lblCountry.Name = "lblCountry";
this.lblCountry.Size = new System.Drawing.Size(94, 27);
this.lblCountry.TabIndex = 0;
this.lblCountry.Text = "lblCountry";
this.lblCountry.TextAlign =
System.Drawing.ContentAlignment.MiddleLeft;
//
// errorProvider
//
this.errorProvider.ContainerControl = this;
//
// AddressUC
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F,
13F);
this.AutoScaleMode =
System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.tableLayoutPanel);
this.DoubleBuffered = true;
this.Name = "AddressUC";
this.Size = new System.Drawing.Size(618, 176);
this.tableLayoutPanel.ResumeLayout(false);
this.tableLayoutPanel.PerformLayout();

((System.ComponentModel.ISupportInitialize)(this.errorProvider)).EndInit();
this.ResumeLayout(false);

}

#endregion

private System.Windows.Forms.TableLayoutPanel tableLayoutPanel;
private System.Windows.Forms.TextBox txtStreet;
private System.Windows.Forms.TextBox txtCity;
private System.Windows.Forms.ComboBox ddlState;
private System.Windows.Forms.ComboBox ddlCountry;
private System.Windows.Forms.TextBox txtPostalCode;
private System.Windows.Forms.Label lblStreet;
private System.Windows.Forms.Label lblCity;
private System.Windows.Forms.Label lblStateProvince;
private System.Windows.Forms.Label lblPostalCode;
private System.Windows.Forms.Label lblCountry;
private System.Windows.Forms.ErrorProvider errorProvider;

public UserControl1()
{
InitializeComponent();
}
}
}
 
Martin said:
In the following example, it's less visible
because controls don't execute any code...

I assume you mean "code in their constructors". What code are you
executing in the controls' constructors? You should do the minimum
amount of work in constructors and do as much of the heavy lifting as
you can when the control is loaded.
 
Hi Bruce,

It's exactly what I mean... Controls don't have any code in their
constructor, OnLoad, etc. Usually, the Country ComboBox load from a SQL
Server Database a list of Countries. The same for the State ComboBox,
but it waits for the Country ComboBox to load its list of state. These
operations are fast...

In my case, controls come out in the following order : txtStreet,
txtCity, txtPostalCode, ddlCountry and ddlState...

Thanks
 
Hi Martin,

Well this time I was able to build the solution :)

I think I see the flicker you're referring to, but it's awfully fast on my
computer. TableLayoutPanel is usually the problem, although it still
renders quickly for such a small control.

It sounds to me like it might be your data-access code that is the bottle
neck (you mentioned it in another post in this thread). If so you might
want to use asynchronous calls to the database or use a BackgroundWorker
component to free up the UI thread while it's loading.

Actually, a better question would be, how much flicker is there? What
exactly do you mean by "appear one after one"? Is it painfully obvious or
is it so quick that it's easy to miss (as in my testing)?

To be perfectly honest, if it's really fast then I don't think that there's
anything you can do about it. That's the price you pay when using Controls
to ease development.
 
Hi Dave,

In the "real version" of my application, I use a lot of UserControl (at
least 4) with the TableLayoutPanel (at least 5)... I'll try to reduce
my use of this TableLayoutPanel... It's an interesting track to
follow... I'll try that and let you know !

Thanks !

Martin
 
Back
Top