2012-02-24 5 views
1

私はICustomTypeDescriptorを実装するモデルを持っています。これは、オブジェクトにないカスタムプロパティを追加してテキストボックスにバインドできるようにするためです。奇妙な部分は、バインディングがPropertyGridには効果がありますが、テキストボックスには効果がないことです。ICustomTypeDescriptorテキストボックスへのデータバインド

このコードは動作します:

DynamicClass<ExtensionModel> binder = new DynamicClass<ExtensionModel>(ext); 
propertyGrid1.SelectedObject = binder; 

ではなく、彼の1:

この場合
var binder = new DynamicClass<ExtensionModel>(ext); 
_versionLabel.DataBindings.Add("Text", binder, "SelectedVersion", false, DataSourceUpdateMode.OnPropertyChanged); 

私は、オブジェクトがターゲットの型と一致していません取得します。例外。私はバインドの代わりにextを置く場合、それはうまく動作します。

テキストボックスのバインディング機能に問題はありますか?

DynamicClassのための私のコードは次のとおりです。

public class DynamicClass<T> : ICustomTypeDescriptor 
{ 
    private readonly T _object; 

    public DynamicClass(T trackedObject) 
    { 
     _object = trackedObject; 
    } 

    // Collection to code add dynamic properties 
    public KeyedCollection<string, DynamicProperty> Properties { get; private set; } 

    // ICustomTypeDescriptor implementation 
    AttributeCollection ICustomTypeDescriptor.GetAttributes() 
    { 
     return TypeDescriptor.GetAttributes(_object, true); 
    } 

    string ICustomTypeDescriptor.GetClassName() 
    { 
     return TypeDescriptor.GetClassName(_object, true); 
    } 

    string ICustomTypeDescriptor.GetComponentName() 
    { 
     return TypeDescriptor.GetComponentName(_object, true); 
    } 

    TypeConverter ICustomTypeDescriptor.GetConverter() 
    { 
     return TypeDescriptor.GetConverter(_object, true); 
    } 

    EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() 
    { 
     return TypeDescriptor.GetDefaultEvent(_object, true); 
    } 

    PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() 
    { 
     return TypeDescriptor.GetDefaultProperty(_object, true); 
    } 

    object ICustomTypeDescriptor.GetEditor(Type editorBaseType) 
    { 
     return TypeDescriptor.GetEditor(_object, editorBaseType, true); 
    } 

    EventDescriptorCollection ICustomTypeDescriptor.GetEvents() 
    { 
     return TypeDescriptor.GetEvents(_object, true); 
    } 

    EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) 
    { 
     return TypeDescriptor.GetEvents(_object, attributes, true); 
    } 

    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() 
    { 
     return TypeDescriptor.GetProperties(_object, true); 
    } 

    PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes) 
    { 
     return TypeDescriptor.GetProperties(_object, attributes, true); 
    } 

    object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd) 
    { 
     return _object; 
    } 
} 
+0

カスタム記述子は表示できますか? (特にSelectedVersionの場合)一般的にこれはうまくいくはずです(私はたくさんの狂ったカスタム記述子の処理をしました)ので、私の勇気は言っています: –

+0

も表示されていないコードのバグ、 "textbox" ComboBoxに拘束力があるようです...? –

+0

ここでコードを追加します。申し訳ありませんが、間違ったコピー/貼り付けでバインド:( –

答えて

1

根本的な問題は、あなたが実際オブジェクト(ExtensionModel)の記述子を配っているが、コンボボックスにのみ知っているという点で、ここにありますラッパー(DynamicClass<T>)、間違ったオブジェクトのメソッドを呼び出そうとします。これを避けるには、オブジェクトをスワップするものに記述子をラップします。

class IndirectDescriptor : PropertyDescriptorDecorator 
{ 
    private readonly object instance; 
    public IndirectDescriptor(PropertyDescriptor tail, object instance) : base(tail) 
    { 
     this.instance = instance; 
    } 
    protected override object GetComponent(object component) 
    { 
     return instance; 
    } 
} 

abstract class PropertyDescriptorDecorator : PropertyDescriptor 
{ 
    private readonly PropertyDescriptor tail; 
    static Attribute[] GetAttributes(AttributeCollection attribs) 
    { 
     var arr = new Attribute[attribs.Count]; 
     attribs.CopyTo(arr, 0); 
     return arr; 
    } 
    public PropertyDescriptorDecorator(PropertyDescriptor tail) : base(tail.Name, GetAttributes(tail.Attributes)) 
    { 
     this.tail = tail; 
    } 
    protected virtual object GetComponent(object component) 
    { 
     return component; 
    } 
    public override void AddValueChanged(object component, EventHandler handler) 
    { 
     tail.AddValueChanged(GetComponent(component), handler); 
    } 
    public override void RemoveValueChanged(object component, EventHandler handler) 
    { 
     tail.RemoveValueChanged(GetComponent(component), handler); 
    } 
    public override bool CanResetValue(object component) 
    { 
     return tail.CanResetValue(GetComponent(component)); 
    } 
    public override TypeConverter Converter 
    { 
     get { return tail.Converter; } 
    } 
    public override string Category 
    { 
     get { return tail.Category; } 
    } 
    public override Type ComponentType 
    { 
     get { return tail.ComponentType; } 
    } 
    public override string Description 
    { 
     get { return tail.Description; } 
    } 
    public override bool DesignTimeOnly 
    { 
     get { return tail.DesignTimeOnly; } 
    } 
    public override AttributeCollection Attributes 
    { 
     get { return tail.Attributes; } 
    } 
    public override string DisplayName 
    { 
     get { return tail.DisplayName; } 
    } 
    public override PropertyDescriptorCollection GetChildProperties(object instance, Attribute[] filter) 
    { 
     return tail.GetChildProperties(GetComponent(instance), filter); 
    } 
    public override object GetEditor(Type editorBaseType) 
    { 
     return tail.GetEditor(editorBaseType); 
    } 
    public override object GetValue(object component) 
    { 
     return tail.GetValue(GetComponent(component)); 
    } 
    public override void SetValue(object component, object value) 
    { 
     tail.SetValue(GetComponent(component), value); 
    } 
    public override bool IsBrowsable 
    { 
     get { return tail.IsBrowsable; } 
    } 
    public override bool IsLocalizable 
    { 
     get { return tail.IsLocalizable; } 
    } 
    public override bool IsReadOnly 
    { 
     get { return tail.IsReadOnly; } 
    } 
    public override string Name 
    { 
     get { return tail.Name; } 
    } 
    public override Type PropertyType 
    { 
     get { return tail.PropertyType; } 
    } 
    public override void ResetValue(object component) 
    { 
     tail.ResetValue(GetComponent(component)); 
    } 
    public override bool SupportsChangeEvents 
    { 
     get { return tail.SupportsChangeEvents; } 
    } 
    public override bool ShouldSerializeValue(object component) 
    { 
     return tail.ShouldSerializeValue(GetComponent(component)); 
    } 
} 
関連する問題