C# ComboBox 绘画冻结
C# ComboBox paint is freezing
我有相当大的(4700 行)Windows 我编写的用于协调制造工厂中三个部门的表单应用程序。我在整个应用程序中有许多组合框,并且都运行良好,但我有一个组合框在加载时可以正常工作,但是一旦您更改选项卡并返回,组合框就会被冻结。请注意:这是对象 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
* suspend paint
* force paint event
我很难过。关于如何解决这个问题有什么想法吗?
编辑:可笑的是,我尝试了以下但没有成功。控件保持隐藏状态。
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();
}
解决这个问题很简单。在将 datasource
分配给组合框之前,只需输入 Value
和 Display
会员代码即可。
所以而不是:
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 行时"freezes" - 完成时间太长。
当你在数据源之前分配Displaymember
和ValueMember
,然后只改变一次数据源时,所有对象继承Display
和Value
成员属性和不会触发事件,因此不会冻结。
重要说明:正如我已经测试和使用过的那样,在任何地方都可以使用 checkedListBox
和 ListBox
。出于某种原因,它不允许我在分配数据源之前分配 Display and Value
成员。
我有相当大的(4700 行)Windows 我编写的用于协调制造工厂中三个部门的表单应用程序。我在整个应用程序中有许多组合框,并且都运行良好,但我有一个组合框在加载时可以正常工作,但是一旦您更改选项卡并返回,组合框就会被冻结。请注意:这是对象 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
* suspend paint
* force paint event
我很难过。关于如何解决这个问题有什么想法吗?
编辑:可笑的是,我尝试了以下但没有成功。控件保持隐藏状态。
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();
}
解决这个问题很简单。在将 datasource
分配给组合框之前,只需输入 Value
和 Display
会员代码即可。
所以而不是:
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 行时"freezes" - 完成时间太长。
当你在数据源之前分配Displaymember
和ValueMember
,然后只改变一次数据源时,所有对象继承Display
和Value
成员属性和不会触发事件,因此不会冻结。
重要说明:正如我已经测试和使用过的那样,在任何地方都可以使用 checkedListBox
和 ListBox
。出于某种原因,它不允许我在分配数据源之前分配 Display and Value
成员。