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

質問
すべての返信
-
質問から想像するに、操作不可能とした時に、そうでない場合と見た目が全く変わらないようにしたいということのようですが、そうした場合、ユーザーは混乱してしまう気がします。それとも何か特別な事情、例えばゲームなどで、ユーザーに操作可能かどうかわからせないようにする必要があるということでしょうか?
>やはりEnabled=Falseにして、色をいちいち指定しなおすしかないのでしょうか?
そうするしか無いと思います。WPF(Windows Presentation Foundation)なんかだとstyleが使えますので、将来的にそちらで制御できるのかもしれませんが、勉強不足でまだよくわかりません。(^^;
-
閲覧モードなのにグレイアウトは見にくいのです。モード表示を明確にしておけば、ユーザーが混乱することもないと思うのです。DataGridViewのReadOnlyのような形にしたいのです。
既存のグレイアウト表示は、「使用しない」という意味(Enabled=False)であって、閲覧専用(ReadOnly=True)ではないから、意味づけが違うのです。そのためにグレイアウトは、いかにも「あなたは設定できません。今のあなたに関係ありませんよ」という感じがします。
けれども、求めているものは、「操作はできないけれど、見せたい」という、ことなのです。やっぱり無理でしょうか……
-
以前私も悩みました。訳あって 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追加