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

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

False
False

最糟糕的是,这确实会切换 UserControl 的实际可见性(即,一旦调用此代码,ucFollow 就会出现),但似乎 Visible 属性不......好吧,在后端可见,并且不反映变化,即使 UI 本身确实如此。

我什至不知道从哪里开始解决这个问题。有没有人知道什么可能会导致这种疯狂?

编辑:这是 Visual Studio 2010 中的标准 C# WinForm。

4

3 回答 3

35

我没有破坏 C#!:)

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

但是,您仍然可以设置Visible 属性 - 在 Form.Visible 属性设置为 true 之前,它们不会生效。

换句话说,当我调用 时ucFollow.Visible = true,我的程序确实在注册它——然而,在代码中,ucFollow 的父 Form.Visible 仍然是错误的。因此,调试器和我的打印语句都识别出,“嘿,这个控件的父窗体仍然不可见,所以这个控件不可见。句号。”

一旦表单可见,所有更改都会生效,并且一切正常。

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

于 2012-06-22T17:44:39.013 回答
8

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

于 2013-11-05T09:17:16.050 回答
4

这是假设属性和字段是同一事物的危险。它们在概念上当然非常相似(这就是重点),但它们在机械上却明显不同。看看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 提供。)

你的答案就在那个饱受折磨的逻辑迷宫中。

于 2012-06-22T17:32:05.527 回答