最近改代码遇到这样一个问题。
C# WinForm中有Panel,根据业务逻辑需要在Panel中加载不同的UserControl。其中一个UserControl中有一个TextBox,需要在UserControl Load的时候,为其设置焦点。暂定这个UserControl的名字为ControlA。
Form中加载UserControl的代码很简单。
public void AddControl(UserControl control)
{
this.pnlMian.Controls.Clear();
this.pnlMian.Controls.Add(control);
}
然后在一个公共类(AppControl.cs)中,添加了一些公共方法。用来加载新的UserControl。
public static void MainFormRefreshControl(UserControl current, UserControl needLoad)
{
Form frm = current.FindForm();
if (frm != null && frm is frmMain)
{
frmMain fMain = (frmMain)frm;
fMain.AddControl(needLoad);
}
}
由于只需要设置Focus,所以认为代码很简单。
于是在ControlA的Load方法最下面加了这样一段代码。
this.txtBarcode.Focus();
用来设置TextBox获得焦点,但很遗憾,运行时没有预期的效果,TextBox没有获取焦点。
一开始以为代码写错,在代码中(用VS2008开发的项目)设置断点。断点设置后,正常运行,代码也顺利通过。运行有了预期效果,TextBox获得了焦点。取消断点,重新运行,问题又出来了。重新设置断点又OK了。反反复复,代码没有做改动,为什么设置断点就好了,不加断点就不行了?问题究竟出在哪里?
网上有人说,要设置TabIndex。参照过程设置了,没用。
网上也有人说,UserControl需要有焦点,才有用。于是在ControlA的Load方法中加入代码 this.Focus();试了,但还是没用。难道更换UserControl后,整个Form都失去焦点?带着这个疑问,在Load方法中替换为如下代码
var findForm = this.FindForm();
if (findForm != null && findForm is frmMain)
{
var mainForm = (frmMain)findForm;
this.Focus();
this.txtBarcode.Focus();
}
运行还是没效果,但设置断点后,却发现问题了。问题在于findForm为NULL。
在所有更换UserControl的地方设置断点,查看系统的运行情况。更换UserControl的代码如下
AppControl.MainFormRefreshControl(this, new ucBuyYardageConfirm() { Dock = DockStyle.Fill });
通过断点运行发现,代码先走ControlA的Load方法,然后在走Form中的AddControl方法。但我印象中应该是this.pnlMian.Controls.Add(control);执行时,才走ControlA的Load方法。这里为什么反了过来?还是说,有什么我还不清楚的地方。这里的确挺奇怪的。
问题明了了,当ControlA完全被加载后(ControlA可找到所在的Form),在设置TextBox的Focus不就行了。将代码稍作修改。
首先在ControlA中增加一个Public方法
public void SetBarcodeFocus()
{
this.txtBarcode.Focus();
}
然后将代码
AppControl.MainFormRefreshControl(this, new ucBuyYardageConfirm() { Dock = DockStyle.Fill });稍作修改,如下.
var ctl = new ucBuyYardageSendCoupon() { Dock = DockStyle.Fill };
AppControl.MainFormRefreshControl(this, ctl);
ctl.SetBarcodeFocus();
测试,运行成功。代码按照预期效果运行。
C# WinForm中有Panel,根据业务逻辑需要在Panel中加载不同的UserControl。其中一个UserControl中有一个TextBox,需要在UserControl Load的时候,为其设置焦点。暂定这个UserControl的名字为ControlA。
Form中加载UserControl的代码很简单。
public void AddControl(UserControl control)
{
this.pnlMian.Controls.Clear();
this.pnlMian.Controls.Add(control);
}
然后在一个公共类(AppControl.cs)中,添加了一些公共方法。用来加载新的UserControl。
public static void MainFormRefreshControl(UserControl current, UserControl needLoad)
{
Form frm = current.FindForm();
if (frm != null && frm is frmMain)
{
frmMain fMain = (frmMain)frm;
fMain.AddControl(needLoad);
}
}
由于只需要设置Focus,所以认为代码很简单。
于是在ControlA的Load方法最下面加了这样一段代码。
this.txtBarcode.Focus();
用来设置TextBox获得焦点,但很遗憾,运行时没有预期的效果,TextBox没有获取焦点。
一开始以为代码写错,在代码中(用VS2008开发的项目)设置断点。断点设置后,正常运行,代码也顺利通过。运行有了预期效果,TextBox获得了焦点。取消断点,重新运行,问题又出来了。重新设置断点又OK了。反反复复,代码没有做改动,为什么设置断点就好了,不加断点就不行了?问题究竟出在哪里?
网上有人说,要设置TabIndex。参照过程设置了,没用。
网上也有人说,UserControl需要有焦点,才有用。于是在ControlA的Load方法中加入代码 this.Focus();试了,但还是没用。难道更换UserControl后,整个Form都失去焦点?带着这个疑问,在Load方法中替换为如下代码
var findForm = this.FindForm();
if (findForm != null && findForm is frmMain)
{
var mainForm = (frmMain)findForm;
this.Focus();
this.txtBarcode.Focus();
}
运行还是没效果,但设置断点后,却发现问题了。问题在于findForm为NULL。
在所有更换UserControl的地方设置断点,查看系统的运行情况。更换UserControl的代码如下
AppControl.MainFormRefreshControl(this, new ucBuyYardageConfirm() { Dock = DockStyle.Fill });
通过断点运行发现,代码先走ControlA的Load方法,然后在走Form中的AddControl方法。但我印象中应该是this.pnlMian.Controls.Add(control);执行时,才走ControlA的Load方法。这里为什么反了过来?还是说,有什么我还不清楚的地方。这里的确挺奇怪的。
问题明了了,当ControlA完全被加载后(ControlA可找到所在的Form),在设置TextBox的Focus不就行了。将代码稍作修改。
首先在ControlA中增加一个Public方法
public void SetBarcodeFocus()
{
this.txtBarcode.Focus();
}
然后将代码
AppControl.MainFormRefreshControl(this, new ucBuyYardageConfirm() { Dock = DockStyle.Fill });稍作修改,如下.
var ctl = new ucBuyYardageSendCoupon() { Dock = DockStyle.Fill };
AppControl.MainFormRefreshControl(this, ctl);
ctl.SetBarcodeFocus();
测试,运行成功。代码按照预期效果运行。