« アンマネージドDLLの動的リンク(3)[最終回] | トップページ | Sandcastle を使用したドキュメント作成(1) »

2010年10月24日 (日)

親コンテナを無効にしても子コントロールを灰色表示にしない方法

.NETでは、通常親コンテナの Enabled プロパティを false にすると、子コントロールも自動的に Enabled プロパティが false になって、灰色表示になります。親が Enabled = false である限り、子コントロールは Enabled = true に設定しようとしても効かない様です。

普通はこれでも問題無いのですが、.NETでないアプリケーションを.NETに移行する場合等、どうしてもコントロールを通常表示の状態で、フォーカスを受け取れない状態にしたい場合もあるかと思います。

こういうときには、WindowsAPI の EnableWindow を使えば出来ます。但し、この時 TabStop プロパティ値も面倒を見る必要があるので注意が必要です。
以下は検証に使用した画面です。後で出てくるフォーカス移動の話の為、タブオーダー画面で表示しています。なお、パネルはその存在が判るようにあえて枠線つき(BorderStyle = BorderStyle.Fixed3D)にしています。

そして、button1 クリックでフォーム左側のパネルの Enabled プロパティ値を反転(true なら false、false なら true)する様にしています。パネルが Enabled = false になると、子コントロールは灰色表示になります。

private void button1_Click(object sender, System.EventArgs e)
{
    panel1.Enabled = !(panel1.Enabled);
}

また、button2 クリックで同じパネルを対象に EnableWindow を使用して、その状態を反転しています。この時、パネルが無効になるときは、子コントロールの TabStop プロパティを false に、パネルを有効にするときは、子コントロールの TabStop プロパティを true にしています。こうしないと、Tab キーによるフォーカス移動が、ちょっとおかしくなります。

[DllImport("user32.dll")]
[return: MarshalAs(UnmanagedType.Bool)]
static extern bool IsWindowEnabled(IntPtr hWnd);
[DllImport("user32.dll")]
static extern bool EnableWindow(IntPtr hWnd, bool bEnable);
private void button2_Click(object sender, System.EventArgs e)
{
    bool enabled = IsWindowEnabled(panel1.Handle);
    foreach(Control control in panel1.Controls)
        control.TabStop = !enabled;
    EnableWindow(panel1.Handle, !enabled);
}

具体的には、button2 にフォーカスがあって、そこから Tab キーで、次のコントロールへ移動する場合、パネルが無効なら、button1 にフォーカスが移動すべきです。しかし、Tab キーを4回押しても、button2 からフォーカスが移動せず、5回目のTabキーを押して、初めて button1 にフォーカスが移動します。よく考えれば判ると思いますが、これはパネル内の子コントロールにフォーカスを移動させようとしていて、実際はフォーカス移動が出来ない為に、button2 にフォーカスが存在し続ける事になっています。そして5回目のTab キー入力で、button1 にフォーカスが行く番になって、ようやく button1 にフォーカスが移動するのです。
同じ事が、button1 にフォーカスがあって、Shift+Tab を押したときにも発生し、5回押すまでは、button1 にフォーカスが居続けます。
こういう理由で、TabStop プロパティ制御をする必要があるものの、子コントロールを通常表示のまま入力不可にする事は、.NETでも可能です。

なお、今回の検証に使用したテストAP一式を、CAB形式して置いておきます。参考にしたい人は、ダウンロードして見て下さい。

「Sample.cab」をダウンロード

« アンマネージドDLLの動的リンク(3)[最終回] | トップページ | Sandcastle を使用したドキュメント作成(1) »

C# Tips」カテゴリの記事

コメント

コメントを書く

コメントは記事投稿者が公開するまで表示されません。

(ウェブ上には掲載しません)

トラックバック

« アンマネージドDLLの動的リンク(3)[最終回] | トップページ | Sandcastle を使用したドキュメント作成(1) »