winform自定义控件(UserControl)加载慢的研究


winform项目中,现有一个自定义控件 uc_test , 该控件中又foreach 添加了数个自定义控件 uc_unit ,

项目运行,因用了该控件的form初始化加载慢要很长时间,

分析得出耗时的操作出现在uc_test的初始化(构造函数) 过程

解决办法:

将uc_unit的逻辑,在uc_test用原生代码实现减少自定义控件的使用,效率有点提升,但是没有明显提升
继续分析,得出是foreach循环生成控件慢,继续跟踪得出生成控件时添加了一些事件导致很慢,如果把事件加载去掉,加载就很快了
那么可以先界面显示控件,然后再启用异步设置事件,测试效果还行
 
 

结论:

1. 页面中尽量避免使用大量的自定义控件,特别是 foreach 循环加载
2. 尽量使用代码组合原生的控件来添加到界面
3. 批量控件事件设置采用异步的方法
 
List<Control> childs = new List<Control>();
foreach (var v in dataSource)
{
    var col = this.GenerateItem(v);
    childs.Insert(0, col);
}
panel1.Controls.AddRange(childs.ToArray());
Task.Run(() =>
{
    foreach (var v in childs)
    {
        v.Click += Uc_Click;
    }
});
GarsonZhang www.yesdotnet.com
GenerateItem 方法:
Panel GenerateItem(ItemData item)
{
    Panel panel = new Panel();
    panel.Width = 180;
    panel.Dock = DockStyle.Left;
    panel.Cursor = Cursors.Hand;
    panel.Tag = item;
    //panel.Click += Uc_Click;

    // title
    Label lblTitle = new Label();
    lblTitle.Text = item.Title;
    lblTitle.AutoSize = true;
    lblTitle.Font = new System.Drawing.Font("宋体", 14F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
    lblTitle.Location = new System.Drawing.Point(9, 11);
    //lblTitle.Size = new System.Drawing.Size(150, 19);
    //lblTitle.Click += (sender, obj) => Uc_Click(panel1, obj);
    panel.Controls.Add(lblTitle);

    // num
    Label lbl_Num = new Label();
    lbl_Num.Text = item.NuM;
    lbl_Num.Font = new System.Drawing.Font("宋体", 24F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point, ((byte)(134)));
    lbl_Num.Location = new System.Drawing.Point(9, 33);
    lbl_Num.AutoSize = true;
    //lbl_Num.Click += (sender, obj) => Uc_Click(panel1, obj);
    panel.Controls.Add(lbl_Num);


    FlowLayoutPanel flowLayoutPanel1 = new FlowLayoutPanel();
    flowLayoutPanel1.Location = new System.Drawing.Point(9, 69);
    flowLayoutPanel1.Name = "flowLayoutPanel1";
    flowLayoutPanel1.Size = new System.Drawing.Size(200, 27);
    //flowLayoutPanel1.Click += (sender, obj) => Uc_Click(panel1, obj);
    panel.Controls.Add(flowLayoutPanel1);

    // preTitle
    Label pre1Title = new Label();
    pre1Title.Text = item.Pre1Txt;
    pre1Title.Location = new System.Drawing.Point(3, 0);
    pre1Title.Padding = new System.Windows.Forms.Padding(0, 6, 0, 0);
    pre1Title.AutoSize = true;
    //pre1Title.Click += (sender, obj) => Uc_Click(panel1, obj);

    flowLayoutPanel1.Controls.Add(pre1Title);

    // preNum
    Label pre1Num = new Label();
    pre1Num.Text = item.Pre1Num;
    pre1Num.Location = new System.Drawing.Point(56, 0);
    pre1Num.Padding = new System.Windows.Forms.Padding(0, 6, 0, 0);
    pre1Num.AutoSize = true;
    //pre1Num.Click += (sender, obj) => Uc_Click(panel1, obj);

    flowLayoutPanel1.Controls.Add(pre1Num);
    if (!(String.IsNullOrWhiteSpace(item.Pre1Num) || item.Pre1Num == "-"))
    {
        PictureEdit pictureEdit1 = new PictureEdit();
        pictureEdit1.Properties.Appearance.BackColor = System.Drawing.Color.Transparent;
        pictureEdit1.Properties.Appearance.Options.UseBackColor = true;
        pictureEdit1.Properties.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
        pictureEdit1.Properties.ShowCameraMenuItem = DevExpress.XtraEditors.Controls.CameraMenuItemVisibility.Auto;
        pictureEdit1.Properties.SizeMode = DevExpress.XtraEditors.Controls.PictureSizeMode.Stretch;
        pictureEdit1.Size = new System.Drawing.Size(16, 16);
        if (item.Pre1Type == EnumNumType.UP)
        {
            pictureEdit1.EditValue = global::XQ.AliAdminTool.UI.Properties.Resources.moveup_16x16;
            pre1Num.ForeColor = Color.Red;
        }
        else
        {
            pictureEdit1.EditValue = global::XQ.AliAdminTool.UI.Properties.Resources.movedown_16x16;
            pre1Num.ForeColor = Color.Green;
        }
        flowLayoutPanel1.Controls.Add(pictureEdit1);
    }

    FlowLayoutPanel flowLayoutPanel2 = new FlowLayoutPanel();
    flowLayoutPanel2.Location = new System.Drawing.Point(9, 90);
    flowLayoutPanel2.Name = "flowLayoutPanel1";
    flowLayoutPanel2.Size = new System.Drawing.Size(200, 27);
    //flowLayoutPanel2.Click += (sender, obj) => Uc_Click(panel1, obj);

    panel.Controls.Add(flowLayoutPanel2);

    // preTitle
    Label pre2Title = new Label();
    pre2Title.Text = item.Pre2Txt;
    pre2Title.Location = new System.Drawing.Point(3, 0);
    pre2Title.Padding = new System.Windows.Forms.Padding(0, 6, 0, 0);
    pre2Title.AutoSize = true;
    //pre2Title.Click += (sender, obj) => Uc_Click(panel1, obj);
    flowLayoutPanel2.Controls.Add(pre2Title);

    // preNum
    Label pre2Num = new Label();
    pre2Num.Text = item.Pre2Num;
    pre2Num.Location = new System.Drawing.Point(56, 0);
    pre2Num.Padding = new System.Windows.Forms.Padding(0, 6, 0, 0);
    pre2Num.AutoSize = true;
    //pre2Num.Click += (sender, obj) => Uc_Click(panel1, obj);
    flowLayoutPanel2.Controls.Add(pre2Num);

    if (!(String.IsNullOrWhiteSpace(item.Pre2Num) || item.Pre2Num == "-"))
    {
        PictureEdit pictureEdit = new PictureEdit();
        pictureEdit.Properties.Appearance.BackColor = System.Drawing.Color.Transparent;
        pictureEdit.Properties.Appearance.Options.UseBackColor = true;
        pictureEdit.Properties.BorderStyle = DevExpress.XtraEditors.Controls.BorderStyles.NoBorder;
        pictureEdit.Properties.ShowCameraMenuItem = DevExpress.XtraEditors.Controls.CameraMenuItemVisibility.Auto;
        pictureEdit.Properties.SizeMode = DevExpress.XtraEditors.Controls.PictureSizeMode.Stretch;
        pictureEdit.Size = new System.Drawing.Size(16, 16);
        if (item.Pre2Type == EnumNumType.UP)
        {
            pictureEdit.EditValue = global::XQ.AliAdminTool.UI.Properties.Resources.moveup_16x16;
            pre2Num.ForeColor = Color.Red;
        }
        else
        {
            pictureEdit.EditValue = global::XQ.AliAdminTool.UI.Properties.Resources.movedown_16x16;
            pre2Num.ForeColor = Color.Green;
        }
        flowLayoutPanel2.Controls.Add(pictureEdit);
    }

    return panel;
}
GarsonZhang www.yesdotnet.com

 

 
 

   

版权声明:本文为YES开发框架网发布内容,转载请附上原文出处连接
YES开发框架
上一篇:JSON.stringify 输出格式化文本
下一篇:解决winform使用EF6 第一次查询会慢个几秒钟
评论列表

发表评论

评论内容
昵称:
关联文章

winform定义(UserControl)研究
winform截取图像
WPF开发随笔收录-定义图标
【荐】开源Winform库:花木兰
IIS初始化(预),解决第一次访问,程序池被回收问题
.NET Core 定义中间 Middleware
C# 解析读取XML文件正确姿势
C# Winform 定义异常处理方法
WPF 组织机构摄像机树 全量 大数据量 分页摄像机节点
C# Winform Menustrip中ToolStripMenuItem显示提示框ToolTipText
.NET IIS第一次访问,程序池被回收问题,IIS初始化(启用预)
.net core winform窗体继承后设计器异常,看不到,并且页无法添加
Devexpress GridControl删除中多余无效ColumnEdit组
窗体GridView布局定义
winformOpenFileDialogFilter属性设置
LayoutControl布局使用
网站迁移纪实:从Web Form 到 Asp.Net Core (Abp vNext 定义开发)
从数据库或者其他位置ASP.NET MVC Views 视图 数据库中加 cshtml
[.Net] .NET Reactor授权方法 .NET Reactor定义注册机和获取机器码
MEF会缺少一些dll,

联系我们
联系电话:15090125178(微信同号)
电子邮箱:garson_zhang@163.com
站长微信二维码
微信二维码