web-dev-qa-db-ja.com

ボタン以外のフォーム上のすべてのコントロールを無効にする方法は?

私のフォームには、メニュー、パネル、スプリッター、ラベル、テキストボックスなど、何百ものコントロールがあります。

単一のボタンを除くすべてのコントロールを無効にする方法はありますか?

ボタンが重要なのは、1つのコントロールがまだ使用可能である必要があるため、ウィンドウを無効にするメソッドなどを使用できないためです。

13
Ryan Peschel

再帰呼び出しを行って、関連するすべてのコントロールを無効にすることができます。次に、ボタンと親コンテナを有効にする必要があります。

 private void Form1_Load(object sender, EventArgs e) {
        DisableControls(this);
        EnableControls(Button1);
    }

    private void DisableControls(Control con) {
        foreach (Control c in con.Controls) {
            DisableControls(c);
        }
        con.Enabled = false;
    }

    private void EnableControls(Control con) {
        if (con != null) {
            con.Enabled = true;
            EnableControls(con.Parent);
        }
    }
27
pinkfloydx33

@ pinkfloydx33の回答とそれに加えた編集に基づいて、さらに簡単にする拡張メソッドを作成しました。public static class このような:

public static class GuiExtensionMethods
{
        public static void Enable(this Control con, bool enable)
        {
            if (con != null)
            {
                foreach (Control c in con.Controls)
                {
                    c.Enable(enable);
                }

                try
                {
                    con.Invoke((MethodInvoker)(() => con.Enabled = enable));
                }
                catch
                {
                }
            }
        }
}

ここで、コントロール、フォーム、メニュー、サブコントロールなどを有効または無効にするには、次のようにします。

this.Enable(true); //Will enable all the controls and sub controls for this form
this.Enable(false);//Will disable all the controls and sub controls for this form

Button1.Enable(true); //Will enable only the Button1

だから、@ pinkfloydx33の答えと同様に、私は何をしますか:

private void Form1_Load(object sender, EventArgs e) 
{
        this.Enable(false);
        Button1.Enable(true);
}

拡張メソッドは静的であり、インスタンスを(手動で)作成することなくどこでも使用できるため、少なくとも私にとってははるかに明確なので、拡張メソッドが好きです。

13
coloboxp

保守が容易な、より優れた、よりエレガントなソリューションを実現するには、ボタンを他のコントロールとは別にするなど、デザインを再検討する必要があるでしょう。次に、他のコントロールがパネルまたはグループボックスにあると想定して、Panel.Enabled = False

本当に現在のデザインを維持したい場合は、再帰を回避するために Linearise ControlCollectionツリーをControlの配列に してから、次の操作を実行できます。

Array.ForEach(Me.Controls.GetAllControlsOfType(Of Control), Sub(x As Control) x.Enabled = False)
yourButton.Enabled = True
9
Neolisk

多くのパネルまたはtableLayoutPanelがネストされている場合、状況はトリッキーになります。親(または親の親)が有効になっていないため、パネルのすべてのコントロールを無効にして親パネルを無効にしてから子コントロールを有効にしようとしても、コントロールはまったく有効になりません。希望する子コントロールを有効にしておくために、フォームレイアウトをツリーとしてルートとして、コンテナまたはパネルをブランチとして、子コントロール(ボタン、テキストボックス、ラベルなど)をリーフノードとして、ツリーレイアウトを見ました。したがって、主な目的は、目的のコントロールと同じレベル内のすべてのノードを無効にし、フォームレベルまでコントロールツリーを登り、有効なコントロールのパスを確立して、子が機能できるようにすることです。

public static void DeshabilitarControles(Control control)
{
    if (control.Parent != null)
    {
        Control padre = control.Parent;
        DeshabilitarControles(control, padre);
    }
}

private static void DeshabilitarControles(Control control, Control padre)
{
    foreach (Control c in padre.Controls)
    {
        c.Enabled = c == control;
    }
    if (padre.Parent != null)
    {
        control = control.Parent;
        padre = padre.Parent;
        DeshabilitarControles(control, padre);
    }
}

public static void HabilitarControles(Control control)
{
    if (control != null)
    {
        control.Enabled = true;
        foreach (Control c in control.Controls)
        {
            HabilitarControles(c);
        }
    }
}
1
Yayo Bruno

@coloboxpの回答を修正しました。最初に、すべての親を有効にする必要があります。

    public static void Enable(this Control con, bool enable)
    {
        if (con != null)
        {
            if (enable)
            {
                Control original = con;

                List<Control> parents = new List<Control>();
                do
                {
                    parents.Add(con);

                    if (con.Parent != null)
                        con = con.Parent;
                } while (con.Parent != null && con.Parent.Enabled == false);

                if (con.Enabled == false)
                    parents.Add(con); // added last control without parent

                for (int x = parents.Count - 1; x >= 0; x--)
                {
                    parents[x].Enabled = enable;
                }

                con = original;
                parents = null;
            }

            foreach (Control c in con.Controls)
            {
                c.Enable(enable);
            }

            try
            {
                con.Invoke((MethodInvoker)(() => con.Enabled = enable));
            }
            catch
            {
            }
        }
    }
0
Andreas_k