どのように私は、クローズドソースのタイプのすべてのプロパティに対してカスタムのUITypeEditorを注入していますか?
-
21-08-2019 - |
質問
私は、私は、カスタムのUITypeEditorを書いた特定のタイプのすべてのインスタンスにEditorAttributeを置かないようにしたいです。
私は、ソースを変更することはできませんので、私はタイプにEditorAttributeを配置することはできません。
私が使用されるのみPropertyGridのインスタンスへの参照を持っています。
私はそれが特定のタイプに遭遇するたびにカスタムのUITypeEditorを使用するようにPropertyGridのインスタンス(またはすべてのインスタンスを)伝えることはできますか?
ここの提供は上の点を開始しているMSDNの記事であります.NET 2.0以上でこれを行う方法について説明します。
解決
あなたは通常TypeDescriptor.AddAttributes
を経由して、実行時に編集者などを関連付けることができます。
Bar
プロパティは、「...」それは 『!の編集』を表示すると表示されるはずです)
using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;
class Foo
{
public Foo() { Bar = new Bar(); }
public Bar Bar { get; set; }
}
class Bar
{
public string Value { get; set; }
}
class BarEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
MessageBox.Show("Editing!");
return base.EditValue(context, provider, value);
}
}
static class Program
{
[STAThread]
static void Main()
{
TypeDescriptor.AddAttributes(typeof(Bar),
new EditorAttribute(typeof(BarEditor), typeof(UITypeEditor)));
Application.EnableVisualStyles();
Application.Run(new Form { Controls = { new PropertyGrid { SelectedObject = new Foo() } } });
}
}
他のヒント
マルクのソリューションは、ぶっきらぼうに、グローバルバータイプにEditorAttributeを適用します。あなたは繊細な気質を持っている場合は、あなたではなく、特定のインスタンスのプロパティに注釈を付けることがあります。残念ながら、それはTypeDescriptor.AddAttributes
では不可能である。
私のソリューションは、余分な属性を持ついくつかの注釈付け、TからラッパーViewModel<T>
、コピーのプロパティを記述することでした。私たちは型レポートの変数datum
があると、私たちはこのようにそれを使うだろう。
var pretty = ViewModel<Report>.DressUp(datum);
pretty.PropertyAttributeReplacements[typeof(Smiley)] = new List<Attribute>() { new EditorAttribute(typeof(SmileyEditor),typeof(UITypeEditor))};
propertyGrid1.SelectedObject = pretty;
どこViewModel<T>
が定義されます:
public class ViewModel<T> : CustomTypeDescriptor
{
private T _instance;
private ICustomTypeDescriptor _originalDescriptor;
public ViewModel(T instance, ICustomTypeDescriptor originalDescriptor) : base(originalDescriptor)
{
_instance = instance;
_originalDescriptor = originalDescriptor;
PropertyAttributeReplacements = new Dictionary<Type,IList<Attribute>>();
}
public static ViewModel<T> DressUp(T instance)
{
return new ViewModel<T>(instance, TypeDescriptor.GetProvider(instance).GetTypeDescriptor(instance));
}
/// <summary>
/// Most useful for changing EditorAttribute and TypeConvertorAttribute
/// </summary>
public IDictionary<Type,IList<Attribute>> PropertyAttributeReplacements {get; set; }
public override PropertyDescriptorCollection GetProperties (Attribute[] attributes)
{
var properties = base.GetProperties(attributes).Cast<PropertyDescriptor>();
var bettered = properties.Select(pd =>
{
if (PropertyAttributeReplacements.ContainsKey(pd.PropertyType))
{
return TypeDescriptor.CreateProperty(typeof(T), pd, PropertyAttributeReplacements[pd.PropertyType].ToArray());
}
else
{
return pd;
}
});
return new PropertyDescriptorCollection(bettered.ToArray());
}
public override PropertyDescriptorCollection GetProperties()
{
return GetProperties(null);
}
}
上記で定義したように、これは特定の種類のプロパティを代入していますが、より高い解像度が必要な場合は、名前でプロパティを置き換えることができます。
ちょうどあなたにをエディタの属性を追加クラスます。