c# - C# ComboBox 绘制冻结
问题描述
我编写了相当大的(4700 行)Windows Forms 应用程序来协调制造工厂的三个部门。我在整个应用程序中有许多组合框,并且都可以正常工作,但是我有一个组合框,它的油漆在加载时可以正常工作,但是一旦您更改选项卡并返回,组合框就会冻结。请注意:这是对象 Form1 > TableLayoutPanel > TabControl > TabPage > TableLayoutPanel > ComboBox 的顺序。
解决此问题的唯一方法是关闭应用程序并重新打开。只要我留在选项卡上,控件就会一直完美运行。
这是我为组合框加载数据的方式:
private void LoadFGPN()
{
SqlConnection con = new SqlConnection(Properties.Resources.Tef7_Conn);
SqlDataAdapter da;
DataTable dt = new DataTable();
StringBuilder sql = new StringBuilder();
sql.Append("SELECT DISTINCT(material) FROM [TEF7].[CM].[ALLPartNumbers] WHERE material LIKE '_____7______-6RP' OR material LIKE '_____4______-6RP' OR material LIKE '_________8__-6ML' OR material LIKE '_________[0-7,9]__-6ML'");
da = new SqlDataAdapter(sql.ToString(), con);
da.Fill(dt);
if (cbFGPN.DataSource == null)
{
cbFGPN.DataSource = dt;
}
else
{
cbFGPN.DataSource = null;
cbFGPN.DataSource = dt;
}
cbFGPN.ValueMember = "material";
cbFGPN.DisplayMember = "material";
} //loads finished good combo box on kanban
我试过的:
* SelectionChangeCommitted 事件并单独添加 .Refresh() 和 .Invalidate() / .Update() 没有成功。
* 组合框的绘制模式属性设置为正常
* winforms tabcontrol
*暂停绘制
*强制绘制事件
我难住了。有想法该怎么解决这个吗?
编辑:只是为了荒谬,我尝试了以下但没有成功。控件保持隐藏状态。
if (tcMain.SelectedIndex == 0)
{
cbFGPN.Hide();
LoadPreOrderGridview("eKanban", null, null, null, null, null); //loads preorder gridview
LoadFGPN();
LoadRawPN();
cbFGPN.Show();
tlpMain.Refresh();
tcMain.Refresh();
tpKanban.Refresh();
tlpKanban.Refresh();
pnKanban.Refresh();
cbFGPN.Refresh();
}
解决方案
解决这个问题非常简单。只需在分配给组合框之前输入Value
和成员代码。Display
datasource
所以而不是:
if (cbFGPN.DataSource == null)
{
cbFGPN.DataSource = dt;
}
else
{
cbFGPN.DataSource = null;
cbFGPN.DataSource = dt;
}
cbFGPN.ValueMember = "material";
cbFGPN.DisplayMember = "material";
做:
cbFGPN.ValueMember = "material";
cbFGPN.DisplayMember = "material";
if (cbFGPN.DataSource == null)
{
cbFGPN.DataSource = dt;
}
else
{
cbFGPN.DataSource = null;
cbFGPN.DataSource = dt;
}
为什么会发生?
当您要分配DisplayMember
和ValueMember
已经填充的元素时,它会转到该元素中的每个对象并向其写入要使用的display
内容和value
成员的内容,并且每次他输入已经存在的对象时,它都会触发很少的事件(例如验证,验证, textChanged、dataSourceChanged 和其他(取决于元素)),当您需要触发 10 个事件 * 4700 行时,它会“冻结” - 完成时间太长。
当您在数据源之前分配数据源然后仅更改一次数据源时,所有对象都会继承Displaymember
和成员属性并且不会触发事件,因此它不会冻结。ValueMember
Display
Value
重要提示:正如我已经测试和使用过的一样,它在任何地方都可以使用checkedListBox
,并且ListBox
. 出于某种原因,它不允许我Display and Value
在分配数据源之前分配成员。
推荐阅读
- scala - Avro 向后兼容性无法按预期工作
- deep-learning - 用于图像分类的图神经网络
- visual-studio-code - 在 vscode 中,lint 错误显示在问题中,但是当鼠标悬停红色波浪时,lint 错误消息不显示
- asp.net - 以编程方式将 asp.net 请求发送到第 3 方服务器?
- jupyter-notebook - 无法启动 Jupyter 笔记本
- c++ - 为什么在我的代码中私有数据成员不可访问?
- mysql - 如何在 MySQL 查询和 Python 中使用 WHERE & AND
- javascript - 当使用 minDate 和/或 maxDate 启用 showYearDropdown 时,如何防止出现或选择超出范围的年份
- html - Angular Material:在不指定宽度的情况下将自定义 sidenav 从长格式转换为图标
- javascript - 从对象数组中的每个对象中删除对象