У меня есть набор классов с таким набором свойств: Каждый из них имеет собственный атрибут, указывающий возможные значения, которые он может принять. В любом случае, чтобы привязать эти значения к combobox вместо hardcoding с помощью <ComboBoxItem/>
?
[Values("Cash","Bank","Not Applicable")]
public Nullable<int> PaymentMethod{ get; set; }
Изменение: мой атрибут выглядит так:
class ValuesAttribute:Attribute
{
public List<string> values { get; set; }
public ValuesAttribute(params String[] values)
{
this.values= new List<string>();
foreach (var v in values)
{
this.values.Add(v);
}
}
}
Для этого я бы использовал конвертер. Отправьте ему базовый объект и имя свойства в качестве параметра. Верните массив key/value, чтобы вы могли привязать как значение (значение index/enum), так и отображаемый текст:
<ComboBox ItemsSource="{Binding ConverterParameter='PaymentMethod',Converter={StaticResource AttributeConverter}}"
DisplayMemberPath="Value" SelectedValuePath="Key"
/>
Затем преобразователь может получить значения с помощью отражения:
public class AttributeConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value != null && parameter as string != null)
{
var property = value.GetType().GetProperty((string)parameter);
if (property != null)
{
var attribute = property.GetCustomAttributes(typeof(ValuesAttribute), false).OfType<ValuesAttribute>().FirstOrDefault();
if (attribute != null)
return attribute.values.Select((display, index) =>
new KeyValuePair<int, string>(index, display)
).ToArray();
}
}
return DependencyProperty.UnsetValue;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Примечание. Если вам нужно сделать это много в своем приложении, возможно, стоит подклассифицировать ComboBox или создать поведение, которое применяет соответствующие свойства.