С# UserControl Видимое свойство не изменяется

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

ucFollow - это пользовательский UserControl, ничего необычного. Вышеприведенный код печатает:

False
False

Хуже того, эта делает для переключения фактической видимости UserControl (т.е. ucFollow появляется после вызова этого кода), но кажется, что свойство Visible не... хорошо, видимый на бэкэнд, и не отражает изменения, даже если сам пользовательский интерфейс.

Я даже не знаю, с чего начать устранение неполадок. Есть ли у кого-нибудь какие-либо идеи относительно того, что может отдаленно вызвать такой сумасшествие?

Изменить: это со стандартным С# WinForm в Visual Studio 2010.

Ответ 1

Я не сломал С#!:)

Оказывается, виновником было свойство Form.Visible. Если для параметра Form.Visible установлено значение true, все элементы управления в форме будут невидимыми (Visible = false) независимо от того, что.

Однако вы все равно можете установить свойства Visible - они просто не вступят в силу до тех пор, пока свойство Form.Visible не будет установлено в значение true.

Другими словами, когда я вызывал ucFollow.Visible = true, моя программа действительно регистрировала его, однако в этот момент кода ucFollow родительский Form.Visible по-прежнему был ложным. Таким образом, как отладчик, так и мои операторы печати распознают: "Эй, эта контрольная родительская форма все еще не видна, поэтому этот элемент управления не отображается. Period."

Как только форма стала видимой, все изменения вступили в силу, и все отлично поработало.

Мораль истории: не полагайтесь на свойства Видимости ваших элементов управления, если форма, содержащая их, уже не видна и не работает.

Ответ 2

виновником является то, что элементы управления Видимое свойство на самом деле является свойством (с get; set;), и набор присваивает внутреннему m_Visible члену, но get будет просматривать все родительские элементы управления и будет возвращать true только в том случае, если все они имеют m_Visible == true

Ответ 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.)

Ваш ответ лежит где-то в этом мучительном лабиринте логики.