简体   繁体   English

C#UserControl可见属性不变

[英]C# UserControl Visible Property Not Changing

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

ucFollow is a custom UserControl, nothing fancy. ucFollow是一个自定义UserControl,没什么特别的。 The above code prints out: 上面的代码打印出来:

False
False

Worst part is, this does toggle the actual visibility of the UserControl (ie ucFollow does appear once this code is called), but it seems somehow that the Visible property isn't ... well, visible on the backend, and doesn't reflect the change, even though the UI itself does. 最糟糕的是,这确实切换了UserControl的实际可见性(即,一旦调用此代码,ucFollow就会出现),但似乎某种程度上Visible属性不是......好,在后端可见,而不是反映变化,即使UI本身也是如此。

I don't even know where to begin troubleshooting this. 我甚至不知道从哪里开始排除故障。 Does anyone have any ideas as to what could remotely cause this kind of craziness? 有没有人有什么想法可以远程引起这种疯狂?

Edit: This is with a standard C# WinForm in Visual Studio 2010. 编辑:这是在Visual Studio 2010中使用标准C#WinForm。

I didn't break C#! 我没有打破C#! :) :)

Turns out the culprit was the Form.Visible property. 事实证明,罪魁祸首是Form.Visible属性。 Before Form.Visible is set to true, any and all controls on the form will be invisible (Visible = false) no matter what. 在Form.Visible设置为true之前,无论如何,表单上的任何和所有控件都将是不可见的(Visible = false)。

However, you can still set Visible properties - they just won't take effect until the Form.Visible property is set to true. 但是,您仍然可以设置 Visible属性 - 只有在Form.Visible属性设置为true之后它们才会生效。

In other words, when I called ucFollow.Visible = true , my program was indeed registering it - however, at that point in the code, ucFollow's parent Form.Visible was still false. 换句话说,当我调用ucFollow.Visible = true ,我的程序确实在注册它 - 但是,在代码中的那一点,ucFollow的父Form.Visible仍然是假的。 Therefore, both the Debugger and my print statements recognized, "Hey, this control's parent form is still not visible, so this control is not visible. Period." 因此,Debugger和我的print语句都识别出“嘿,这个控件的父窗体仍然不可见,所以这个控件不可见。期间。”

As soon as the form was made visible, all the changes took effect and everything worked great. 一旦表单可见,所有更改都生效,一切都很顺利。

Moral of the story: Don't rely on the Visibility properties of your controls unless the form containing them is already visible and running. 故事的道德:除非包含它们的表单已经可见并且正在运行,否则不要依赖控件的Visibility属性。

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

This is the danger of assuming properties and fields are the same thing. 这是假设属性和字段是相同的危险。 They are of course very similar conceptually (that's the point) but they are emphatically not that same mechanically. 它们在概念上当然非常相似(这就是重点),但它们在机械上并不是那么相同。 Have a look at what ucFollow.Visible = true actually does: 看看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();
    }
}

(Code courtesy of ILSpy.) (代码由ILSpy提供。)

Your answer lies somewhere in that tormented maze of logic. 你的答案就在那个折磨着的迷宫中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM