C#UserControl可见属性不更改

Debug.WriteLine(ucFollow.Visible); ucFollow.Visible = true; Debug.WriteLine(ucFollow.Visible); 

ucFollow是一个自定义UserControl,没什么特别的。 上面的代码打印出来:

 False False 

最糟糕的是,这确实切换了UserControl的实际可见性(即,一旦调用此代码,ucFollow就会出现),但似乎某种程度上,Visible属性不是……好,在后端可见,而不是反映变化,即使UI本身也是如此。

我甚至不知道从哪里开始排除故障。 有没有人对什么可以远程引起这种疯狂有任何想法?

编辑:这是在Visual Studio 2010中使用标准C#WinForm。

我没有打破C#! 🙂

事实certificate,罪魁祸首是Form.Visible属性。 在Form.Visible设置为true之前,无论如何,表单上的任何和所有控件都将是不可见的(Visible = false)。

但是,您仍然可以设置 Visible属性 – 只有在Form.Visible属性设置为true之后它们才会生效。

换句话说,当我调用ucFollow.Visible = true ,我的程序确实在注册它 – 但是,在代码中的那一点,ucFollow的父Form.Visible仍然是假的。 因此,Debugger和我的print语句都识别出,“嘿,这个控件的父窗体仍然不可见,所以这个控件不可见。期间。”

一旦表单可见,所有更改都生效,一切都很顺利。

故事的道德:除非包含它们的表单已经可见并且正在运行,否则不要依赖控件的Visibility属性。

罪魁祸首是控件Visible属性实际上是一个属性(使用get; set;),并且该set将分配给内部m_Visible成员,但get将查看所有父控件,并且只有在所有父控件都具有m_Visible == true时才返回true

这是假设属性和字段是相同的危险。 它们在概念上当然非常相似(这就是重点),但它们在机械上并不是那么相同。 看看ucFollow.Visible = true实际上是做什么的:

 protected virtual void SetVisibleCore(bool value) { try { HandleCollector.SuspendCollect(); if (this.GetVisibleCore() != value) { if (!value) { this.SelectNextIfFocused(); } bool flag = false; if (this.GetTopLevel()) { if (this.IsHandleCreated || value) { SafeNativeMethods.ShowWindow(new HandleRef(this, this.Handle), value ? this.ShowParams : 0); } } else { if (this.IsHandleCreated || (value && this.parent != null && this.parent.Created)) { this.SetState(2, value); flag = true; try { if (value) { this.CreateControl(); } SafeNativeMethods.SetWindowPos(new HandleRef(this.window, this.Handle), NativeMethods.NullHandleRef, 0, 0, 0, 0, 23 | (value ? 64 : 128)); } catch { this.SetState(2, !value); throw; } } } if (this.GetVisibleCore() != value) { this.SetState(2, value); flag = true; } if (flag) { using (new LayoutTransaction(this.parent, this, PropertyNames.Visible)) { this.OnVisibleChanged(EventArgs.Empty); } } this.UpdateRoot(); } else { if (this.GetState(2) || value || !this.IsHandleCreated || SafeNativeMethods.IsWindowVisible(new HandleRef(this, this.Handle))) { this.SetState(2, value); if (this.IsHandleCreated) { SafeNativeMethods.SetWindowPos(new HandleRef(this.window, this.Handle), NativeMethods.NullHandleRef, 0, 0, 0, 0, 23 | (value ? 64 : 128)); } } } } finally { HandleCollector.ResumeCollect(); } } 

(代码由ILSpy提供。)

你的答案就在那个折磨着迷宫的迷宫中。