2008-11-24 29 views
22

如何在运行时以各种方式修改propertygrid?我希望能够添加和删除属性并添加“动态类型”,我的意思是使用TypeConverter在propertygrid中生成运行时生成的下拉列表。如何在运行时修改PropertyGrid(添加/删除属性和动态类型/枚举)

我实际上已经能够做到这两件事(添加/删除属性和添加动态类型),但只能分别不在同一时间。

为了实现在运行时添加和删除属性的支持,我使用this codeproject article并修改了一下代码以支持不同类型(不仅仅是字符串)。

private System.Windows.Forms.PropertyGrid propertyGrid1; 
private CustomClass myProperties = new CustomClass(); 

public Form1() 
{ 
    InitializeComponent(); 

    myProperties.Add(new CustomProperty("Name", "Sven", typeof(string), false, true)); 
    myProperties.Add(new CustomProperty("MyBool", "True", typeof(bool), false, true)); 
    myProperties.Add(new CustomProperty("CaptionPosition", "Top", typeof(CaptionPosition), false, true)); 
    myProperties.Add(new CustomProperty("Custom", "", typeof(StatesList), false, true)); //<-- doesn't work 
} 

/// <summary> 
/// CustomClass (Which is binding to property grid) 
/// </summary> 
public class CustomClass: CollectionBase,ICustomTypeDescriptor 
{ 
    /// <summary> 
    /// Add CustomProperty to Collectionbase List 
    /// </summary> 
    /// <param name="Value"></param> 
    public void Add(CustomProperty Value) 
    { 
     base.List.Add(Value); 
    } 

    /// <summary> 
    /// Remove item from List 
    /// </summary> 
    /// <param name="Name"></param> 
    public void Remove(string Name) 
    { 
     foreach(CustomProperty prop in base.List) 
     { 
      if(prop.Name == Name) 
      { 
       base.List.Remove(prop); 
       return; 
      } 
     } 
    } 

等等

public enum CaptionPosition 
{ 
    Top, 
    Left 
} 

我的完整的解决方案可以下载here

它工作正常,当我添加字符串,布尔或枚举,但当我尝试添加像动态类型StatesList它不起作用。有谁知道为什么,可以帮助我解决它?

public class StatesList : System.ComponentModel.StringConverter 
{ 
    private string[] _States = { "Alabama", "Alaska", "Arizona", "Arkansas" }; 

    public override System.ComponentModel.TypeConverter.StandardValuesCollection 
    GetStandardValues(ITypeDescriptorContext context) 
    { 
     return new StandardValuesCollection(_States); 
    } 

    public override bool GetStandardValuesSupported(ITypeDescriptorContext context) 
    { 
     return true; 
    } 

    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context) 
    { 
     return true; 
    } 
} 

利用类型转换器的方法,工作得很好,当你不尝试在运行时没有任何问题,以添加属性,例如this code的作品,但我希望能够做到这两点。请致电my project。 谢谢!

回答

7

你所做的是将StatesList(TypeConverter)作为属性添加。
你应该做的是添加一个属性StatesList作为它的TypeConverter。

5

啊,当然!

myProperties.Add(new CustomProperty("Custom", "", typeof(States), false, true)); 

[TypeConverter(typeof(StatesList))] 
public class States 
{ 
} 

工程就像一个魅力,谢谢!

我已经更新了我的项目,希望对别人有帮助,可以找到here

+0

不客气:) – 2008-11-24 12:55:36

+0

我知道后很老了,但我有一个简短的问题。我在我的应用程序中精确地使用您的代码,但自定义组合框不起作用。该物业的名称是灰色的,没有选项可用。任何想法,我能做些什么来解决这个问题? 由于提前, 马丁 – user653427 2011-03-10 13:51:34

3

这个问题和答案对我来说非常有用。但是,我需要通过允许运行时生成的下拉列表值来进一步扩展。我想我会发布一些示例代码来说明它需要什么,以防有人发现它有用。

首先,我添加了一个选项参数到CustomProperty的构造函数,并增加了选项属性:

private List<string> lOptions; 

    public CustomProperty(string sName, object value, Type tType, bool bReadOnly, bool bVisible, List<string> lOptions) 
    { 
     this.lOptions = lOptions; 
    } 

    public List<string> Options 
    { 
     get { return lOptions; } 
    } 

其次,我添加了一个选项属性设置CustomPropertyDescriptor类:

public List<string> Options 
    { 
     get 
     { 
      return m_Property.Options; 
     } 
    } 

第三,我必须修改我的动态类型类中的GetStandardValues方法(即StatesList),以利用新的选项属性对CustomPropertyDescriptor对象:

public override StandardValuesCollection 
       GetStandardValues(ITypeDescriptorContext context) 
    { 
     CustomPropertyDescriptor descriptor = (CustomPropertyDescriptor)context.PropertyDescriptor; 
     return new StandardValuesCollection(descriptor.Options); 
    } 

最后,我在我的选项列表通过创建一个新的CustomProperty的对象时:

List<string> optionsList = new List<string>(new string[] { "test1", "test2", "test3" });   
    CustomProperty myProperty = new CustomProperty(attr.Name, attr.Value, valueType, false, true, optionsList); 

在地方我为这个例子传入的静态列表,你可以用你喜欢的任何方式为你的下拉列表生成选项列表,让你完全控制可用的选项。

0
在我的情况

类型转换器并不适用于美国一流

[TypeConverter(typeof(StatesList))] // not work 
public class States 
{ 
} 

所以我说倍率,CustomPropertyDescriptor

public override TypeConverter Converter 
{ 
    get { 
     if (this.PropertyType.Equals(typeof(States))) { 
      return new StatesList(); ; 
     } 
     return base.Converter; 
    } 
}