web-dev-qa-db-ja.com

実行時にPropertyGridを変更する方法(プロパティと動的タイプ/列挙型を追加/削除)

実行時にあらゆる方法でpropertygridをどのように変更しますか?プロパティを追加および削除し、「動的タイプ」を追加できるようにしたいのですが、これは、TypeConverterを使用してプロパティグリッドに実行時に生成されるドロップダウンをもたらすタイプを意味します。

私は実際にそれらの両方(プロパティの追加/削除と動的型の追加)を行うことができましたが、同時にではなく別々にしかできませんでした。

実行時にプロパティを追加および削除するサポートを実装するために、 このcodeprojectの記事 を使用し、さまざまなタイプ(文字列だけでなく)をサポートするようにコードを少し変更しました。

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
}

私の完全なソリューションはダウンロードできます ここ

文字列、bool、または列挙型を追加すると正常に機能しますが、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;
    }
}

TypeConverterを使用する方法は、実行時にプロパティを追加しようとしない場合は正常に機能します。たとえば、 このコード は問題なく機能しますが、両方を実行できるようにしたいです。

私のプロジェクト をご覧ください。ありがとう!

24
salle55

あなたがしていることは、StatesList(TypeConverter)をプロパティとして追加することです。
あなたがすべきことは、TypeConverterとしてStatesListを持つプロパティを追加することです。

もちろん!

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

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

チャームのように機能します、ありがとう!

私は自分のプロジェクトを更新しました、それが他の人に役立つことを願っています、それは見つけることができます ここ

5
salle55

この質問と回答は私にとって非常に役に立ちました。ただし、実行時に生成されるドロップダウンリスト値を許可することで、さらに拡張する必要がありました。誰かがそれが役に立つと思う場合に備えて、私はそれが必要とするものに関していくつかのサンプルコードを投稿すると思いました。

まず、CustomPropertyコンストラクターにoptionsパラメーターを追加し、Optionsプロパティを追加しました。

    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; }
    }

次に、OptionsプロパティをCustomPropertyDescriptorクラスに追加しました。

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

3番目に、CustomPropertyDescriptorオブジェクトの新しいOptionsプロパティを利用するために、動的型クラス(つまり、StatesList)のGetStandardValuesメソッドを変更する必要がありました。

    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);

この例で渡した静的リストの代わりに、ドロップダウンのオプションのリストを任意の方法で生成して、使用可能なオプションを完全に制御できます。

4
Scott

私の場合、TypeConverterはStatesクラスに適用されませんでした

[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;
    }
}
0
Dizz Y