カスタムコントロールのプロパティの型をコントロールにしたい時に必要なTypeConverterの実装

以前に、.NET Framework1.1を利用している時に下記のエントリをしました。

カスタムコントロールのプロパティの型をコントロールにしたい時に必要なTypeConverterの抽象クラスです。

各、コントロール毎にTypeConverterを一から作るのはめんどくさいので、抽象クラスを作っておいて、継承先で型を指定するプロパティをオーバライドする事で指定の型のTypeConverterを作成しています。

今回、ジェネリックを利用する事で、抽象クラスである必要が無くなり、継承する必要がなくなりました。
利用するときに、その型を指定すればよいだけです。

using System;
using System.Drawing;
using System.Reflection;
using System.Collections;
using System.ComponentModel;
using System.ComponentModel.Design;
using System.ComponentModel.Design.Serialization;
namespace NAL6295.Web.UI.Controls
{
    /// <summary>
    /// コントロールの型情報と型名の相互変換
    /// </summary>
    /// <typeparam name="T">System.Web.UI.Controlを継承したクラスのみ指定可能</typeparam>
    public class ControlConverter<T> : System.ComponentModel.StringConverter where T:System.Web.UI.Control    {


        private ArrayList _values;

        /// <summary>
        ///		値リストのサポートを許可する
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>		
        public override bool GetStandardValuesSupported(System.ComponentModel.ITypeDescriptorContext context)
        {
            return true;
        }

        /// <summary>
        ///		値リストの作成
        /// </summary>
        /// <param name="context"></param>
        /// <returns>デザイン画面に存在するControlTypeプロパティで指定されたコントロールのリストを取得しそのIDリストを返す</returns>
        public override System.ComponentModel.TypeConverter.StandardValuesCollection GetStandardValues(System.ComponentModel.ITypeDescriptorContext context)
        {
            _values = new ArrayList();

            foreach (System.Web.UI.Control item in GetControlList(context))
            {
                _values.Add(item.ID);
            }

            return new System.ComponentModel.TypeConverter.StandardValuesCollection(_values);
        }

        /// <summary>
        ///		文字列型から指定された型への変換
        ///		選択リストに無い文字列が指定されていたときは、String.Emptyを返す
        /// </summary>
        /// <param name="context"></param>
        /// <param name="culture"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
        {
            if (value is string)
            {
                foreach (System.Web.UI.Control item in GetControlList(context))
                {
                    if (item.ID == (string)value)
                    {
                        return base.ConvertFrom(context, culture, value);
                    }
                }
                return string.Empty;
            }
            return base.ConvertFrom(context, culture, value);
        }

        /// <summary>
        ///		指定された型のリストを返す
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        private object[] GetControlList(ITypeDescriptorContext context)
        {
            IReferenceService serv = (IReferenceService)context.GetService(typeof(IReferenceService));
            return serv.GetReferences(typeof(T));
        }
    }
}

利用例:

	public class カスタムコントロール : Control
	{
		//いろんな処理
	
		private _hintControlName = "";
		[TypeConverter(typeof(ControlConverter<Label>))
		,DefaultValue("")
		,Description("このコントロールのヒントを表示するラベルを選択するプロパティです。")]
		public string Hint
		{
			get
			{
				return _hintControlName;
			}
			set
			{
				_hintControlName = value;

			}
		}

		//いろんな処理


	}