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开发框架网发布内容,转载请附上原文出处连接
post YES开发框架