Предположим, у меня есть следующий пользовательский атрибут оформленный класс, который реализует TypeConverter. Я хотел бы создать поле со списком в Wpf.PropertyGrid так, чтобы значения в поле со списком были взяты из массива строк, указанного в пользовательском атрибуте. Проблема, с которой я сталкиваюсь, заключается в том, что, хотя я могу перебирать все свойства с помощью пользовательского атрибута, я не могу определить фактическое свойство, которое вызвало 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);
}
}