5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

コレクションエディタの拡張

Last updated at Posted at 2016-07-15

はじめに

コレクションエディタは簡単にリスト要素のプロパティを変更することが出来て便利なものですが、カスタマイズしようと思うとなかなか思うようにできません。ここでは次の3つのカス
タマイズについて紹介したいと思います。

  • リストアイテムの追加、削除、移動の禁止
  • プロパティラベルの文字列変更
  • フォームクローズ時にタイトルが重複していればエラーメッセージを通知する

CollectionEditorEx.png

なお、コードは抜粋したものです。コード全体は下記を参照ください。
https://github.com/kyamawaki/CollectionEditorEx

 準備

コレクションフォーム作成時にイベントハンドラを追加しています。
フォームロード時にコントロールをテーブルに格納しています。

        /// <summary>
        /// コレクションフォーム作成
        /// </summary>
        /// <returns></returns>
        protected override CollectionForm CreateCollectionForm()
        {
            _collectionForm = base.CreateCollectionForm();
            _collectionForm.Load += Form_Load;
            _collectionForm.FormClosing += Form_FormClosing;
            return _collectionForm;
        }

        /// <summary>
        /// フォームロード時に呼ばれる
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void OnLoad(object sender, EventArgs e)
        {
            InitFormControlTable();
            CustomizeFormControlBehavior();
        }

        /// <summary>
        /// フォームコントロールの振る舞いをカスタマイズする
        /// </summary>
        protected virtual void CustomizeFormControlBehavior()
        {
            foreach (KeyValuePair<string, Control> kvp in _formControlTable)
            {
                kvp.Value.TextChanged += Control_TextChanged;
                kvp.Value.Click += Control_Click;
            }
        }

 リストアイテムの追加、削除、移動の禁止

関連コントロールを無効状態にすることで、アイテムの追加、削除などを禁止しています。コントロールを非表示にする方法も試してみましたが、レイアウトが崩れるのでこの方法にしました。


        /// <summary>
        /// コントロール有効状態変更イベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Control_EnabledChanged(object sender, EventArgs e)
        {
            Control control = sender as Control;
            if (control == null)
            {
                return;
            }
            OnControlEnableChanged(control, e);
        }

        /// <summary>
        /// コントロール有効状態変更時に呼ばれる
        /// </summary>
        /// <param name="control"></param>
        /// <param name="e"></param>
        protected virtual void OnControlEnableChanged(Control control, EventArgs e)
        {
            switch (control.Name)
            {
                case "addButton":
                case "removeButton":
                case "upButton":
                case "downButton":
                    control.Enabled = false;
                    break;
            }
        }

プロパティラベルの文字列変更

画面右上の「プロパティ(P)」が、「hogehoge:プロパティ(P)」と表示されるのが嫌で、[
プロパティ(P)」に固定するようにしています。


        /// <summary>
        /// プロパティラベルテキスト変更イベント
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Control_TextChanged(object sender, EventArgs e)
        {
            Control control = sender as Control;
            if (control == null)
            {
                return;
            }
            OnControlTextChanged(control, e);
        }

        /// <summary>
        /// プロパティラベルテキスト変更時に呼ばれる
        /// </summary>
        /// <param name="control"></param>
        /// <param name="e"></param>
        protected virtual void OnControlTextChanged(Control control, EventArgs e)
        {
            switch (control.Name)
            {
                case "propertiesLabel":
                    control.Text = "プロパティ(&P):";
                    break;
            }
        }

フォームクローズ時に重複プロパティがあればエラーメッセージを通知する

フォームのクローズ時にプロパティの内容をチェックして重複があればエラーメッセージを表示するようにしました。本当にしたかったことは重複があればフォームを閉じないようにしたかったのですが、クローズをキャンセルしてもリストボックスの要素が消えてしまうという問題を解決できなかったので、メッセージだけ出してクローズするようにしています。

        /// <summary>
        /// 指定した配列をコレクション内の項目として設定します。
        /// </summary>
        /// <param name="editValue"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        protected override object SetItems(object editValue, object[] value)
        {
            // 編集結果を取得してクローズ時に検証する
            _editedItems.Clear();
            _editedItems.AddRange(value);

            return base.SetItems(editValue, value);
        }

        /// <summary>
        /// フォームクローズ時に呼ばれる
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        protected virtual void OnClosing(object sender, FormClosingEventArgs e)
        {
            List<string> tempItems = new List<string>();
            foreach(object item in _editedItems)
            {
                if (tempItems.Contains(item as string))
                {
                    MessageBox.Show("タイトルが重複しています");
                    break;
                }
                tempItems.Add(item as string);
            }
        }
5
4
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
4

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?