none
コントロールをグレイアウトさせずに操作不可能にできますか? RRS feed

  • 質問

  • Windows Form初心者です。

    Enabled=Falseで操作不可能にできることは、わかります。

    複数のコントロールがグループボックスに入っており、それらを

    操作不可能(閲覧専用)にしたり、操作可能(編集可)にしたり

    したいのです。

    その制御はToolStripButtonで行いたいので、ToolStripは操作可能に

    したいのです。

    やはりEnabled=Falseにして、色をいちいち指定しなおすしかないのでしょうか?

    それとも、上にカバーのようなコントロールか何かを置くことができるのでしょうか?

    2006年8月3日 5:57

すべての返信

  • 質問から想像するに、操作不可能とした時に、そうでない場合と見た目が全く変わらないようにしたいということのようですが、そうした場合、ユーザーは混乱してしまう気がします。それとも何か特別な事情、例えばゲームなどで、ユーザーに操作可能かどうかわからせないようにする必要があるということでしょうか?

    >やはりEnabled=Falseにして、色をいちいち指定しなおすしかないのでしょうか?

    そうするしか無いと思います。WPF(Windows Presentation Foundation)なんかだとstyleが使えますので、将来的にそちらで制御できるのかもしれませんが、勉強不足でまだよくわかりません。(^^;

    2006年8月3日 12:05
    モデレータ
  • 閲覧モードなのにグレイアウトは見にくいのです。モード表示を明確にしておけば、ユーザーが混乱することもないと思うのです。DataGridViewのReadOnlyのような形にしたいのです。

    既存のグレイアウト表示は、「使用しない」という意味(Enabled=False)であって、閲覧専用(ReadOnly=True)ではないから、意味づけが違うのです。そのためにグレイアウトは、いかにも「あなたは設定できません。今のあなたに関係ありませんよ」という感じがします。

    けれども、求めているものは、「操作はできないけれど、見せたい」という、ことなのです。やっぱり無理でしょうか……

    2006年8月4日 0:07
  • ならば、コントロールひとつひとつをReadOnlyして(必要なら)色をかえるとかしかないとおもいます。
    ただ、GroupBox内のコントロールはコレクションの形で取得できるので、
    ループしてコントロールの種類ごとに上記処理すればそれほど手間ではないと思います。
    問題はComboBoxとかRadioButtonなどにはReadOnlyプロパティがないので、
    なんらか処理をしてやらないといけないところだと思います。

    # 確かにEnabledのグレイアウトは見づらい…

    2006年8月4日 1:57
  • やはりそうですか…… .NETになってから(かな?)、どのコントロールも、Foreachで、共通のプロパティ名ForeColorとBackColorを使って設定できるので、心配していたよりも、面倒くさくありませんでした。標準でReadOnlyプロパティがあればよいのにと思います。ありがとうございました。

    2006年8月4日 3:25
  •  Ogacha さんからの引用

    既存のグレイアウト表示は、「使用しない」という意味(Enabled=False)であって、閲覧専用(ReadOnly=True)ではないから、意味づけが違うのです。そのためにグレイアウトは、いかにも「あなたは設定できません。今のあなたに関係ありませんよ」という感じがします。

    Buttonコントロールに関して言えば、EnableかDisenableかどうかだけで、ReadOnlyのプロパティは必要ないでしょう。なぜなら普通はReadOnly以外にあり得ないからです。

    2006年8月4日 4:30
    モデレータ
  • 以前私も悩みました。訳あって ReadOnly は使いませんでした。

    私の場合、親の状態で色が変わるコントロールの中では基本的に TextBox ぐらいしか使用していませんので、BackColor を Window にすることで対処しました。
    TextBox の BackColor は元々 Window ですが、一度別の色を設定してから Window を再設定します。すると、親の状態等に従わなくなります。(Control.BackColor はアンビエントプロパティだそうで)
    ただ、TextBox ぐらいしかこの手法は使えないのと、文字の色には効果がありません。

    上記の対応の前に、以下のようなクラスを作成しました。
    groupBox1.Enabled = false; を行う前に、Form_Load 等での初期化処理として次のコードを実行します。
    KeepColorPanel.Possessed(groupBox1);

    仕組みですが、パネルとパネル上のコントロールの間に動的に作成するパネルをすり込ませます。
    この作成したパネルでは、OnParentEnabledChanged をオーバライドして、標準の動作を処理させません。
    その結果、親の Enabled が変化してもそれに伴う色変更処理.など.が抑制されます。

    数ヶ月前に作成したのですが、それなりに危険な香りもするので、結局私は使っていません。
    ただマイライブラリには残しているので、もしかしたら検証してもらえるかもという期待を込めて投稿します。(^^;
    (終わったスレに便乗)

    [C#]



    public class KeepColorPanel : Panel
    {
        public static void Possessed(Control pTarget)
        {
            System.Type wType = pTarget.GetType();
            if (!(wType == typeof(Panel) || wType == typeof(GroupBox)))
                throw new Exception("未対応のコントロールが渡されました。");
            if (pTarget.Controls.Count > 0 && pTarget.Controls[0] is KeepColorPanel)
                return;

            KeepColorPanel wPanel = new KeepColorPanel();
            wPanel.Location = new Point(0, 0);
            wPanel.Size = pTarget.Size;
            wPanel.Anchor =
                (AnchorStyles.Left | AnchorStyles.Top
                | AnchorStyles.Right | AnchorStyles.Bottom);

            pTarget.SuspendLayout();
            while (pTarget.Controls.Count > 0)
                pTarget.Controls[0].Parent = wPanel;
            wPanel.Parent = pTarget;
            /* (透過色は、System.Windows.Forms.ControlStyles の*/
            /*  SupportsTransparentBackColor が関係するらしい)*/
            wPanel.BackColor = Color.Transparent;
            pTarget.ResumeLayout();
        }

        protected override void OnParentEnabledChanged(EventArgs e)
        {
            // base の処理をさせない
        }
    }

     

    ※投稿後にAnchor追加

    2006年8月4日 10:52
  • もうこのスレは終わってるのかな

    私が以前に使ったのは 極単純で 同じ大きさ同じ色のボタンを同じ位置に重ねて貼り付けておき

    BringToFrontで 制御する方法です ただし 無効になっているボタンもクリックすれば凹みますので視覚的にそれで問題なければ 簡単でしたよ

    2006年8月4日 11:59