欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

.net WinForm用户控件开发--(5)用户控件复杂属性设置

程序员文章站 2022-05-20 18:52:26
  这一节,大家共同学习下,用户控件的自定义的复杂的属性设置,我们这里自定义一个用户控件和自定义一个属性。    本节重点:    &nb...

  这一节,大家共同学习下,用户控件的自定义的复杂的属性设置,我们这里自定义一个用户控件和自定义一个属性。

   本节重点:

      1.怎样定义复杂属性

      2.复杂属性和基本类型相互转换  

 1.第一步, 先来自定义一个类,代码如下

   

[csharp]
/// <summary>  
   /// 自定义属性类  
   /// </summary>  
   public class customattri 
   { 
 
       public customattri(int width, int height) 
       { 
           _width = width; 
           _height = height; 
       } 
 
       public customattri() 
       {  
        
       } 
       private int _width; 
       private int _height; 
 
       /// <summary>  
       /// 宽度  
       /// </summary>  
       public int width 
       { 
           get 
           { return _width; } 
           set 
           { 
               _width = value; 
           } 
       } 
 
       /// <summary>  
       /// 高度  
       /// </summary>  
       public int height 
       { 
           get 
           { 
               return _height; 
           } 
           set 
           { 
               _height = value; 
           } 
       } 
   } 

 /// <summary>
    /// 自定义属性类
    /// </summary>
    public class customattri
    {

        public customattri(int width, int height)
        {
            _width = width;
            _height = height;
        }

        public customattri()
        {
       
        }
        private int _width;
        private int _height;

        /// <summary>
        /// 宽度
        /// </summary>
        public int width
        {
            get
            { return _width; }
            set
            {
                _width = value;
            }
        }

        /// <summary>
        /// 高度
        /// </summary>
        public int height
        {
            get
            {
                return _height;
            }
            set
            {
                _height = value;
            }
        }
    }
  然后自定义一个控件,并且定义一属性secondsize,代码如下

  

[csharp]
public partial class ucpanel : control 
    { 
        public ucpanel() 
        { 
            initializecomponent(); 
        } 
 
      private customattri _ssize=new customattri(20,30);; 
        /// <summary>  
        /// 定义自定义属性  
        /// </summary>  
        [description("第二尺寸")] 
        [category("尺寸")] 
        public customattri secondsize 
        {  
          get 
          { 
            return _ssize; 
          } 
         set 
            { 
              _ssize=value; 
            } 
        } 
    } 

public partial class ucpanel : control
    {
        public ucpanel()
        {
            initializecomponent();
        }

      private customattri _ssize=new customattri(20,30);;
        /// <summary>
        /// 定义自定义属性
        /// </summary>
        [description("第二尺寸")]
        [category("尺寸")]
        public customattri secondsize
        {
          get
          {
            return _ssize;
          }
         set
            {
              _ssize=value;
            }
        }
    }

   此时编译项目,然后把用户控件拖到窗体上,就可以在属性设计器中看到此属性,但是此时属性是只读的,不能设置值。

   效果图如下:

       

 .net WinForm用户控件开发--(5)用户控件复杂属性设置

2. 接下来,我们实现让用户可以自己设置属性的值,并把用户输入的值进行转换。

    如果想要把用户输入的值转换为我们自定义的类型,需要继承typeconverter 类,并实现其方法。

    转换器代码如下:

    

