Enum 상수 값 들을 콤보박스나 라디오 버튼 리스트의 아이템으로 바인딩 해야 하는 경우 System.Windows.Markup.MarkupExtension 를 활용해서 바인딩 처리 할 수 있습니다. 그리고 Enum 상수 값을 필터 처리 해서 원하는 요소만 보이게 처리하는 방법에 대해 알아보겠습니다. Enum 상수 바인딩다음과 같은 Enum이 있습니다. public enum ETest
{
A,
B,
C,
D,
E
}
위 ETest 상수들을 콤보박스 아이템으로 바인딩 하면서 원하는 값 만 표시되도록 처리 하고자 합니다. 각 뷰 모델에서 ETest의 값 열거 타입 속성을 만들어서 컨버터를 사용해서 처리 해도 좋지만, 특정 Enum타입이 아닌 모든 Enum에서 사용 가능하도록 처리 하는 것이 더 좋을 것 같습니다.
이를 위해서 공통으로 사용할 수 있는 System.Windows.Markup.MarkupExtension 을 다음과 같이 만들어 사용할 수 있습니다. public class EnumBindingSourceExtension : MarkupExtension
{
private Type _enumType;
/// <summary>
/// 기본 생성자
/// </summary>
public EnumBindingSourceExtension() { }
/// <summary>
/// enum 타입 파라메터 생성자
/// </summary>
/// <param name="enumType"></param>
public EnumBindingSourceExtension(Type enumType)
{
this.EnumType = enumType;
}
public Type EnumType
{
get { return this._enumType; }
private set
{
if (value != this._enumType)
{
if (null != value)
{
// null 타입 체크
Type enumType = Nullable.GetUnderlyingType(value) ?? value;
if (!enumType.IsEnum)
throw new ArgumentException("Enum 타입이 아닙니다!");
}
this._enumType = value;
}
}
}
public string Fillter
{
get; set;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (null == this._enumType)
throw new InvalidOperationException("Enum 타입이 아닙니다!");
Type enumType = Nullable.GetUnderlyingType(this._enumType) ?? this._enumType;
Array enumValues = Enum.GetValues(enumType);
if (enumType == this._enumType)
{
if (string.IsNullOrWhiteSpace(Fillter))
{
return enumValues;
}
else
{
var fillterArr = Fillter.ToString().Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
return enumValues.Cast<Enum>().Where(p => fillterArr.Contains(p.ToString()));
}
}
{
Array enumValArr = Array.CreateInstance(enumType, enumValues.Length + 1);
enumValues.CopyTo(enumValArr, 1);
if (string.IsNullOrWhiteSpace(Fillter))
{
return enumValues;
}
else
{
var fillterArr = Fillter.ToString().Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries);
return enumValues.Cast<Enum>().Where(p => fillterArr.Contains(p.ToString()));
}
}
}
}
간단히 코드를 보면 생성자를 통해 EnumType 속성에 바인딩 대상의 Enum 타입을 설정하고, 표시 할 상수 값을 지정할 수 있도록 Fillter 속성이 있습니다. Fillter 속성은 콤마(,)로 구분 짓고 있으며 ProvideValue() 메서드의 코드를 간단히 살펴보면 System.Enum 의 GetValues() 메서드를 통해 Enum 상수 배열을 뽑아 냅니다. 그리고 Fillter 속성을 체크해서 원하는 상수 값만 다시 한번 뽑아 반환 시켜 줍니다. EnumBindingSourceExtension 사용xaml에서 다음과 같이 위에서 만든 EnumBindingSourceExtension을 사용할 수 있습니다. [ViewModel.cs] private ETest _selectedETest = ETest.A;
public ETest SelectedETest
{
get => _selectedETest;
set
{
_selectedETest = value;
OnPropertyChanged();
}
}
뷰 xaml에서 EnumBindingSourceExtension 네임스페이스를 추가해 주고 [View.xaml] <ComboBox ItemsSource="{Binding Source={local:EnumBindingSource {x:Type local:ETest}, Fillter='A,C'}}"
SelectedItem="{Binding SelectedETest}"/>
위 처럼 Enum ETest을 콤보박스 아이템으로 바인딩 처리 동시에 상수 값 A, C 만 콤보박스 아이템으로 표시 되는 걸 확인할 수 있습니다. 동시에 콤보박스 아이템 선택시 해당 Enum 값에 맞게 SelectedETest에 정상 바인딩 되는 것을 확인할 수 있습니다.
|