Wpf.PropertyGrid ComboBox来自自定义属性中的字符串数组

时间:2019-04-02 21:55:05

标签: c# wpf data-binding wpf-controls propertygrid

假设我具有以下实现TypeConverter的自定义属性修饰类。我想在Wpf.PropertyGrid中创建一个组合框,以便组合框中的值取自custom属性中指定的字符串数组。我遇到的问题是,尽管我可以使用custom属性遍历所有属性,但是我无法弄清楚将TypeConverter作为context调用的实际属性。PropertyGrid为null。可以创建这样的组合框吗?如果是,怎么办?

课程:

[TypeConverter(typeof(ExpandableObjectConverter))]
public class Animals : INotifyPropertyChanged
{
    // Constructor
    public Animals()
    {
        foreach (PropertyDescriptor prop in TypeDescriptor.GetProperties(this))
        {
            DefaultValueAttribute attr = (DefaultValueAttribute)prop.Attributes[typeof(DefaultValueAttribute)];
            if (attr != null)
                prop.SetValue(this, attr.Value);
        }
    }

    // Properties
    private string _pets, _others;

    // both properties have the same TypeConverter, but they use different custom attributes
    [RefreshProperties(RefreshProperties.All)]
    [TypeConverter(typeof(ListTypeConverter))]
    [ListTypeConverterAttribute(new [] { "cat", "dog" })]
    [ListTypeConverterAttribute(new [] { "cat1", "dog1" })]
    [DefaultValue("cat")]
    public string Pets
    {
        get { return _pets; }
        set { SetField(ref _pets, value); }
    }

    [RefreshProperties(RefreshProperties.All)]
    [ListTypeConverterAttribute(typeof(ListTypeConverter))]
    [ListTypeConverterAttribute(new [] { "cow", "sheep" })]
    [DefaultValue("sheep")]
    public string Others
    {
        get { return _others; }
        set { SetField(ref _others, value); }
    }

    // Methods
    public override string ToString()
    {
        return string.Empty;
    }

    // ----- Implement INotifyPropertyChanged -----
    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged(string propertyName)
    {
        PropertyChangedEventHandler handler = this.PropertyChanged;
        if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
    }

    protected bool SetField<T>(ref T field, T value, [CallerMemberName] string propertyName = null)
    {
        if (EqualityComparer<T>.Default.Equals(field, value))
            return false;
        field = value;
        OnPropertyChanged(propertyName);
        return true;
    }
}

自定义属性:

public sealed class ListTypeConverterAttribute : Attribute
{
    public ListTypeConverterAttribute(params string[] list)
    {
        this.List = list;
    }

    public string[] List { get; set; }

    public override object TypeId
    {
        get { return this; }
    }
}

TypeConverter:

public class ListTypeConverter : TypeConverter
{
    public override bool GetStandardValuesSupported(ITypeDescriptorContext context)
    {
        return true;
    }

    public override bool GetStandardValuesExclusive(ITypeDescriptorContext context)
    {
        return true;
    }

    public override StandardValuesCollection GetStandardValues(ITypeDescriptorContext context)
    {
        base.GetStandardValues(context);

        List<string> list = new List<string>();

        // HERE IS MY ISSUE ...
        // How do I get the property invoking the TypeConverter so I can get its list?
        // context.PropertyGrid == null

        return new StandardValuesCollection(list);
    }
}

0 个答案:

没有答案