実行時にPropertyGridを変更する方法(プロパティと動的な型/列挙を追加/削除)
-
10-07-2019 - |
質問
どのようにして実行時にプロパティグリッドを変更しますか?プロパティを追加および削除し、「動的な型」を追加できるようにしたい、つまり、TypeConverterを使用してpropertygridで実行時に生成されるドロップダウンを生成する型です。
実際には、これらの両方(プロパティの追加/削除と動的タイプの追加)を行うことができましたが、同時にはできません。
実行時にプロパティを追加および削除するサポートを実装するには、 thisを使用しました。 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;
}
}
}
etc ...
public enum CaptionPosition
{
Top,
Left
}
私の完全なソリューションは、こちらからダウンロードできます。
文字列、ブール、または列挙型を追加すると正常に機能しますが、「動的タイプ」を追加しようとすると、 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;
}
}
このコードは問題なく動作しますが、両方を実行できるようにしたいです。
私のプロジェクトをご覧ください。 ありがとう!
解決
行うことは、StatesList(TypeConverter)をプロパティとして追加することです。
行うべきことは、StatesListをTypeConverterとしてプロパティを追加することです。
他のヒント
ああ、もちろん!
myProperties.Add(new CustomProperty("Custom", "", typeof(States), false, true));
[TypeConverter(typeof(StatesList))]
public class States
{
}
魅力のように動作します、ありがとう!
プロジェクトを更新しました。他の人に役立つことを願っています。こちら。
この質問と回答は私にとって非常に有用でした。ただし、実行時に生成されるドロップダウンリストの値を許可することで、さらに拡張する必要がありました。誰かが役に立つと思ったら、必要なものに関していくつかのサンプルコードを投稿すると思いました。
まず、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; }
}
次に、CustomPropertyDescriptorクラスにOptionsプロパティを追加しました:
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);
この例で渡した静的リストの代わりに、ドロップダウンのオプションのリストを任意の方法で生成し、使用可能なオプションを完全に制御できます。
私の場合、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;
}
}