2010-03-29 28 views
4

我在調整WinForms應用程序。此應用程序有一個Form,其中包含一個PropertyGrid。將對象分配給SelectedObject屬性,以便屬性網格顯示對象的屬性。在UITypeEditor的EditValue中訪問其他上下文數據

分配的對象的類型具有一個屬性,該屬性包含指定UITypeEditorEditorAttribute

UITypeEditor的此實施方式在其覆蓋GetEditStyle方法中返回UITypeEditorEditStyle.Drop。它的EditValue方法顯示一個ListBox,可以從中分配實例屬性的值。

所有這一切都很好。

現在我有一個額外的要求,要求根據主辦PropertyGridForm所持有的其他狀態修改列表中的可用項目。我無法弄清楚如何將這個上下文信息傳遞給EditValue方法。

即使我嘗試將其轉換爲更具體的類型,但參數context上似乎沒有任何內容。我也無法解決如何添加其他服務以從provider中檢索。

任何想法?

回答

2

我不知道你想要做什麼會更好通過GetStandardValuesTypeConverter?但無論哪種方式,都context.Instancecontext.PropertyDescriptor似乎在快速測試(用於GetEditStyleEditValue)來填充:

或者作爲一種轉換器:

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() 
       } 
      } 
     }); 
    } 
} 
+0

感謝馬克,或許是我的問題需要調整,我需要訪問由__isn't__分配給電網的'SelectedObject'屬性由對象保存的值_form_保持的值。 – AnthonyWJones 2010-03-29 16:36:13

+0

@Anthony - 獲取表單會很棘手 - 有什麼方法可以將它抽象到實例中嗎? – 2010-03-29 18:27:14

+1

我想我可以但我希望有另一種方式。我並不想污染攜帶數據的對象來滿足應用程序架構的興趣。它不一定是形式本身,而是其他訪問額外數據的方式,這實際上是「IServiceProvider」的角色,但我無法在此上下文中找到添加自己的服務的方法。 – AnthonyWJones 2010-03-30 07:11:32

1

在覆蓋EditValue方法,context.Container將提供編輯器所屬的對象。 context.Container.Components屬性將列出包含表單及其所有子項的所有控件。

4

我是在類似的情況下,我想注入一個對象到我的自定義UITypeEditor的構造函數。

我跟着Nicolas Cadilhac在Here的評論,給他所有的信用。它使用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(); 
    } 
} 

邁克爾

相關問題