关于Form_Load中访问控件Visible属性的问题!本帖最后由 bcrun 于 2013-08-15 12:51:45 编辑郁闷,发现VB6
关于Form_Load中访问控件Visible属性的问题! 本帖最后由 bcrun 于 2013-08-15 12:51:45 编辑 '郁闷,发现VB6新bug,注意,Text1.Visible设计时实际为True,又试了有hwnd的几个控件都这样.近似的,如果用的是Label1则正常
Private Sub Form_Load() Debug.Print Text1.Visible 'VB6 bug:输出false End Sub 应付办法:调整程序设计流程,改在Resize或Initialize等事件中访问
注:起因是需要在窗体加载时调整控件布局,此功能需要先判断控件可见性。
补充:发此帖时,感觉印象中若干年前似乎有人讨论过此问题,不过也实在没更多印象了。
[解决办法] 代码加一句,先显示窗体,就True了。
Private Sub Form_Load() Me.Show Debug.Print Text1.Visible 'VB6 bug:输出false End Sub [解决办法] 说白了就是一个事件先后的问题.
先有Initialize事件,再有Load事件,再加载显示控件,再Show 再有Resize事件
问题是.有Hwnd的没有Show,那就表示不可见.
[解决办法] 这不是 Bug,而是基本概念。
刚加载没显示的时候就是 Visible = False,这是定性的。
去检测属性值纯属脱裤子放屁——多此一举。
[解决办法] Me.Visible = True
Debug.Print Text1.Visible
[解决办法] 这个也算BUG吗?如果你非要在窗体的Load事件中检查控件的Visible属性,基本等同于还没怀孕就检查是男是女一样!!
至于类似Lable1控件,这些控件没有hwnd属性,它们可以理解为父窗口的一块区域而已。
[解决办法] 一个 TextBox 控件可以看成一个窗口句柄和一个类的的组成。
VB6 和 VB.Net 的控件设计方式是不一样的:
VB6 中句柄和类是强关联的,取 Visible 就是取 hWnd 的对应属性的
当前值 。
VB.Net 中句柄和类是弱关联的,取 Visible 属性取的是
变量值 ,并不反映当前的真是状态。
'以下为 System.Windows.Forms.Control 的 reflector 代码' Public Property Visible As Boolean Get Return Me.GetVisibleCore End Get Set(ByVal value As Boolean) Me.SetVisibleCore(value) End Set End Property Friend Overridable Function GetVisibleCore() As Boolean If Not Me.GetState(2) Then '这个标志位存放的是应该是 Visible 属性' Return False End If '就算递归检查容器也与 hWnd 无关' Return ((Me.ParentInternal Is Nothing) OrElse Me.ParentInternal.GetVisibleCore) End Function Friend Function GetState(ByVal flag As Integer) As Boolean Return ((Me.state And flag) <> 0) End Function Private state As Integer 所以两者没有可比性,设计就是这样的,不存在“缺陷”的说法。
[解决办法] 不是 Bug,是一种设计约定。
比如我在某一个控件(比如 ListBox 或 ComBoBox)的 Click 事件中对另一个控件进行操作。如果我在 Form_Load 事件中将对该 ListBox 或 ComBoBox 或 AddItem 并设置了当前 Index,则 Click 事件就被触发。但此时另一个控件还不能进行某些操作,比如 SetFocus(因为还没有完成初始化)。所以,我可以在前一个控件的 Click 事件中这样写:
If txtCLS.Visible Then txtCLS.SetFocus
这样,由于 FormLoad 中的语句引起的事件触发就不会发生错误,而后续运行中的事件触发就得到正确处理。
当然了,如果当初设计时没有对 Visible 这样处理,也还可以再添加一个新的属性,比如较 Initialized 来处理这种情况,也是可以的。但目前的约定更简单一些。
不要预先假设微软的设计者比我们更 2。
[解决办法] 窗口未显示出来之前,其子控件是不可以见的,如果非得在那里面判断,则先使用
show 显示窗口
[解决办法] 这就象要玩游戏,那么“玩家”只能遵从设计者制定的“游戏规则”。
而不会因为玩家觉得怎么样玩“更合理”,它就自动按玩家的想法来处理。
[解决办法] 简单地说,我觉得楼主说的这个,应该还算不上BUG。
当然,也不是说“微软出品”就是没BUG 。
至少,我目前发现了两个在界面处理方面的BUG:
一个是 Windows XP系统的;一个是 VB6的下拉列表控件的。
[解决办法] 这个基本上人尽皆知的事情真的不能算BUG
就好像在load事件中不能xxx.setfocus一样
[解决办法] 引用: 不是 Bug,是一种设计约定。 比如我在某一个控件(比如 ListBox 或 ComBoBox)的 Click 事件中对另一个控件进行操作。如果我在 Form_Load 事件中将对该 ListBox 或 ComBoBox 或 AddItem 并设置了当前 Index,则 Click 事件就被触发。但此时另一个控件还不能进行某些操作,比如 SetFocus(因为还没有完成初始化)。所以,我可以在前一个控件的 Click 事件中这样写: If txtCLS.Visible Then txtCLS.SetFocus 这样,由于 FormLoad 中的语句引起的事件触发就不会发生错误,而后续运行中的事件触发就得到正确处理。 当然了,如果当初设计时没有对 Visible 这样处理,也还可以再添加一个新的属性,比如较 Initialized 来处理这种情况,也是可以的。但目前的约定更简单一些。 不要预先假设微软的设计者比我们更 2。
说的很有道理,赞一个
[解决办法] 引用: 说白了就是一个事件先后的问题. 先有Initialize事件,再有Load事件,再加载显示控件,再Show 再有Resize事件 问题是.有Hwnd的没有Show,那就表示不可见. 先Load后Initialize好吧?
一般我们要设置某个控件启动后获得焦点都在Initialize事件中处理。