扩展提供程序和复杂类型,设计模式 [英] Extender Provider and Complex Types, Design Mode
问题描述
大家好
假设您为控件创建了扩展程序提供程序,如下所示:
Hi All
Suppose you created an extender provider for controls as follows:
[ProvideProperty("Information", typeof(Control))]
public class TestExtender:Component, IExtenderProvider
{
public Information GetInformation(Control extendee) {
// retrieves information object from a Dictionary<control,> list
}
public Information SetInformation(Control extendee, Information information) {
// adds information to Dictionary<control,>
}
}
(other details omitted to focus on the Information object)
该信息对象将具有许多属性(标题,文本等).
编译后,我将扩展程序提供程序添加到窗体中,并且按预期方式将Information属性添加到PropertyGrid.
我的问题-如何获得PropertyGrid来将Information的子属性添加到PropertyGrid?
因此,在控件的PropertyGrid中,例如说TextBox1,将有一个属性Information,而当您单击+时,它将显示Information类的属性.
我无法弄清楚该怎么做.
The information object would have numerous properties (Title, Text, etc).
When compiled, I add the extender provider to the form, and it adds an Information property to the PropertyGrid as expected.
My question - how do you get the PropertyGrid to add the subproperties of Information to the PropertyGrid?
So, in the PropertyGrid of a Control, say TextBox1, there would be a property Information, and when you click the +, it would display the properties of class Information.
I can''t figure out how to do this.
推荐答案
此方法适用于普通的UserControl,因此应该对您有效:
定义基础字段,并为其创建一个公共属性,并带有所需的显示属性的名称.包括属性属性",如下所示:
This works for a normal UserControl, so it should work for you:
Define the base field, and create a public property for it, with the name of the display property you wish. Include the property Properties as shown below:
private ThumbDisplay thumb = new ThumbDisplay();
[Category("Appearance"),
DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public ThumbDisplay Thumbnails
{
get { return thumb; }
set { thumb = value; }
}
使用该属性为属性创建您的类,如下所示:
Create your class for the property, with Properties as shown:
[TypeConverter(typeof(ThumbInfoConverter))]
public class ThumbDisplay
{
private int minWidth = 25;
[NotifyParentProperty(true),
RefreshProperties(RefreshProperties.Repaint)]
public int MinWidth
{
get { return minWidth; }
set { minWidth = value; }
}
private int initialWidth = 100;
[NotifyParentProperty(true),
RefreshProperties(RefreshProperties.Repaint)]
public int InitialWidth
{
get { return initialWidth; }
set { initialWidth = value; }
}
private int maxWidth = 255;
[NotifyParentProperty(true),
RefreshProperties(RefreshProperties.Repaint)]
public int MaxWidth
{
get { return maxWidth; }
set { maxWidth = value; }
}
}
}
为您的班级创建InfoConverter类:
Create the InfoConverter class for your class:
class ThumbInfoConverter : ExpandableObjectConverter
{
/// <summary>
/// CanConvertFrom specifies data types the converter can convert from.
/// </summary>
/// <param name="context"></param>
/// <param name="t"></param>
/// <returns></returns>
public override bool CanConvertFrom(ITypeDescriptorContext context,
Type t)
{
if (t == typeof(string))
{
return true;
}
return base.CanConvertFrom(context, t);
}
/// <summary>
///ConvertFrom actually implements the conversion.
/// </summary>
/// <param name="context"></param>
/// <param name="info"></param>
/// <param name="value"></param>
/// <returns></returns>
public override object ConvertFrom(ITypeDescriptorContext context,
CultureInfo info,
object value)
{
if (value is string)
{
try
{
string s = (string)value;
//Parse the format "min, initial, max"
Regex r = new Regex(@"\s*(?<min>\d+),\s*(?<initial>\d+),\s*(?<max>\s*\d+)");
Match m = r.Match(s);
if (m.Groups.Count == 4)
{
// All ok
int min = Convert.ToInt32(m.Groups[1].Value);
int initial = Convert.ToInt32(m.Groups[2].Value);
int max = Convert.ToInt32(m.Groups[3].Value);
ThumbDisplay t = new ThumbDisplay();
t.MinWidth = min;
t.InitialWidth = initial;
t.MaxWidth = max;
return t;
}
}
catch { }
// If you got this far, complain that you
// could not parse the string.
throw new ArgumentException("Cannot convert '" + (string)value +
"' to type ThumbDisplay \"minimumWidth, initialWidth, "+
"maximumWidth\"");
}
return base.ConvertFrom(context, info, value);
}
/// <summary>
///CanConvertTo specifies which data types the converter can convert to.
/// </summary>
/// <param name="context"></param>
/// <param name="culture"></param>
/// <param name="value"></param>
/// <param name="destType"></param>
/// <returns></returns>
public override object ConvertTo(ITypeDescriptorContext context,
CultureInfo culture,
object value,
Type destType)
{
if (destType == typeof(string))
{
ThumbDisplay t = (ThumbDisplay)value;
return string.Format("{0}, {1}, {2}",
t.MinWidth,
t.InitialWidth,
t.MaxWidth);
}
return base.ConvertTo(context, culture, value, destType);
}
}
为了自己提供子属性的排序顺序,请覆盖ExpandableObjectConverter GetProperties方法:
In order to provide the sort order for the subproperties yourself, overide the ExpandableObjectConverter GetProperties method:
public override PropertyDescriptorCollection GetProperties(ITypeDescriptorContext context,
object value,
Attribute[] attributes)
{
return TypeDescriptor.GetProperties(typeof(ThumbDisplay), attributes).Sort(new string[] { "MinWidth", "InitialWidth", "MaxWidth" });
}
这篇关于扩展提供程序和复杂类型,设计模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!