바인딩하는 모든 객체가 my에 정의되기를 원 ViewModel
하므로 <ObjectDataProvider>
가능한 경우 xaml에서 사용하지 않으려 고 합니다.
내 솔루션은 View에 정의 된 데이터와 코드 숨김을 사용하지 않습니다. DataType, 재사용 가능한 ValueConverter, Enum 유형에 대한 설명 모음을 가져 오는 메소드 및 바인딩 할 ViewModel의 단일 특성 만 있습니다.
내가 바인딩 할 때 Enum
A와 ComboBox
내가 표시 할 텍스트 결코의 값과 일치하지 Enum
내가 사용하므로, [Description()]
그것을 내가 실제로에 표시하려는 텍스트를 제공하는 속성을 ComboBox
. 내가 요일을 열거하면 다음과 같이 보일 것입니다.
public enum DayOfWeek
{
// add an optional blank value for default/no selection
[Description("")]
NOT_SET = 0,
[Description("Sunday")]
SUNDAY,
[Description("Monday")]
MONDAY,
...
}
먼저 열거 형을 처리하는 몇 가지 방법으로 도우미 클래스를 만들었습니다. 한 방법은 특정 값에 대한 설명을 가져오고 다른 방법은 유형에 대한 모든 값과 설명을 가져옵니다.
public static class EnumHelper
{
public static string Description(this Enum value)
{
var attributes = value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
if (attributes.Any())
return (attributes.First() as DescriptionAttribute).Description;
// If no description is found, the least we can do is replace underscores with spaces
// You can add your own custom default formatting logic here
TextInfo ti = CultureInfo.CurrentCulture.TextInfo;
return ti.ToTitleCase(ti.ToLower(value.ToString().Replace("_", " ")));
}
public static IEnumerable<ValueDescription> GetAllValuesAndDescriptions(Type t)
{
if (!t.IsEnum)
throw new ArgumentException($"{nameof(t)} must be an enum type");
return Enum.GetValues(t).Cast<Enum>().Select((e) => new ValueDescription() { Value = e, Description = e.Description() }).ToList();
}
}
다음으로을 만듭니다 ValueConverter
. 에서 상속 MarkupExtension
하면 XAML 에서 사용하기가 더 쉬워 지므로 리소스로 선언 할 필요가 없습니다.
[ValueConversion(typeof(Enum), typeof(IEnumerable<ValueDescription>))]
public class EnumToCollectionConverter : MarkupExtension, IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return EnumHelper.GetAllValuesAndDescriptions(value.GetType());
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return null;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
내 ViewModel
하나 와 콤보 상자 View
모두에 바인딩 할 수있는 속성이 하나만 필요합니다 .SelectedValue
ItemsSource
private DayOfWeek dayOfWeek;
public DayOfWeek SelectedDay
{
get { return dayOfWeek; }
set
{
if (dayOfWeek != value)
{
dayOfWeek = value;
OnPropertyChanged(nameof(SelectedDay));
}
}
}
그리고 마지막으로 바인딩 ComboBox
합니다 (을 사용하여보기 ValueConverter
에 ItemsSource
바인딩) ...
<ComboBox ItemsSource="{Binding Path=SelectedDay, Converter={x:EnumToCollectionConverter}, Mode=OneTime}"
SelectedValuePath="Value"
DisplayMemberPath="Description"
SelectedValue="{Binding Path=SelectedDay}" />
이 솔루션을 구현하려면 EnumHelper
클래스와 EnumToCollectionConverter
클래스 만 복사하면됩니다 . 그들은 열거 형 과 함께 작동 합니다 . 또한, 나는 여기에 포함되지 않았지만, ValueDescription
클래스는 2 개 공공 개체 속성이라는 하나 단순한 클래스 Value
라는 하나 Description
. 당신은 그 자신을 만들 수 있습니다 또는 당신이를 사용하도록 코드를 변경할 수 Tuple<object, object>
또는KeyValuePair<object, object>