[C#][Windows Formsアプリ][ColorDialog] ShowDialogの基本

スポンサーリンク

はじめに

本記事では、Windows Forms の ColorDialog コントロールで標準の「色の選択」ダイアログを表示し、選択された色をフォームやコントロールに反映する基本手順を学びます。キーポイントは次の3つです。

ShowDialog() の戻り値(DialogResult)の扱い方
・選択色(Color)やダイアログの表示オプション(FullOpen など)の設定
ColorDialog の破棄(Dispose)と「オーナー」指定の考え方

説明

ColorDialog は、ユーザーに色を選ばせるための共通ダイアログです。表示には ShowDialog() を使い、ユーザーが「OK」を押したときのみ選択結果を反映します。流れはシンプルです。

1) ColorDialog のインスタンスを作成する
2) 初期色やオプション(FullOpenAnyColorSolidColorOnly など)を設定する
3) ShowDialog() または ShowDialog(this) を呼び出して表示する(this はオーナー)
4) 戻り値が DialogResult.OK のとき、dlg.Color を使って反映する
5) 使い終わったら Disposeusing 構文で自動化が安全)

主なプロパティの概要:

Color … 選択中(既定/結果)の色。初期値としても設定可能。
FullOpen … ダイアログを開いた直後から「色の作成(カスタム)」領域を展開。
AnyColor … すべての色を表示。
SolidColorOnly … 固定色のみ選択可にする。
CustomColors … カスタム色のパレット(int[])を保存・復元。

ShowDialog()DialogResult を返します。OKCancel などがあり、基本は OK のときだけ選択色を反映します。
また、ShowDialog(this) のように「オーナー(親ウィンドウ)」を指定すると、ダイアログのフォーカスやモーダル動作が安定します。

サンプルコード

以下は、ボタンで ColorDialog を開き、選んだ色をプレビュー(パネル背景)に反映するサンプルです。カスタム色の保存・復元、オーナー指定、using による破棄も含めています。

using System;
using System.Drawing;
using System.Windows.Forms;

namespace ColorDialogSample
{


    public class MainForm : Form
    {
        private readonly Button btnPickColor;
        private readonly Panel previewPanel;

        // カスタム色を保持(アプリ起動中に限る簡易実装)
        private int[] _customColors = Array.Empty<int>();

        public MainForm()
        {
            Text = "ColorDialog と ShowDialog の基本";
            Width = 420;
            Height = 240;
            StartPosition = FormStartPosition.CenterScreen;

            btnPickColor = new Button
            {
                Text = "色を選ぶ...",
                AutoSize = true,
                Location = new Point(20, 20)
            };
            btnPickColor.Click += OnPickColorClicked;

            previewPanel = new Panel
            {
                BorderStyle = BorderStyle.FixedSingle,
                BackColor = Color.White,
                Location = new Point(20, 70),
                Size = new Size(360, 80)
            };

            var infoLabel = new Label
            {
                AutoSize = true,
                Location = new Point(20, 160),
                Text = "選択した色が上のパネルに反映されます。"
            };

            Controls.Add(btnPickColor);
            Controls.Add(previewPanel);
            Controls.Add(infoLabel);
        }

        private void OnPickColorClicked(object sender, EventArgs e)
        {
            // using を使うことで確実に Dispose される
            using (var dlg = new ColorDialog())
            {
                // ダイアログ初期設定
                dlg.AllowFullOpen = true; // 「色の作成」ボタンを有効
                dlg.FullOpen = true;      // 初回からカスタム領域を展開
                dlg.AnyColor = true;      // すべての色を一覧に
                dlg.SolidColorOnly = false;
                dlg.Color = previewPanel.BackColor; // 現在色を初期値に

                // 以前のカスタム色を復元(ある場合)
                dlg.CustomColors = _customColors;

                // オーナーを this(このフォーム)に指定して開く
                var result = dlg.ShowDialog(this);

                if (result == DialogResult.OK)
                {
                    // 選ばれた色を反映
                    previewPanel.BackColor = dlg.Color;

                    // 今回のカスタム色を保存(次回に活用)
                    _customColors = dlg.CustomColors ?? Array.Empty<int>();
                }
                else
                {
                    // Cancel や閉じる操作の場合は何もしない
                }
            }
        }
    }
}

コード解説(重要ポイントごとに分解します):

1) 生成と破棄
using (var dlg = new ColorDialog()) { ... } とすることで、ダイアログが閉じた後に自動で Dispose() が呼ばれ、リソースリークを防げます。

2) 初期色
dlg.Color = previewPanel.BackColor; により、現在表示中の色を初期選択として提示できます。ユーザーは「今の色」を起点に微調整できます。

3) 表示オプション
FullOpen = true で初回からカスタム領域を展開。AnyColorSolidColorOnly は候補色の幅を調整します。用途に応じてオン・オフしてください。

4) オーナー指定
ShowDialog(this) として親フォームを明示します。これにより、モーダルの前面表示・フォーカス挙動が安定し、背後に隠れるなどの不具合を避けやすくなります。簡易的には ShowDialog() でも動きますが、基本はオーナー指定を推奨です。

5) 戻り値の確認
if (result == DialogResult.OK) { ... } のように、OK のときだけ反映します。誤って DialogResult.Yes など別の値と比較しないよう注意してください。

6) カスタム色の保存・復元
CustomColorsint[](RGB を 0x00BBGGRR のようにエンコード)で、ユーザーが作成した色パレットを保持します。サンプルではフィールド _customColors に入れ替えて、次回のダイアログ表示に引き継いでいます。

つまづきポイント

OK 判定を忘れるShowDialog() の戻り値が DialogResult.OK のときのみ色を反映します。Cancel 時に反映してしまうと「勝手に変わった」ように見えます。

オーナー未指定で背後に隠れるShowDialog() 単独で開くと、環境によっては親の背後に回ることがあります。ShowDialog(this) を基本形に。

Dispose 漏れ:ダイアログはネイティブリソースを持ちます。using 構文での自動破棄が安全です。

CustomColors の型に注意int[] であり Color[] ではありません。そのまま List<Color> に入れ替えようとすると型不一致になります。

マルチスレッドからの呼び出し:UI スレッド以外から ShowDialog() を叩くと例外やフリーズの原因。UI スレッド(フォーム側)で呼び出しましょう。

フォームに色が見えにくいForm.BackColor を変えても、上に大きなパネルやユーザーコントロールが覆っていると気づきにくいです。サンプルのようにプレビュー用パネルを用意すると分かりやすくなります。

まとめ

ColorDialogShowDialog() の戻り値を丁寧に扱い、ColorFullOpen など基本プロパティを押さえるだけで実用レベルに届きます。using で確実に破棄し、必要に応じてオーナー指定とカスタム色の保存・復元を組み合わせれば、ユーザーにとってわかりやすい色選択体験を提供できます。

Please follow and like us:

コメント

タイトルとURLをコピーしました