web-dev-qa-db-ja.com

C#UserControlの表示プロパティは変更されません

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

ucFollowはカスタムUserControlであり、特別なものではありません。上記のコードは次のように出力されます。

False
False

最悪の部分は、これdoes UserControlの実際の可視性を切り替えます(つまり、このコードが呼び出されるとucFollowが表示されます)、しかし、どういうわけか、Visibleプロパティは...うまく表示されておらず、バックエンドに表示されており、UI自体は反映されていても、変更を反映していないようです。

これのトラブルシューティングをどこから始めればよいのかさえわかりません。何がこの種の狂気を遠隔で引き起こす可能性があるかについて誰かが何か考えを持っていますか?

編集:これは、Visual Studio 2010の標準のC#WinFormを使用しています。

15
sichinumi

私はC#を壊しませんでした! :)

犯人はForm.Visibleプロパティであることが判明しました。 Form.Visibleがtrueに設定される前は、フォーム上のすべてのコントロールは、何があっても非表示(Visible = false)になります。

ただし、それでも可能ですset Visibleプロパティ-Form.Visibleプロパティがtrueに設定されるまで、それらは有効になりません。

言い換えると、ucFollow.Visible = trueを呼び出したとき、プログラムは実際にそれを登録していましたが、コードのその時点では、ucFollowの親Form.Visibleはまだfalseでした。したがって、デバッガーと私のprintステートメントの両方が、「ねえ、このコントロールの親フォームはまだ表示されていないので、このコントロールは表示されていません。期間」と認識しました。

フォームが表示されるとすぐに、すべての変更が有効になり、すべてがうまく機能しました。

話の教訓:コントロールを含むフォームがすでに表示されて実行されていない限り、コントロールの可視性プロパティに依存しないでください。

29
sichinumi

原因は、controls Visibleプロパティが実際にはプロパティ(get; set;を使用)であり、セットが内部m_Visibleメンバーに割り当てられることですが、getはすべての親コントロールを調べ、すべてがm_Visible == trueである場合にのみtrueを返します。

4
anonymous

これは、プロパティとフィールドが同じものであると想定することの危険性です。もちろん、それらは非常に似ています概念的に(それがポイントです)が、機械的にはそれほど同じではないことを強調します。何を見てください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の厚意により提供されています。)

あなたの答えは、その苦しめられた論理の迷路のどこかにあります。

3
dlev