【发布时间】:2017-09-08 00:08:55
【问题描述】:
我正在使用属性网格来显示对象属性。必须根据条件显示动态属性。我需要将列表项显示为下拉列表。 所以我写了一些必要的类。 (请考虑这个列表也是动态的)。
如您所见,我有一个自定义属性网格:
public class myPropertyGrid : PropertyGrid
{
private System.ComponentModel.Container components = null;
public myPropertyGrid()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if(components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
#region Codice generato da Progettazione componenti
/// <summary>
/// Metodo necessario per il supporto della finestra di progettazione. Non modificare
/// il contenuto del metodo con l'editor di codice.
/// </summary>
private void InitializeComponent()
{
//
// UserControl1
//
this.Name = "myPropertyGrid";
}
#endregion
protected override PropertyTab CreatePropertyTab(Type tabType)
{
myTab t = new myTab();
return t;
}
}
public class myTab : PropertyTab
{
public myTab()
{
}
// get the properties of the selected component
public override System.ComponentModel.PropertyDescriptorCollection GetProperties(object component, System.Attribute[] attributes)
{
PropertyDescriptorCollection properties;
if(attributes!=null)
properties=TypeDescriptor.GetProperties(component,attributes);
else
properties=TypeDescriptor.GetProperties(component);
//Componet must implement the ICUSTOMCLASS interface.
ICustomClass bclass=(ICustomClass)component;
//The new array of properties, based on the PublicProperties properties of "model"
PropertyDescriptor[] arrProp = new PropertyDescriptor[bclass.PublicProperties.Count];
for (int i=0;i<bclass.PublicProperties.Count;i++)
{
//Find the properties in the array of the propertis which neme is in the PubliCProperties
PropertyDescriptor prop=properties.Find(bclass.PublicProperties[i].Name,true);
//Build a new properties
arrProp[i] = TypeDescriptor.CreateProperty(prop.ComponentType, prop, new CategoryAttribute("جزئیات"));
}
return new PropertyDescriptorCollection(arrProp);
}
public override System.ComponentModel.PropertyDescriptorCollection GetProperties(object component)
{
return this.GetProperties(component,null);
}
// PropertyTab Name
public override string TabName
{
get
{
return "Properties";
}
}
//Image of the property tab (return a blank 16x16 Bitmap)
public override System.Drawing.Bitmap Bitmap
{
get
{
return new Bitmap(16,16);;
}
}
}
我有一个名为 PropertyList 的类,该类用于将属性添加到属性网格并从属性网格中删除属性。
public class PropertyList : NameObjectCollectionBase
{
public void Add(Object value)
{
//The key for the object is taken from the object to insert
this.BaseAdd(((CustomProperty)value).Name, value);
}
public void Remove(String key)
{
this.BaseRemove(key);
}
public void Remove(int index)
{
this.BaseRemoveAt(index);
}
public void Clear()
{
this.BaseClear();
}
public CustomProperty this[String key]
{
get
{
return (CustomProperty)(this.BaseGet(key));
}
set
{
this.BaseSet(key, value);
}
}
public CustomProperty this[int indice]
{
get
{
return (CustomProperty)(this.BaseGet(indice));
}
set
{
this.BaseSet(indice, value);
}
}
}
还有一个自定义属性的类
public class CustomProperty
{
private string sName = string.Empty;
private bool bReadOnly = false;
private bool bVisible = true;
private object objValue = null;
private object tag = null;
private string displayName = string.Empty;
public CustomProperty(object tag, string sName, object value, Type type, bool bReadOnly, bool bVisible)
{
this.tag = tag;
this.sName = sName;
this.objValue = value;
this.type = type;
this.bReadOnly = bReadOnly;
this.bVisible = bVisible;
}
public CustomProperty(object tag, string displayName, string sName, object value, Type type, bool bReadOnly, bool bVisible)
:this(tag,sName,value,type,bReadOnly,bVisible)
{
this.displayName = displayName;
}
private Type type;
public Type Type
{
get { return type; }
}
public bool ReadOnly
{
get
{
return bReadOnly;
}
}
public string Name
{
get
{
return sName;
}
set
{
sName = value;
}
}
public bool Visible
{
get
{
return bVisible;
}
}
public object Value
{
get
{
return objValue;
}
set
{
objValue = value;
}
}
public object Tag
{
get
{
return tag;
}
set
{
tag = value;
}
}
public string DisplayName
{
get
{
return displayName;
}
set
{
displayName = value;
}
}
}
我想添加从动态列表创建的组合框,为此我编写了以下代码:
[TypeConverter(typeof(VersionConvertor))]
[Editor(typeof(VersionTypeEditor), typeof(UITypeEditor))]
public class VersionClass
{
public VersionClass()
{
}
}
public class VersionConvertor : TypeConverter
{
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
{
return true;
}
}
public class VersionTypeEditor : UITypeEditor
{
private IWindowsFormsEditorService _editorService;
private ListBox lb;
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
// drop down mode (we'll host a listbox in the drop down)
return UITypeEditorEditStyle.DropDown;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
_editorService = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
// use a list box
lb = new ListBox();
lb.SelectionMode = SelectionMode.One;
lb.SelectedValueChanged += OnListBoxSelectedValueChanged;
lb.DisplayMember = "Name";
List<string> listItem = new List<string>();
listItem.Add("a"); // assume that these items are added dynamically
listItem.Add("b");
foreach (string item in listItem)
{
lb.Items.Add(item);
}
lb.SelectedItem = listItem[0];
lb.ValueMember = listItem[0];
_editorService.DropDownControl(lb);
if (lb.SelectedItem == null) // no selection, return the passed-in value as is
return value;
return lb.SelectedItem;
}
private void OnListBoxSelectedValueChanged(object sender, EventArgs e)
{
lb.SelectedItem = ((ListBox)(sender)).SelectedItem;
_editorService.CloseDropDown();
}
}
我该如何解决这个错误?
【问题讨论】:
标签: .net properties propertygrid