当不可见时,VisibleChanged事件不会被触发

5

我正在开发c# WinForm应用程序。

我有一个自定义的UserControl:MyControl : UserControl, INotifyPropertyChanged。我在事件VisibleChanged上附加了一个方法:this.VisibleChanged += new System.EventHandler(this.MyControl_VisibleChanged);

我的应用程序有多个页面,每个页面都是像MyControl一样的控件。MainWindow顶部包含一个按钮,用于切换选项卡。

我的问题是,只有当Visible更改为true时,才会调用我的函数MyControl_VisibleChanged。我在选项卡中添加了一个测试以检查MyControl.Visible,当我选择其他选项卡时,MyControl.Visiblefalse,但没有触发事件。

我尝试为该控件定义一个新的Visible属性,但该值从未被设置,只有base值被修改。

您能帮助我找到解决方案吗?


我遇到了同样的问题。每当它变得可见时,我都会收到回调,但从未在它变得不可见时收到过回调。 - John Fairbanks
2个回答

4
这是Visible工作方式的一个怪癖,在这里解释了。他的解决方案是使用他完全控制的属性,但你也可以使用一种方法,允许选项卡切换告诉它们的子元素再次引发VisibleChanged事件。 这个问题的前两个答案也可能有用。

当我阅读它们时,所有这些参考资料都在讨论可见性将父状态考虑在内的事实。我认为这不是OP所遇到的问题。我正在经历与他相同的问题,只是VisibleChanged回调拒绝触发,除非Visibility = true。每当它变为false时,回调都不会被调用。 - John Fairbanks
@JohnFairbanks 我已经测试并确认,如果您直接在表单上使用控件(即除了表单本身之外没有父控件),那么 VisibleChanged 可以很好地设置为 true 和 false。因此,这是与父级状态有关的问题。如果您将控件放在父面板上并显示/隐藏父面板,则子项的 VisibleChanged 仅在 true 时触发。但是,按照谨慎的顺序显示可行:在隐藏父项之前逐个隐藏子项,然后 VisibleChanged 将在 false 时触发。要再次显示,请在显示子项之前在父项上设置可见性。 - Bloopy
你是正确的!抱歉,我的错误!我将它嵌入了一个选项卡控件中。 - John Fairbanks

2

Control.Visible 属性有点奇怪,因为它的 set-accessor 设置了一个本地值,你无法访问该控件,但是 get-accessor 返回此控件及其所有父级中隐藏值的净效果。

此外,OnVisibleChangedOnParentVisibleChanged 虚拟方法(或其对应事件)并不会在其名称所示的时候触发。特别是如果更改父级可见性使您不可见,则不会触发。

有一个 OnParentBecameInvisible 虚拟方法(没有相应的事件),它执行其名称所示的操作,并填补了其他两个方法留下的空白,但它是内部的 System.Windows.Forms 组件,因此普通人无法使用。

(以上内容基于阅读 .NET 4.8 参考源代码)

如果您挂钩您的控件及其所有父级的 VisibleChanged 事件,可能可以得到适当的通知,但是如果您进行大量控件层次结构重排,则正确维护这些挂钩可能会很棘手。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接