zoukankan      html  css  js  c++  java
  • winform控件学习[TypeConverter(typeof(ScopeConverter))]

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.ComponentModel;
    using System.Windows.Forms;
    using System.Drawing;
    using System.ComponentModel.Design.Serialization;
    using System.Reflection;
    
    namespace CustomControlSample
    {
    /*
    CanConvertFrom()――根据类型参数进行测试,判断是否能从这个类型转换成当前类型,在本例中我们只提供转换string和InstanceDescriptor类型的能力。
    CanConvertTo()――根据类型参数进行测试,判断是否能从当前类型转换成指定的类型。
    ConvertTo()――将参数value的值转换为指定的类型。
    ConvertFrom()――串换参数value,并返回但书类型的一个对象。
    */
    
    #region Converter 类
    /// <summary>
    /// 三个方法CanConvertFrom,CanConvertTo,ConvertTo,ConvertFrom
    /// </summary>
    public class ScopeConverter : TypeConverter
    {
    public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
    {
    if (sourceType == typeof(String)) return true;
    
    return base.CanConvertFrom(context, sourceType);
    }
    
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
    if (destinationType == typeof(String)) return true;
    
    if (destinationType == typeof(InstanceDescriptor)) return true;
    
    return base.CanConvertTo(context, destinationType);
    }
    
    /*
    * ConvertTo的实现,如果转换的目标类型是string,
    * 我将Scope的两个属性转换成string类型,并且用一个“,”连接起来,
    * 这就是我们在属性浏览器里看到的表现形式,
    * 
    * 如果转换的目标类型是实例描述器(InstanceDescriptor,
    * 它负责生成实例化的代码),我们需要构造一个实例描述器,
    * 构造实例描述器的时候,我们要利用反射机制获得Scope类的构造器信息,
    * 并在new的时候传入Scope实例的两个属性值。实例描述器会为我们生成这样的代码:
    * this.myListControl1.Scope = new CustomControlSample.Scope(10, 200);
    * 在最后不要忘记调用 base.ConvertTo(context, culture, value, destinationType),
    * 你不需要处理的转换类型,交给基类去做好了。
    */
    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
    {
    String result = "";
    if (destinationType == typeof(String))
    {
    Scope scope = (Scope)value;
    result = scope.Min.ToString() + "," + scope.Max.ToString();
    return result;
    
    }
    
    if (destinationType == typeof(InstanceDescriptor))
    {
    ConstructorInfo ci = typeof(Scope).GetConstructor(new Type[] { typeof(Int32), typeof(Int32) });
    Scope scope = (Scope)value;
    return new InstanceDescriptor(ci, new object[] { scope.Min, scope.Max });
    }
    return base.ConvertTo(context, culture, value, destinationType);
    }
    
    
    /*
    * ConvertFrom的代码,由于系统能够直接将实例描述器转换为Scope类型,
    * 所以我们就没有必要再写代码,我们只需要关注如何将String(在属性浏览出现的属性值的表达)
    * 类型的值转换为Scope类型。没有很复杂的转换,只是将这个字符串以“,”分拆开,并串换为Int32类型
    * ,然后new一个Scope类的实例,将分拆后转换的两个整型值赋给Scope的实例,
    * 然后返回实例。在这段代码里,我们要判断一下用户设定的属性值是否有效。
    * 比如,如果用户在Scope属性那里输入了“10200”,
    * 由于没有输入“,”,我们无法将属性的值分拆为两个字符串,
    * 也就无法进行下面的转换,所以,我们要抛出一个异常,通知用户重新输入。
    */
    public override object ConvertFrom(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value)
    {
    if (value is string)
    {
    String[] v = ((String)value).Split(',');
    if (v.GetLength(0) != 2)
    {
    throw new ArgumentException("Invalid parameter format");
    }
    
    Scope csf = new Scope();
    csf.Min = Convert.ToInt32(v[0]);
    csf.Max = Convert.ToInt32(v[1]);
    return csf;
    }
    return base.ConvertFrom(context, culture, value);
    }
    /*
    * 为了在属性浏览器里能够独立的编辑子属性
    * ,我们还要重写两个方法:GetPropertiesSupported()和GetProperties();
    * 下面是ScopeConverter的完整代码:
    * 在GetProperties方法里,我用TypeDescriptor获得了Scope类的所有的属性描述器并返回。
    * 如果你对TypeDescriptor还不熟悉的话,可以参考MSDN。
    * 重写这两个方法并编译以后,在测试工程里查看控件的属性,你可以看到Scope是如下的形式
    */
    
    //下面方法实现对属性的子属性可进行编辑
    public override bool GetPropertiesSupported(ITypeDescriptorContext context)
    {
    return true;
    }
    
    public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
    {
    return TypeDescriptor.GetProperties(typeof(Scope), attributes);
    }
    }
    #endregion
    
     
    
    /// <summary>
    /// 指定转换器
    /// </summary>
    [TypeConverter(typeof(ScopeConverter))]
    //c#中没有提供类型转换器的类
    public class Scope
    {
    private Int32 _min;
    private Int32 _max;
    
    public Scope()
    {
    }
    
    public Scope(Int32 min, Int32 max)
    {
    _min = min;
    _max = max;
    }
    
    [Browsable(true)]
    public Int32 Min
    {
    get
    {
    return _min;
    }
    set
    {
    _min = value;
    }
    }
    
    [Browsable(true)]
    public Int32 Max
    {
    get
    {
    return _max;
    }
    set
    {
    _max = value;
    }
    
    }
    }
    
     
    
    
    //主代码
    public class MyListControl:System.Windows.Forms.Control
    {
    private List<Int32> _list = new List<Int32>();
    private Scope _scope = new Scope(1, 9);
    
    public MyListControl()
    {
    
    }
    
    [Browsable(true)]
    public List<Int32> Item
    {
    get
    {
    return _list;
    }
    set
    {
    _list = value;
    }
    }
    [Browsable(true)]
    //属性为其他类型
    public Scope Scope
    {
    get
    {
    return _scope;
    }
    set
    {
    _scope = value;
    }
    }
    
    protected override void OnPaint(PaintEventArgs e)
    {
    base.OnPaint(e);
    
    Graphics g = e.Graphics;
    //绘制控件的边框
    
    g.DrawRectangle(Pens.Black, new Rectangle(Point.Empty, new Size(Size.Width - 1, Size.Height - 1)));
    
    for (Int32 i = 0; i < _list.Count; i++)
    {
    g.DrawString(_list[i].ToString(), Font, Brushes.Black, 1, i * FontHeight);
    }
    }
    }
    }
  • 相关阅读:
    接水果(fruit)
    大融合
    排序(sortb)
    latex公式测试
    次小生成树
    HDU 2973 YAPTCHA (威尔逊定理)
    状压DP概念 及例题(洛谷 P1896 互不侵犯)
    ICPC Asia Nanning 2017 F. The Chosen One (大数、规律、2的k次幂)
    HDU 1074 Doing Homework (状压DP)
    最长上升(不下降)子序列(LIS) 不同求解方法(动规、贪心)
  • 原文地址:https://www.cnblogs.com/anbylau2130/p/2724023.html
Copyright © 2011-2022 走看看