提供3000多款全球软件/控件产品
针对软件研发的各个阶段提供专业培训与技术咨询
根据客户需求提供定制化的软件开发服务
全球知名设计软件,显著提升设计质量
打造以经营为中心,实现生产过程透明化管理
帮助企业合理产能分配,提高资源利用率
快速打造数字化生产线,实现全流程追溯
生产过程精准追溯,满足企业合规要求
以六西格玛为理论基础,实现产品质量全数字化管理
通过大屏电子看板,实现车间透明化管理
对设备进行全生命周期管理,提高设备综合利用率
实现设备数据的实时采集与监控
利用数字化技术提升油气勘探的效率和成功率
钻井计划优化、实时监控和风险评估
提供业务洞察与决策支持实现数据驱动决策
转帖|其它|编辑:郝浩|2010-12-01 13:49:13.000|阅读 615 次
概述:在设计用户控件的时候(不管是winform还是webform),对于一般的简单属性(string,int,bool……基元类型)系统会为我们自动提供相应的类型转换。本文主要介绍用户控件中复杂属性的设计时支持
# 慧都年终大促·界面/图表报表/文档/IDE等千款热门软控件火热促销中 >>
在设计用户控件的时候(不管是winform还是webform),对于一般的简单属性(string,int,bool……基元类型)系统会为我们自动提供相应的类型转换。举个例子:我们在用户控件中定义一个Age属性
public int Age
{
get;
set;
}
这时我们打开设计器,就会看到
这个属性了。我们可以随便为其设置int类型的值。但是当我们试着填写一个string类型的字符时,系统就会弹出一个"属性无效"窗口,在这个过程中我们就可以看出系统已经为Age做了类型转换,而且这个转换失败了,因为类型不匹配。
现在让我们再写一个复杂点的属性Person。先创建一个Person类,它里面包含了name和age属性:
public class Person
{
private string strName;
private int intAge;
public string StrName
{
get { return strName; }
set { strName = value; }
}
public int IntAge
{
get { return intAge; }
set { intAge = value; }
}
}
然后在用户控件中,我们新建一个person的属性:
private Person person;
public Person Person
{
get { return person; }
set { person = value; }
}
打开设计器窗体后我们可以看到Person属性是灰色的
为什么会这样呢?答案很简单,系统不知道如何去显示这个属性。但总得显示点儿什么吧?于是无可奈何下显示了person类的类型名。这与我们所期望的形如Location样式的可差远了
到底差在哪里呢?类型转换器!当我们在Person里面填写"zhangsan,21"的时候,类型转换器就能自动将这两个属性值对应到strName,intAge上面去,这就是类型转换器的作用。那么下面我们就来实现一个person的类型转换器。
实现类型转换器
首先新建一个新类PersonConverter,用于提供person类型转换的能力,所有的注释我都写在代码里面了,大家一看就明白:
public class PersonConverter:TypeConverter
{
//指示我们设置的内容能否转换
//因为我们输入的是"zhangsan,12"的字符串形式,所以这里接受字符串类型的转换
public override bool CanConvertFrom(ITypeDescriptorContext context, Type sourceType)
{
return sourceType == typeof(string) || base.CanConvertFrom(context, sourceType);
}
//这个方法指示了最后的这个复杂属性是以什么形式表现出来的。
//如果destinationType == typeof(string)的话,最后person显示的就是"zhangsan,21"的形式
//如果destinationType == typeof(InstanceDescriptor)的话,person显示的就是"WindowsFormsControlLibrary1.Person"类名的形式。
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);
}
//这个方法实现了我们输入的字符串如何被转化为person类型
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");
}
Person csf = new Person { Name = Convert.ToString(v[0]), Age = Convert.ToInt32(v[1]) };
return csf;
}
return base.ConvertFrom(context, culture, value);
}
//这个则是实现了具体如何显示person这个属性的方法
public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
{
if (destinationType == typeof(String))
{
Person scope = (Person)value;
String result = scope.Name.ToString() + "," + scope.Age.ToString();
return result;
}
if (destinationType == typeof(InstanceDescriptor))
{
ConstructorInfo ci = typeof(Person).GetConstructor(new Type[] { typeof(string), typeof(Int32) });
Person scope = (Person)value;
return new InstanceDescriptor(ci, new object[] { scope.Name, scope.Age });
}
return base.ConvertTo(context, culture, value, destinationType);
}
//以下两个方法提供子属性单独设置的能力。
public override bool GetPropertiesSupported(ITypeDescriptorContext context)
{
return true;
}
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context, object value, Attribute[] attributes)
{
return TypeDescriptor.GetProperties(typeof(Person), attributes);
}
}
然后在用户控件的person属性上加上这么一句,指定了person的转换器:
[TypeConverter(typeof(PersonConverter))]
public Person Person
{
get;
set;
}
我们现在再来看看person的设计时的样子,这样就和我们需求的一样了。
这里再教大家一个偷懒的方法,就是实现转换器的时候不必重写最上面的那四个方法,直接重写"提供子属性单独设置的能力"的两个方法就是了。只不过这样person属性显示的效果如下:
就是person显示的内容变了,子属性还是提供设置。对于要求不高的属性也够了。
实现模态属性编辑器
前面我们实现了形如Location属性的设计时属性设置支持,但我们有时需要的可能不只是这么复杂的属性设置。比如BackgroundImage这个属性,当我们设置它的时候,系统会弹出一个界面出来让我们选择图片:
使用这种方式无疑增加了我们选择图片的方便度。那这种形式的设置该如何实现呢?
首先我们新建一个窗体,这个窗体就是将来需要显示给用户设置属性的(比如上图的"选择资源"窗体)。我们还是以person类为例:
该窗体的后台代码如下:
private Person _person;
public PersonWindow(Person person)
{
InitializeComponent();
Person = person;
textBox1.Text = person.StrName;
textBox2.Text = person.IntAge.ToString();
}
public Person Person
{
get { return _person; }
set { _person = value; }
}
/// <summary>
/// 确认按钮
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void button1_Click(object sender, EventArgs e)
{
Person.StrName = textBox1.Text;
Person.IntAge = int.Parse(textBox2.Text);
}
这里要注意的一点就是confirm按钮的DialogResult要设置为DialogResult.OK,cancel按钮的DialogResult要设置为DialogResult.Cancel。至于为什么要这么做大家往后看就知道了。
然后我们再建立一个class PersonModalEditor:System.Drawing.Design.UITypeEditor类,其代码如下:
public override System.Drawing.Design.UITypeEditorEditStyle GetEditStyle(System.ComponentModel.ITypeDescriptorContext context)
{
//指示以什么样的形式打开编辑窗体
return UITypeEditorEditStyle.Modal;
}
//属性编辑方法,当我们单击属性窗口中的属性按钮时会执行这个方法。
public override object EditValue(System.ComponentModel.ITypeDescriptorContext context, IServiceProvider provider, object value)
{
//获取服务对象,这个对象专门为winform编辑器提供一些功能
IWindowsFormsEditorService service =
(IWindowsFormsEditorService) provider.GetService(typeof (IWindowsFormsEditorService));
if (service==null)
{
return null;
}
Person p = new Person();
CategoryWindow form = new CategoryWindow(p);
//这里知道为什么要设置confirm按钮的DialogResult属性的原因了吧。
if (service.ShowDialog(form) == System.Windows.Forms.DialogResult.OK)
{
return p;
}
return value; //系统会根据这个返回值在person属性里面进行填充
}
最后我们在用户控件的person属性上加上这个一句话:
[Editor(typeof(CategoryModalEditor), typeof(UITypeEditor))]
public Person Person
{
get { return person; }
set { person = value; }
}
这句话指定了系统如何打开person的属性编辑器。我们看看效果图:
本站文章除注明转载外,均为本站原创或翻译。欢迎任何形式的转载,但请务必注明出处、不得修改原文相关链接,如果存在内容上的异议请邮件反馈至chenjj@pclwef.cn
文章转载自:博客转载面对“数字中国”建设和中国制造2025战略实施的机遇期,中车信息公司紧跟时代的步伐,以“集约化、专业化、标准化、精益化、一体化、平台化”为工作目标,大力推进信息服务、工业软件等核心产品及业务的发展。在慧都3D解决方案的实施下,清软英泰建成了多模型来源的综合轻量化显示平台、实现文件不失真的百倍压缩比、针对模型中的大模型文件,在展示平台上进行流畅展示,提升工作效率,优化了使用体验。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
本站的模型资源均免费下载,登录后即可下载。模型仅供学习交流,勿做商业用途。
服务电话
重庆/ 023-68661681
华东/ 13452821722
华南/ 18100878085
华北/ 17347785263
客户支持
技术支持咨询服务
服务热线:400-700-1020
邮箱:sales@pclwef.cn
关注我们
地址 : 重庆市九龙坡区火炬大道69号6幢