各位老大,我现在有个form程序,功能是餐饮点菜前台,页面上现实当前在用的餐桌,因为餐桌是不确定的,所以需要动态添加,我是在panel里动态添加子控件的,代码片段如下:private void initDesk()
{
string strSql = dkSql;
if (strSql == "") return;
if (dtDk == null)
{
dtDk = bm.GetUserAllDesk(strSql); //获得子控件个数
}
this.pnlDesk.Controls.Clear();//添加前先清空 if (dtDk.Rows.Count > 0)
{
// 分页片段==============================
if (dtDk.Rows.Count % dkPageSize == 0)
{
dkPageCount = dtDk.Rows.Count / dkPageSize;
}
else
{
dkPageCount = dtDk.Rows.Count / dkPageSize + 1;
}
int start = (dkPageIndex - 1) * dkPageSize;
int end = start + dkPageSize - 1;
if (end > dtDk.Rows.Count - 1) end = dtDk.Rows.Count - 1;
// 分页片段============================== int cols = 9;//列数
int iLine = 0;//行数
int sum = end - start; //当前页需要显示数目 if ((sum + 1) % cols == 0)
{
iLine = (sum+1) / cols;
}
else
{
iLine = (sum + 1) / cols + 1;
} //动态添加按钮 int i = 0;
int j = 0;
int s = start;
DeskControl btn;//自定义子控件
while (j < iLine)
{
btn = new DeskControl();//初始化
btn.Location = new System.Drawing.Point(100 * i +10*i + 20, 10 * j + 100*j + 3);//显示位置
btn.Size = new System.Drawing.Size(100, 100);//显示大小
btn.Name = dtDk.Rows[s]["dkID"].ToString();//名称
btn.DcDeskNum.Text = dtDk.Rows[s]["dkName"].ToString();
string isbusy = dtDk.Rows[s]["dkIsBusy"].ToString();
if (isbusy.ToLower() == "false")
{
// 这些都是子控件里一些属性和方法赋值,下同
btn.setEmpty();
btn.DcMoney.Visible = false;
btn.DcTime.Visible = false;
btn.DcPersonCount.Text = dtDk.Rows[s]["dktPrnCountLow"].ToString() + "-" + dtDk.Rows[s]["dktPrnCountHigh"].ToString();
}
else if (isbusy.ToLower() == "true")
{
btn.setBusy();
try
{
btn.DcMoney.Text = ((Decimal)dtDk.Rows[s]["slValue"]).ToString("f2");
btn.DcTime.Text = ((DateTime)dtDk.Rows[s]["slStartTime"]).ToString("HH:mm");
btn.DcPersonCount.Text = dtDk.Rows[s]["slPersonCount"].ToString();
}
catch{ }
}
else
{
btn.setEmpty();
btn.DcMoney.Visible = false;
btn.DcTime.Visible = false;
btn.DcPersonCount.Visible = false;
}
btn.ControlClik += new DeskControl.ControlClickEventHandler(Desk_Click);//子控件点击事件
this.pnlDesk.Controls.Add(btn);//添加子控件
// 以下控制换行
i++;
s++;
if (i > cols - 1)
{
i = 0;
j++;
}
if (s > end)
{
break;
}
}
}
}
程序运行没有问题,但是initDesk()方法会被重复调用,就是说会一直反复清空子控件再添加子控件,系统运行20分钟后就出错了,如下:
应用程序出错:System.ComponentModel.Win32Exception: Error creating window handle.
at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at System.Windows.Forms.Control.ControlCollection.Add(Control value)
at Restaurant.FrmMainDesk.initDesk()
at Restaurant.FrmMainDesk.btnDkNext_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at Restaurant.Common.BitmapButton.OnMouseUp(MouseEventArgs e)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
错误描述:Application_ThreadExceptionError creating window handle是系统报错,似乎在注册表里有个阀值限制,但是我必须是动态添加控件,是否有什么好的方法。这个错误报错的位置不确定,反正每次都是报:Error creating window handle。各位老大帮帮忙啊!动态添加子控件 控件
{
string strSql = dkSql;
if (strSql == "") return;
if (dtDk == null)
{
dtDk = bm.GetUserAllDesk(strSql); //获得子控件个数
}
this.pnlDesk.Controls.Clear();//添加前先清空 if (dtDk.Rows.Count > 0)
{
// 分页片段==============================
if (dtDk.Rows.Count % dkPageSize == 0)
{
dkPageCount = dtDk.Rows.Count / dkPageSize;
}
else
{
dkPageCount = dtDk.Rows.Count / dkPageSize + 1;
}
int start = (dkPageIndex - 1) * dkPageSize;
int end = start + dkPageSize - 1;
if (end > dtDk.Rows.Count - 1) end = dtDk.Rows.Count - 1;
// 分页片段============================== int cols = 9;//列数
int iLine = 0;//行数
int sum = end - start; //当前页需要显示数目 if ((sum + 1) % cols == 0)
{
iLine = (sum+1) / cols;
}
else
{
iLine = (sum + 1) / cols + 1;
} //动态添加按钮 int i = 0;
int j = 0;
int s = start;
DeskControl btn;//自定义子控件
while (j < iLine)
{
btn = new DeskControl();//初始化
btn.Location = new System.Drawing.Point(100 * i +10*i + 20, 10 * j + 100*j + 3);//显示位置
btn.Size = new System.Drawing.Size(100, 100);//显示大小
btn.Name = dtDk.Rows[s]["dkID"].ToString();//名称
btn.DcDeskNum.Text = dtDk.Rows[s]["dkName"].ToString();
string isbusy = dtDk.Rows[s]["dkIsBusy"].ToString();
if (isbusy.ToLower() == "false")
{
// 这些都是子控件里一些属性和方法赋值,下同
btn.setEmpty();
btn.DcMoney.Visible = false;
btn.DcTime.Visible = false;
btn.DcPersonCount.Text = dtDk.Rows[s]["dktPrnCountLow"].ToString() + "-" + dtDk.Rows[s]["dktPrnCountHigh"].ToString();
}
else if (isbusy.ToLower() == "true")
{
btn.setBusy();
try
{
btn.DcMoney.Text = ((Decimal)dtDk.Rows[s]["slValue"]).ToString("f2");
btn.DcTime.Text = ((DateTime)dtDk.Rows[s]["slStartTime"]).ToString("HH:mm");
btn.DcPersonCount.Text = dtDk.Rows[s]["slPersonCount"].ToString();
}
catch{ }
}
else
{
btn.setEmpty();
btn.DcMoney.Visible = false;
btn.DcTime.Visible = false;
btn.DcPersonCount.Visible = false;
}
btn.ControlClik += new DeskControl.ControlClickEventHandler(Desk_Click);//子控件点击事件
this.pnlDesk.Controls.Add(btn);//添加子控件
// 以下控制换行
i++;
s++;
if (i > cols - 1)
{
i = 0;
j++;
}
if (s > end)
{
break;
}
}
}
}
程序运行没有问题,但是initDesk()方法会被重复调用,就是说会一直反复清空子控件再添加子控件,系统运行20分钟后就出错了,如下:
应用程序出错:System.ComponentModel.Win32Exception: Error creating window handle.
at System.Windows.Forms.NativeWindow.CreateHandle(CreateParams cp)
at System.Windows.Forms.Control.CreateHandle()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at System.Windows.Forms.Control.ControlCollection.Add(Control value)
at Restaurant.FrmMainDesk.initDesk()
at Restaurant.FrmMainDesk.btnDkNext_Click(Object sender, EventArgs e)
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at Restaurant.Common.BitmapButton.OnMouseUp(MouseEventArgs e)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
错误描述:Application_ThreadExceptionError creating window handle是系统报错,似乎在注册表里有个阀值限制,但是我必须是动态添加控件,是否有什么好的方法。这个错误报错的位置不确定,反正每次都是报:Error creating window handle。各位老大帮帮忙啊!动态添加子控件 控件
不管你是重绘还是重新填充子控,似乎都应该只处理发生变化的那部分?
重绘可以(Invalidate指定区域),不过会涉及到一些几何换算
换成子控件逻辑上更容易把控,性能方面,同一时刻改变的桌位应该也不会太多
这一句应该放进while循环里,因为你每一个桌位都是一个对象,而你现在的逻辑是只有一个对象,当你添加一个桌位,再添加另一个桌位的时候,因为是对象,都在跟着变化
另外,在批量操作时
this.pnlDesk.SuspendLayout();
initDesk();
this.pnlDesk.ResumeLayout();
然后运行程序,观察数值变化如果能看见这些数值一直增大,说明程序的确存在泄露资源问题,那么你可以:
1)确保每次清空COntrols之后,每个子控件都dispose
2)检查每个子控件,是否注册过其他对象的事件,如果是,请在每个子控件的Dispose(bool disposing)方法中将事件注销。参见 http://www.cnblogs.com/xiaozhi_5638/archive/2013/01/14/2859807.html 关于“弱委托”。
3)出现这个问题不叫“内存泄露”