艾伟:WinForm控件开发总结(五)-----为控件的复杂属性提供类型转换器

简介: 上一篇文章我已经介绍了TypeConverterAttribute元数据的作用,本文将通过代码向你展示具体的实现。在这个例子中,我要给控件添加一个复杂的属性,这个属性对这个控件没有什么功用,纯粹是为了演示,有些牵强附会了。

      上一篇文章我已经介绍了TypeConverterAttribute元数据的作用,本文将通过代码向你展示具体的实现。在这个例子中,我要给控件添加一个复杂的属性,这个属性对这个控件没有什么功用,纯粹是为了演示,有些牵强附会了。
       现在在前一篇文章中的创建的控件代码中添加一个Scope属性:
      

        [Browsable(true)]
        public Scope Scope
         {
            get
             {
                return _scope;
            }
            set
             {
                _scope = value;
            }
        }
      这个属性的类型是Scope类,代码如下:
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;
            }
           
        }
}

       添加完属性后,build控件工程,然后在测试的工程里选中添加的控件,然后在属性浏览器里观察它的属性,发现Scope属性是灰的,不能编辑。前一篇文章提到了,在属性浏览器里可以编辑的属性都是有类型转换器的,而.NET框架为基本的类型和常用的类型都提供了默认的类型转换器。接下来我们为Scope类添加一个类型转换器,以便这个属性能够被编辑,而且也可以在源代码文件里自动生成相应的代码。下面是类型转换器的代码:

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);
        }

        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);
        }

        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);
        }
    }

      现在我们为类型提供类型转换器,我们在类型前面添加一个TypeConverterAttribute,如下:
           
    [TypeConverter(typeof(ScopeConverter))]
    public class Scope
        添加完以后build工程,然后切换到测试工程,选中控件,在属性浏览器里查看属性,现在的Scope属性可以编辑了,如下图所示: 
         
         我们修改默认的值,然后看看Form设计器为我们生成了什么代码:
      
this.myListControl1.BackColor = System.Drawing.SystemColors.ActiveCaptionText;
            this.myListControl1.Item.Add(1);
            this.myListControl1.Item.Add(2);
            this.myListControl1.Item.Add(3);
            this.myListControl1.Item.Add(6);
            this.myListControl1.Item.Add(8);
            this.myListControl1.Item.Add(9);
            this.myListControl1.Location = new System.Drawing.Point(12, 34);
            this.myListControl1.Name = "myListControl1";
            this.myListControl1.Scope = new CustomControlSample.Scope(10, 200);
            this.myListControl1.Size = new System.Drawing.Size(220, 180);
            this.myListControl1.TabIndex = 1;
        this.myListControl1.Text = "myListControl1";
        关键是这一行this.myListControl1.Scope = new CustomControlSample.Scope(10, 200),Scope类的类型转换器为属性提供了实例化的代码。      
目录
相关文章
|
C# 容器
Winform控件优化之TabControl控件的美化和功能扩展
在基本的TabControl控件使用和功能之上,可以尝试对其进行美化和功能扩展,比如动态删除或添加tab、绘制图标按钮及鼠标hover时的背景变化、Tab从右向左布局的优化处理等。最重要...
2064 0
Winform控件优化之TabControl控件的美化和功能扩展
|
9月前
|
C# 容器
WPF框架下,窗体的嵌套显示
WPF框架下,窗体的嵌套显示
172 0
|
前端开发 C# 图形学
【WPF】WPF开发用户控件、用户控件属性依赖DependencyProperty实现双向绑定、以及自定义实现Command双向绑定功能演示
Wpf开发过程中,最经常使用的功能之一,就是用户控件(UserControl)了。用户控件可以用于开发用户自己的控件进行使用,甚至可以用于打造一套属于自己的UI框架。依赖属性(DependencyProperty)是为用户控件提供可支持双向绑定的必备技巧之一,同样用处也非常广泛。
782 0
【WPF】WPF开发用户控件、用户控件属性依赖DependencyProperty实现双向绑定、以及自定义实现Command双向绑定功能演示
|
C#
WPF整理-为控件添加自定义附加属性
原文:WPF整理-为控件添加自定义附加属性 附加属性,大家都不陌生,最常见的是Canvas.Left/Canvas.Top,类似的也有Grid.Row/Grid.Column等附加属性。举个最常见的例子 需要说明的是并不是所有的附加属性都是元素放进去后才会有附加效果,上面的例子只是刚好是这种错觉的巧合情况,Grid.Row也属于这种巧合。
2042 0
艾伟:WinForm控件开发总结(六)-----控件属性类型转换器代码详解
在上一篇文章,我为控件添加一个一个复杂属性,并且为这个属性的类型的编写了一个类型转换器,现在我们来看看这个类型转换器的代码,并解释一下这些代码的意义。       要实现一个类型转换器,我们必须要重写(override)四个方法:       CanConvertFrom()――根据类型参数进行测试,判断是否能从这个类型转换成当前类型,在本例中我们只提供转换string和InstanceDescriptor类型的能力。
812 0
|
Web App开发
艾伟:WinForm控件开发总结(三)------认识WinForm控件常用的Attribute
在前面的文章里我们制作了一个非常简单的控件。现在我们回过头来看看这些代码透露出什么信息。   这个类是直接从Control类派生出来的,自定义控件都是直接从Control类派生出来的。这个类定义了一个属性TextAlignment,用来控制文本在控件中显示的位置:           ...
977 0
|
Web App开发
艾伟:WinForm控件开发总结(七)-----为复杂属性的子属性提供编辑功能
前面的几篇文章中,我们给控件添加一个复杂的类型Scope,并且给它的类型提供的一个类型转换器,现在我们可以在属性浏览器中编辑它的值,并且它的值也被串行化的源代码里了。但是你有没有发现,在属性浏览器里编辑这个属性的值还是不太方便。
666 0
|
C#
艾伟_转载:WPF/Silverlight陷阱:XAML自定义控件的嵌套内容无法通过名称访问
为了说明这个问题,假定我们需要实现一个具有特殊功能的按钮控件。编写Xaml文件如下: Button> 对 Code Behind类,唯一的改动是把向导生成的基类从UserControl改成Button: public partial class XamlButton : Button{    ...
1046 0
|
Web App开发
艾伟:WinForm控件开发总结(四)-----控件属性的串行化
前一篇文章介绍了常用的设计时Attribute。其中BrowsableAttribute,CategoryAttribute,DescriptionAttribute,DefaultPropertyAttribute,DefaultEventAttribute都是比较简单的,也是可有可无,但是为了提供更好的用户体验这些Attribute最好不要省掉,如果你对这些Attribute还不熟悉,可以参考我前一篇文章的描述或者查看MSDN,这里我就不在赘述了。
932 0
|
Android开发
QTQuick控件基础(2)
import QtQuick 2.2import QtQuick.Controls 1.2import QtQuick.Window 2.1ApplicationWindow {    visible: true    width: 640    height: 480    title: qsTr...
971 0

热门文章

最新文章