uitypeeditorのeditvalueで追加のコンテキストデータにアクセスします
-
23-09-2019 - |
質問
WinFormsアプリケーションを微調整しています。このアプリケーションには Form
それにはaが含まれます PropertyGrid
. 。オブジェクトはに割り当てられます SelectedObject
プロパティグリッドがオブジェクトのプロパティを表示するようにプロパティ。
割り当てられたオブジェクトのタイプには、 EditorAttribute
指定a UITypeEditor
.
のこの実装 UITypeEditor
戻り値 UITypeEditorEditStyle.Drop
そのオーバーライドで GetEditStyle
方法。これは EditValue
メソッドはaを表示します ListBox
インスタンスプロパティの値を割り当てることができます。
これまでのところすべて良いです。
これで、リスト内の利用可能なアイテムを、次の状態に基づいて変更する必要がある追加の要件があります。 Form
ホスティング PropertyGrid
. 。このコンテキスト情報を取得する方法はわかりません EditValue
方法。
何もないようです context
より具体的なタイプにキャストしてみてもパラメーター。他のサービスを追加してから取得する方法を解決することはできません provider
.
何か案は?
解決
あなたがしようとしていることは、 TypeConverter
経由 GetStandardValues
?しかし、どちらにしても、両方 context.Instance
と context.PropertyDescriptor
思われる クイックテストに存在する(両方のために GetEditStyle
と EditValue
):
using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;
class MyData
{
[Editor(typeof(MyEditor), typeof(UITypeEditor))]
public string Bar { get; set; }
public string[] Options { get; set; }
}
class MyEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
// break point here; inspect context
return UITypeEditorEditStyle.DropDown;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
// break point here; inspect context
return base.EditValue(context, provider, value);
}
}
class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form
{
Controls =
{
new PropertyGrid {
Dock = DockStyle.Fill,
SelectedObject = new MyData()
}
}
});
}
}
またはタイプコンバーターとして:
using System;
using System.ComponentModel;
using System.Windows.Forms;
class MyData
{
[TypeConverter(typeof(MyConverter))]
public string Bar { get; set; }
public string[] Options { get; set; }
}
class MyConverter : StringConverter
{
public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
{
return true;
}
public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
{
MyData data = (MyData)context.Instance;
if(data == null || data.Options == null) {
return new StandardValuesCollection(new string[0]);
}
return new StandardValuesCollection(data.Options);
}
}
class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.Run(new Form
{
Controls =
{
new PropertyGrid {
Dock = DockStyle.Fill,
SelectedObject = new MyData()
}
}
});
}
}
他のヒント
私は同様の状況にあり、カスタムUityPeeditorのコンストラクターにオブジェクトを注入したかったのです。
私はニコラス・キャディルハックのコメントに従いました ここ, 、彼にすべての信用を与えます。 typedescriptionProviderを使用します。
これが完全なコードセットです。
class Foo
{
public Foo() { Bar = new Bar(); }
public Bar Bar { get; set; }
}
class Bar
{
public string Value { get; set; }
}
class BarTypeDescriptionProvider : TypeDescriptionProvider
{
private TypeDescriptionProvider _baseProvider;
string _extraParam;
public BarTypeDescriptionProvider(Type t, string extraParam)
{
this._extraParam = extraParam;
_baseProvider = TypeDescriptor.GetProvider(t);
}
public string ExtraParam
{
get { return _extraParam; }
}
public override ICustomTypeDescriptor GetTypeDescriptor(Type objectType, object instance)
{
return new BarTypeDescriptor(this, _baseProvider.GetTypeDescriptor(objectType, instance), objectType);
}
}
class BarTypeDescriptor : CustomTypeDescriptor
{
private Type _objectType;
private BarTypeDescriptionProvider _provider;
public BarTypeDescriptor(BarTypeDescriptionProvider provider, ICustomTypeDescriptor descriptor, Type objectType): base(descriptor)
{
if (provider == null) throw new ArgumentNullException("provider");
if (descriptor == null)
throw new ArgumentNullException("descriptor");
if (objectType == null)
throw new ArgumentNullException("objectType");
_objectType = objectType;
_provider = provider;
}
public override object GetEditor(Type editorBaseType)
{
return new BarEditor(_provider.ExtraParam);
}
}
class BarEditor : UITypeEditor
{
private string _extraParam;
public BarEditor(string x)
: base()
{
_extraParam = x;
}
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
{
MessageBox.Show(_extraParam);
return base.EditValue(context, provider, value);
}
}
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
string extraParam = "Extra param from main form";
TypeDescriptor.AddProvider(new BarTypeDescriptionProvider(typeof(Bar), extraParam), typeof(Bar));
this.propertyGrid1.SelectedObject = new Foo();
}
}
マイケル
オーバーライドされたeditvalueメソッドでは、 context.Container
編集者が属するオブジェクトを提供します。 context.Container.Components
プロパティは、フォームとそのすべての子供を含むすべてのコントロールをリストします。