[csharp]
/// <summary>  
   /// 自定义类型转换器  
   /// </summary>  
   public class customattriconverter:typeconverter 
   { 
       /// <summary>  
       /// 表示是否允许将给定类型的对象转换为自定义类型  
       /// </summary>  
       /// <param name="context">当前上下文对象</param>  
       /// <param name="sourcetype">给定的类型</param>  
       /// <returns></returns>  
       public override bool canconvertfrom(itypedescriptorcontext context, type sourcetype) 
       { 
           //如果给定的类型为字符串,可以转换为自定义类型  
           if (sourcetype==typeof(string)) 
           { 
               return true; 
           } 
           return base.canconvertfrom(context, sourcetype); 
       } 
 
       /// <summary>  
       /// 表示是否允许将自定义类型转换为指定的类型  
       /// </summary>  
       /// <param name="context">当前上下文</param>  
       /// <param name="destinationtype">指定的类型</param>  
       /// <returns></returns>  
       public override bool canconvertto(itypedescriptorcontext context, type destinationtype) 
       { 
           //如果目标类型是字符串,允许将自定义类型转换为字符串  
           if (destinationtype==typeof(string)) 
           { 
               return true; 
           } 
           return base.canconvertto(context, destinationtype); 
       } 
 
       /// <summary>  
       /// 将指定类型转换为自定义类型  
       /// </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) 
           { 
               string[] sizearr = ((string)value).split(',');//将输入的字符串以逗号进行分割  
               customattri ca = new customattri(); 
               ca.width=convert.toint16(sizearr[0]); 
               ca.height=convert.toint16(sizearr[1]); 
               return ca; 
           } 
           return base.convertfrom(context, culture, value); 
       } 
 
       /// <summary>  
       /// 将自定义类型转换为指定类型  
       /// </summary>  
       /// <param name="context">当前上下文</param>  
       /// <param name="culture">区域</param>  
       /// <param name="value"></param>  
       /// <param name="destinationtype">指定类型</param>  
       /// <returns></returns>  
       public override object convertto(itypedescriptorcontext context, system.globalization.cultureinfo culture, object value, type destinationtype) 
       { 
           //如果要转换为自定义类型  
           if (destinationtype==typeof(string)) 
           { 
               if (value is customattri) 
               { 
                   customattri ca = (customattri)value; 
                   return ca.width.tostring() + "," + ca.height.tostring(); 
               }    
           } 
           return base.convertto(context, culture, value, destinationtype); 
       } 
 
 
   } 

 /// <summary>
    /// 自定义类型转换器
    /// </summary>
    public class customattriconverter:typeconverter
    {
        /// <summary>
        /// 表示是否允许将给定类型的对象转换为自定义类型
        /// </summary>
        /// <param name="context">当前上下文对象</param>
        /// <param name="sourcetype">给定的类型</param>
        /// <returns></returns>
        public override bool canconvertfrom(itypedescriptorcontext context, type sourcetype)
        {
            //如果给定的类型为字符串,可以转换为自定义类型
            if (sourcetype==typeof(string))
            {
                return true;
            }
            return base.canconvertfrom(context, sourcetype);
        }

        /// <summary>
        /// 表示是否允许将自定义类型转换为指定的类型
        /// </summary>
        /// <param name="context">当前上下文</param>
        /// <param name="destinationtype">指定的类型</param>
        /// <returns></returns>
        public override bool canconvertto(itypedescriptorcontext context, type destinationtype)
        {
            //如果目标类型是字符串,允许将自定义类型转换为字符串
            if (destinationtype==typeof(string))
            {
                return true;
            }
            return base.canconvertto(context, destinationtype);
        }

        /// <summary>
        /// 将指定类型转换为自定义类型
        /// </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)
            {
                string[] sizearr = ((string)value).split(',');//将输入的字符串以逗号进行分割
                customattri ca = new customattri();
                ca.width=convert.toint16(sizearr[0]);
                ca.height=convert.toint16(sizearr[1]);
                return ca;
            }
            return base.convertfrom(context, culture, value);
        }

        /// <summary>
        /// 将自定义类型转换为指定类型
        /// </summary>
        /// <param name="context">当前上下文</param>
        /// <param name="culture">区域</param>
        /// <param name="value"></param>
        /// <param name="destinationtype">指定类型</param>
        /// <returns></returns>
        public override object convertto(itypedescriptorcontext context, system.globalization.cultureinfo culture, object value, type destinationtype)
        {
            //如果要转换为自定义类型
            if (destinationtype==typeof(string))
            {
                if (value is customattri)
                {
                    customattri ca = (customattri)value;
                    return ca.width.tostring() + "," + ca.height.tostring();
                }  
            }
            return base.convertto(context, culture, value, destinationtype);
        }


    }
   然后把该转换器标记在自定义属性上,这样在窗体上,就可以为该用户控件的属性设置值了

   

[csharp]
[description("第二尺寸")] 
    [category("尺寸")] 
    [typeconverter(typeof(customattriconverter))] 
    public customattri secondsize 
    {  
      get 
      { 
        return _ssize; 
      } 
     set 
        { 
          _ssize=value; 
        } 
    } 

    [description("第二尺寸")]
        [category("尺寸")]
        [typeconverter(typeof(customattriconverter))]
        public customattri secondsize
        {
          get
          {
            return _ssize;
          }
         set
            {
              _ssize=value;
            }
        }
    效果图:

 .net WinForm用户控件开发--(5)用户控件复杂属性设置

 3.子属性的实现

  上面代码虽然实现了可以给自定义属性设置值,但是字属性不能显示出来,如果想实现把子属性显示出来,需要重载以下方法

   

[csharp]
/// <summary>  
      /// 返回此对象是否支持属性。  
      /// </summary>  
      /// <param name="context"></param>  
      /// <returns></returns>  
      public override bool getpropertiessupported(itypedescriptorcontext context) 
      { 
          return true; 
      } 
 
      public override propertydescriptorcollection getproperties(itypedescriptorcontext context, object value, attribute[] attributes) 
      { 
          //return base.getproperties(context, value, attributes);  
          return typedescriptor.getproperties(typeof(customattri), attributes); 
      } 

  /// <summary>
        /// 返回此对象是否支持属性。
        /// </summary>
        /// <param name="context"></param>
        /// <returns></returns>
        public override bool getpropertiessupported(itypedescriptorcontext context)
        {
            return true;
        }

        public override propertydescriptorcollection getproperties(itypedescriptorcontext context, object value, attribute[] attributes)
        {
            //return base.getproperties(context, value, attributes);
            return typedescriptor.getproperties(typeof(customattri), attributes);
        }
  效果图:

  .net WinForm用户控件开发--(5)用户控件复杂属性设置

 至此,复杂自定义属性的设置,我们已经讲解完成。

 

 作者:zx13525079024