C#UserControl可见属性不变

时间:2012-06-22 17:22:29

标签: c# winforms user-controls

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

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

False
False

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

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

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

3 个答案:

答案 0 :(得分:28)

我没有打破C#! :)

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

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

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

只要表格可见,所有更改都会生效,一切都很顺利。

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

答案 1 :(得分:4)

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

答案 2 :(得分:3)

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

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