前言:相较于之前文章,用这种方式优点是可以修改在属性控件上显示的效果,然后重新绑定就可以了
1.效果图
2.使用举例
PropertyGridProperty propertyGridProperty = new PropertyGridProperty();
Property p1 = new Property("自定义", "名称", "Name", "", "Bridge", false, true);
p1.Converter = new DropDownListConverter("Bridge", "Hani", "Jodan");
propertyGridProperty.Add(p1);
Property p2 = new Property("自定义", "年龄", "Age", "", 100, false, true);
propertyGridProperty.Add(p2);
Property p3 = new Property("自定义", "籍贯", "Location", "", "sz", false, true);
p3.Converter = new DropDownListConverter("sz", "gz", "bj");
propertyGridProperty.Add(p3);
this.propertyGrid1.SelectedObject = propertyGridProperty;
3.属性类和类型转换器
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
namespace AttributeTest
{
/// <summary>
/// PropertyGrid对应的类
/// </summary>
public class PropertyGridProperty : ICustomTypeDescriptor
{
List<Property> _listProperty = new List<Property>();
public void Add(Property value)
{
if (value != null)
{
if (!_listProperty.Contains(value))
{
_listProperty.Add(value);
}
}
}
public void Remove(Property value)
{
if (value != null && _listProperty.Contains(value))
{
_listProperty.Remove(value);
}
}
public Property this[int index]
{
get
{
return _listProperty[index];
}
set
{
_listProperty[index] = value;
}
}
public Property this[object name]
{
get
{
return _listProperty.FirstOrDefault(p => p.Name == name.ToString());
}
set
{
Property pre = _listProperty.FirstOrDefault(p => p.Name == name.ToString());
pre = value;
}
}
#region ICustomTypeDescriptor 成员
public AttributeCollection GetAttributes()
{
return TypeDescriptor.GetAttributes(this, true);
}
public string GetClassName()
{
return TypeDescriptor.GetClassName(this, true);
}
public string GetComponentName()
{
return TypeDescriptor.GetComponentName(this, true);
}
public TypeConverter GetConverter()
{
return TypeDescriptor.GetConverter(this, true);
}
public EventDescriptor GetDefaultEvent()
{
return TypeDescriptor.GetDefaultEvent(this, true);
}
public PropertyDescriptor GetDefaultProperty()
{
return TypeDescriptor.GetDefaultProperty(this, true);
}
public object GetEditor(Type editorBaseType)
{
return TypeDescriptor.GetEditor(this, editorBaseType, true);
}
public EventDescriptorCollection GetEvents(Attribute[] attributes)
{
return TypeDescriptor.GetEvents(this, attributes, true);
}
public EventDescriptorCollection GetEvents()
{
return TypeDescriptor.GetEvents(this, true);
}
public PropertyDescriptorCollection GetProperties(Attribute[] attributes)
{
PropertyDescriptor[] newProps = new PropertyDescriptor[_listProperty.Count];
for (int i = 0; i < _listProperty.Count; i++)
{
Property prop = (Property)this[i];
newProps[i] = new CustomPropertyDescriptor(ref prop, attributes);
}
return new PropertyDescriptorCollection(newProps);
}
public PropertyDescriptorCollection GetProperties()
{
return TypeDescriptor.GetProperties(this, true);
}
public object GetPropertyOwner(PropertyDescriptor pd)
{
return this;
}
#endregion
}
/// <summary>
/// 属性类
/// </summary>
public class Property
{
public Property(string sCategory, string sDisplayName, string sName, string sDescription, object sValue, bool sReadonly, bool sVisible)
{
this.Category = sCategory;
this.DisplayName = sDisplayName;
this.Name = sName;
this.Description = sDescription;
this.Value = sValue;
this.ReadOnly = sReadonly;
this.Visible = sVisible;
}
/// <summary>
/// 属性所属类别
/// </summary>
public string Category { get; set; }
/// <summary>
/// 属性显示名称
/// </summary>
public string DisplayName { get; set; }
/// <summary>
/// 属性名
/// </summary>
public string Name { get; set; }
/// <summary>
/// 描述
/// </summary>
public string Description { get; set; }
/// <summary>
/// 属性值
/// </summary>
public object Value { get; set; }
/// <summary>
/// 是否为只读
/// </summary>
public bool ReadOnly { get; set; }
/// <summary>
/// 是否可见
/// </summary>
public bool Visible { get; set; }
/// <summary>
/// 类型转换器,在制作下拉列表时需要用到
/// </summary>
public TypeConverter Converter { get; set; }
/// <summary>
/// 属性编辑器
/// </summary>
public virtual object Editor { get; set; }
}
public class CustomPropertyDescriptor : PropertyDescriptor
{
Property _property;
public CustomPropertyDescriptor(ref Property myProperty, Attribute[] attrs)
: base(myProperty.Name, attrs)
{
_property = myProperty;
}
#region PropertyDescriptor 重写方法
public override bool CanResetValue(object component)
{
return false;
}
public override Type ComponentType
{
get { return null; }
}
public override object GetValue(object component)
{
return _property.Value;
}
public override string Description
{
get { return _property.Description; }
}
public override string Category
{
get { return _property.Category; }
}
public override string DisplayName
{
get { return !string.IsNullOrWhiteSpace(_property.DisplayName) ? _property.DisplayName : _property.Name; }
}
public override bool IsReadOnly
{
get { return _property.ReadOnly; }
}
public override void ResetValue(object component)
{
//Have to implement
}
public override bool ShouldSerializeValue(object component)
{
return false;
}
public override void SetValue(object component, object value)
{
_property.Value = value;
}
public override TypeConverter Converter
{
get { return _property.Converter; }
}
public override Type PropertyType
{
get { return _property.Value.GetType(); }
}
public override object GetEditor(Type editorBaseType)
{
return _property.Editor == null ? base.GetEditor(editorBaseType) : _property.Editor;
}
#endregion
}
/// <summary>
/// 下拉框类型转换器
/// </summary>
public class DropDownListConverter : StringConverter
{
object[] _objects;
public DropDownListConverter(params object[] objects)
{
_objects = objects;
}
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return true;//true下拉框不可编辑
}
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
return new StandardValuesCollection(_objects);
}
}
}