RadioButton을 열거 형에 바인딩하는 방법은 무엇입니까?


406

나는 다음과 같은 열거 형을 가지고있다 :

public enum MyLovelyEnum
{
    FirstSelection,
    TheOtherSelection,
    YetAnotherOne
};

내 DataContext에 속성이 있습니다.

public MyLovelyEnum VeryLovelyEnum { get; set; }

WPF 클라이언트에 3 개의 RadioButton이 있습니다.

<RadioButton Margin="3">First Selection</RadioButton>
<RadioButton Margin="3">The Other Selection</RadioButton>
<RadioButton Margin="3">Yet Another one</RadioButton>

이제 적절한 양방향 바인딩을 위해 RadioButton을 속성에 어떻게 바인딩합니까?


3
XAML에서 개별 RadioButton을 지정하지 않고이 작업을 수행하려면 this 또는 this 와 같은 열거 형 값에 바인딩 된 ListBox를 사용하는 것이 좋습니다. 항목 템플릿은 같은 RadioButtons를 사용하도록 덮어 씁니다 .
Rachel

답변:


389

좀 더 일반적인 변환기를 사용할 수 있습니다

public class EnumBooleanConverter : IValueConverter
{
  #region IValueConverter Members
  public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    string parameterString = parameter as string;
    if (parameterString == null)
      return DependencyProperty.UnsetValue;

    if (Enum.IsDefined(value.GetType(), value) == false)
      return DependencyProperty.UnsetValue;

    object parameterValue = Enum.Parse(value.GetType(), parameterString);

    return parameterValue.Equals(value);
  }

  public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  {
    string parameterString = parameter as string;
    if (parameterString == null)
        return DependencyProperty.UnsetValue;

    return Enum.Parse(targetType, parameterString);
  }
  #endregion
}

그리고 XAML-Part에서는 다음을 사용합니다.

<Grid>
    <Grid.Resources>
      <l:EnumBooleanConverter x:Key="enumBooleanConverter" />
    </Grid.Resources>
    <StackPanel >
      <RadioButton IsChecked="{Binding Path=VeryLovelyEnum, Converter={StaticResource enumBooleanConverter}, ConverterParameter=FirstSelection}">first selection</RadioButton>
      <RadioButton IsChecked="{Binding Path=VeryLovelyEnum, Converter={StaticResource enumBooleanConverter}, ConverterParameter=TheOtherSelection}">the other selection</RadioButton>
      <RadioButton IsChecked="{Binding Path=VeryLovelyEnum, Converter={StaticResource enumBooleanConverter}, ConverterParameter=YetAnotherOne}">yet another one</RadioButton>
    </StackPanel>
</Grid>

51
나를 위해 매력처럼 일했습니다. 또한 실버 라이트 (및 아마도 WPF가 적절 함)가 이전 라디오 버튼 값을 설정 해제 할 때 한 번, 다시 새로운 값을 설정하기 위해 변환기를 두 번 호출하기 때문에 "false"에서 UnsetValue를 반환하도록 ConvertBack을 수정했습니다. 나는 재산 세터에서 다른 것들을 걸고 있었으므로 한 번만 호출하기를 원했습니다. -if (parameterString == null || value.Equals (false)) return DependencyProperty.UnsetValue;
MarcE

8
내가 알 수있는 것으로부터 , 라디오 버튼이 다른 그룹에 있지 않으면 이 수행 해야합니다 (그룹 이름이 설정되지 않은 AFAIK 버튼이 기본적으로 동일한 그룹에 있음). 그렇지 않으면 속성 "바운스"를 설정하기위한 호출로 이상한 동작이 발생합니다.
nlawalker

2
예. false로 설정할 때 변환기에서 Unset을 호출하면 true EnumToBooleanConverter가 아니라 EnumToRadioButtonConverter가됩니다. 대신 속성 설정 기에서 값이 다른지 확인합니다. if (_myEnumBackingField == value) return;
Stéphane

8
이 솔루션의 바인딩은 단방향으로 만 올바르게 작동합니다. 바인딩 된 속성을 다른 값으로 할당하여 프로그래밍 방식으로 라디오 버튼을 전환 할 수 없었습니다. 제대로 작동하고 더 나은 솔루션을 원하면 scott의 접근 방식을 사용하십시오.
l46kok

2
@Marc,이 경우 'DependencyProperty.UnsetValue'가 아닌 'Binding.DoNothing'을 반환하는 것이 적절하지 않습니까?
Mark A. Donohoe

559

허용 된 답변을 더 단순화 할 수 있습니다. 열거 형을 xaml에 문자열로 입력하고 필요한 것보다 변환기에서 더 많은 작업을 수행하는 대신 문자열 표현 대신 열거 형 값을 명시 적으로 전달할 수 있으며 CrimsonX가 언급 한대로 런타임이 아닌 컴파일 타임에 오류가 발생합니다.

ConverterParameter = {x : 정적 로컬 : YourEnumType.Enum1}

<StackPanel>
    <StackPanel.Resources>          
        <local:ComparisonConverter x:Key="ComparisonConverter" />          
    </StackPanel.Resources>
    <RadioButton IsChecked="{Binding Path=YourEnumProperty, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static local:YourEnumType.Enum1}}" />
    <RadioButton IsChecked="{Binding Path=YourEnumProperty, Converter={StaticResource ComparisonConverter}, ConverterParameter={x:Static local:YourEnumType.Enum2}}" />
</StackPanel>

그런 다음 변환기를 단순화하십시오.

public class ComparisonConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value?.Equals(parameter);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value?.Equals(true) == true ? parameter : Binding.DoNothing;
    }
}

편집 (12 월 16 일 10 일) :

DependencyProperty.UnsetValue 대신 Binding.DoNothing을 반환하도록 제안한 anon에게 감사드립니다.


참고-동일한 컨테이너에있는 여러 개의 RadioButton 그룹 (Feb 17 '11) :

xaml에서 단일 선택 단추가 동일한 상위 컨테이너를 공유하는 경우 하나를 선택하면 다른 특성에 바인드되어 있어도 해당 컨테이너 내의 다른 모든 컨테이너가 선택 해제됩니다. 따라서 공통 속성에 바인딩 된 RadioButton을 스택 패널과 같은 자체 컨테이너에 그룹화하십시오. 관련 RadioButton이 단일 상위 컨테이너를 공유 할 수없는 경우 각 RadioButton의 GroupName 속성을 공통 값으로 설정하여 논리적으로 그룹화하십시오.


편집 (Apr 5 '11) :

삼항 연산자를 사용하기 위해 단순화 된 ConvertBack의 if-else입니다.


참고-클래스에 중첩 된 열거 형 유형 (Apr 28 '11) :

열거 형 유형이 네임 스페이스에 직접 포함되지 않고 클래스에 중첩 된 경우 '+'구문을 사용하여 XAML의 열거 형에 액세스하여 질문에 대한 (표시되지 않음) 답변에 나와있는 것처럼 답변 을 찾을 수 없습니다 WPF에서 정적 참조를위한 열거 형 :

ConverterParameter = {x : 정적 로컬 : YourClass + YourNestedEnumType.Enum1}

그러나이 Microsoft Connect 문제 로 인해 VS2010의 디자이너는 더 이상 상태를로드 "Type 'local:YourClass+YourNestedEnumType' was not found."하지 않지만 프로젝트는 성공적으로 컴파일 및 실행됩니다. 물론 열거 형을 네임 스페이스로 직접 이동할 수 있다면이 문제를 피할 수 있습니다.


편집 (Jan 27 '12) :

Enum 플래그를 사용하는 경우 변환기는 다음과 같습니다.

public class EnumToBooleanConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return ((Enum)value).HasFlag((Enum)parameter);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        return value.Equals(true) ? parameter : Binding.DoNothing;
    }
}

편집 (5 월 7 일 '15 일) :

(하는 null 허용 열거의 경우 하지 질문에 물었지만, 예를 들어, ORM DB에서 널 (null)을 반환하거나 때마다 프로그램 로직에 값이 제공되지 않는 것을 적합 할 수 있습니다, 경우에 따라 필요할 수 있습니다), 추가 기억 Convert 메서드에서 초기 null을 확인하고 적절한 부울 값을 반환합니다. 일반적으로 아래와 같이 false입니다 (라디오 버튼을 선택하지 않으려는 경우).

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value == null) {
            return false; // or return parameter.Equals(YourEnumType.SomeDefaultValue);
        }
        return value.Equals(parameter);
    }

참고-NullReferenceException (10 월 10 일 '18) :

NullReferenceException 발생 가능성을 제거하도록 예제를 업데이트했습니다. IsCheckednullable 형식이므로 반환 Nullable<Boolean>하는 것이 합리적인 해결책 인 것 같습니다.


26
나는 이것이 더 나은 해결책이라고 믿는다. 또한이 변환을 사용하면 열거 값이 변경되면 런타임이 아닌 컴파일 타임에 프로젝트가 중단되므로 큰 이점이 있습니다.
CrimsonX

4
이것은 허용되는 것보다 확실히 더 나은 솔루션입니다. +1
OrPaz

7
좋은 해결책. 나는 이것이 실제로 2 개의 값을 비교하는 비교 변환기라고 덧붙일 것입니다. ComparisonConverter와 같은 EnumToBooleanConverter보다 더 일반적인 이름을 가질 수 있습니다
MikeKulls

5
@ 스캇, 아주 좋아요. 이 변환기는 플래그 속성이 있거나없는 모든 경우에 적합합니다. 그러나이 필터를 enum을 플래그로 사용하여 변환기로 직접 사용하는 것은 어리석은 일입니다. 올바른 결과를 얻으려면 이전 값으로 부울 계산 (| = 또는 ^ =)을 달성해야하지만 변환기가 이전 값에 액세스 할 수 없기 때문입니다. 그런 다음 각 열거 형 값에 대해 부울을 추가하고 MVVM 모델에서 적절한 부울 계산을 직접 수행해야합니다. 그러나 모든 정보에 매우 감사합니다.
Eric Ouellet

2
Windows Phone 8 (아마도 Win Store 앱의 경우)에는 x : static이 없으므로 여기에서 직접 솔루션을 사용할 수 없습니다. 그러나 IDE / Complier는 충분히 똑똑하고 모든 문자열 리터럴에 대해 문자열을 찾습니다 (어쨌든 내 추측). <RadioButton IsChecked = "{Binding TrackingMode, ConverterParameter = Driving, Converter = {StaticResource EnumToBooleanConverter}, Mode = TwoWay}"/> Driving이 아닌 런타임에 디자인 / 컴파일 시간 동안 오타가 발생합니다.
Adarsha

26

EnumToBooleanConverter 답변의 경우 : DependencyProperty.UnsetValue를 반환하는 대신 라디오 버튼 IsChecked 값이 false가되는 경우 Binding.DoNothing을 반환하는 것을 고려하십시오. 전자는 문제를 나타내며 (사용자에게 빨간색 사각형 또는 유사한 유효성 표시기를 표시 할 수 있음) 후자는 아무 것도 수행하지 않아야한다는 것을 나타내며,이 경우 원하는 것입니다.

http://msdn.microsoft.com/en-us/library/system.windows.data.ivalueconverter.convertback.aspx http://msdn.microsoft.com/en-us/library/system.windows.data.binding .donothing.aspx


Silverlight에는 바인딩이 없습니다. WPF 전용입니다. 대신 null을 사용하십시오.
Alexander Vasilyev

1
바인딩 UWP에서도 없어진 것이 없습니다.
BlackICE

5

ListBox에서 RadioButton을 사용한 다음 SelectedValue에 바인딩합니다.

이것은이 주제에 관한 오래된 글이지만, 기본 아이디어는 동일해야합니다 .


ListBox와 DataTemplate을 사용하여 비슷한 방법을 사용하는 양방향 바인딩을 얻으므로 그렇게해야합니다.
Bryan Anderson

이 버그 : geekswithblogs.net/claraoscura/archive/2008/10/17/125901.aspx 가 나를 위해 하루를 망쳤습니다.
Slampen 2016 년

3
이것은 지금까지 가장 좋은 솔루션이며 다른 모든 것은 중복 코드를 유발합니다. ( ListBox를 사용하는 또 다른 예 )
HB

3

UWP의 경우 그렇게 간단하지 않습니다. 필드 값을 매개 변수로 전달하려면 추가 후프를 뛰어 넘어야합니다.

실시 예 1

WPF 및 UWP 모두에 유효합니다.

<MyControl>
    <MyControl.MyProperty>
        <Binding Converter="{StaticResource EnumToBooleanConverter}" Path="AnotherProperty">
            <Binding.ConverterParameter>
                <MyLibrary:MyEnum>Field</MyLibrary:MyEnum>
            </Binding.ConverterParameter>
        </MyControl>
    </MyControl.MyProperty>
</MyControl>

실시 예 2

WPF 및 UWP 모두에 유효합니다.

...
<MyLibrary:MyEnum x:Key="MyEnumField">Field</MyLibrary:MyEnum>
...

<MyControl MyProperty="{Binding AnotherProperty, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={StaticResource MyEnumField}}"/>

실시 예 3

WPF에만 유효합니다!

<MyControl MyProperty="{Binding AnotherProperty, Converter={StaticResource EnumToBooleanConverter}, ConverterParameter={x:Static MyLibrary:MyEnum.Field}}"/>

UWP는 지원하지 않습니다 x:Static그래서 예 3은 밖으로 질문입니다; 예제 1을 사용 한다고 가정하면 결과는 더 자세한 코드입니다. 예제 2 가 약간 더 좋지만 여전히 이상적이지는 않습니다.

해결책

public abstract class EnumToBooleanConverter<TEnum> : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {
        var Parameter = parameter as string;

        if (Parameter == null)
            return DependencyProperty.UnsetValue;

        if (Enum.IsDefined(typeof(TEnum), value) == false)
            return DependencyProperty.UnsetValue;

        return Enum.Parse(typeof(TEnum), Parameter).Equals(value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        var Parameter = parameter as string;
        return Parameter == null ? DependencyProperty.UnsetValue : Enum.Parse(typeof(TEnum), Parameter);
    }
}

그런 다음 지원하려는 각 유형에 대해 열거 형 유형을 상자 화하는 변환기를 정의하십시오.

public class MyEnumToBooleanConverter : EnumToBooleanConverter<MyEnum>
{
    //Nothing to do!
}

박스에 넣어야하는 이유는 ConvertBack메서드 에서 형식을 참조 할 방법이 없기 때문입니다 . 권투는 그것을 처리합니다. 처음 두 예제 중 하나를 사용하는 경우 매개 변수 유형을 참조하면 상자 클래스에서 상속 할 필요가 없습니다. 가능한 한 한 줄로 모든 것을하고 싶다면, 후자의 솔루션이 이상적입니다.

사용법은 예 2 와 비슷 하지만 실제로는 덜 장황합니다.

<MyControl MyProperty="{Binding AnotherProperty, Converter={StaticResource MyEnumToBooleanConverter}, ConverterParameter=Field}"/>

단점은 지원하려는 각 유형에 대한 변환기를 정의해야한다는 것입니다.


1

RadioButtons 및 CheckBoxes를 열거 형에 바인딩하는 것을 처리하는 새 클래스를 만들었습니다. 단일 선택 확인란 또는 단일 선택 단추에 대해 플래그가 지정된 열거 형 (복수의 확인란 선택)과 비 플래그 형 열거 형에 작동합니다. 또한 ValueConverters가 전혀 필요하지 않습니다.

처음에는 더 복잡해 보일 수 있지만 일단이 클래스를 프로젝트에 복사하면 완료됩니다. 일반적이므로 모든 열거 형에 쉽게 재사용 할 수 있습니다.

public class EnumSelection<T> : INotifyPropertyChanged where T : struct, IComparable, IFormattable, IConvertible
{
  private T value; // stored value of the Enum
  private bool isFlagged; // Enum uses flags?
  private bool canDeselect; // Can be deselected? (Radio buttons cannot deselect, checkboxes can)
  private T blankValue; // what is considered the "blank" value if it can be deselected?

  public EnumSelection(T value) : this(value, false, default(T)) { }
  public EnumSelection(T value, bool canDeselect) : this(value, canDeselect, default(T)) { }
  public EnumSelection(T value, T blankValue) : this(value, true, blankValue) { }
  public EnumSelection(T value, bool canDeselect, T blankValue)
  {
    if (!typeof(T).IsEnum) throw new ArgumentException($"{nameof(T)} must be an enum type"); // I really wish there was a way to constrain generic types to enums...
    isFlagged = typeof(T).IsDefined(typeof(FlagsAttribute), false);

    this.value = value;
    this.canDeselect = canDeselect;
    this.blankValue = blankValue;
  }

  public T Value
  {
    get { return value; }
    set 
    {
      if (this.value.Equals(value)) return;
      this.value = value;
      OnPropertyChanged();
      OnPropertyChanged("Item[]"); // Notify that the indexer property has changed
    }
  }

  [IndexerName("Item")]
  public bool this[T key]
  {
    get
    {
      int iKey = (int)(object)key;
      return isFlagged ? ((int)(object)value & iKey) == iKey : value.Equals(key);
    }
    set
    {
      if (isFlagged)
      {
        int iValue = (int)(object)this.value;
        int iKey = (int)(object)key;

        if (((iValue & iKey) == iKey) == value) return;

        if (value)
          Value = (T)(object)(iValue | iKey);
        else
          Value = (T)(object)(iValue & ~iKey);
      }
      else
      {
        if (this.value.Equals(key) == value) return;
        if (!value && !canDeselect) return;

        Value = value ? key : blankValue;
      }
    }
  }

  public event PropertyChangedEventHandler PropertyChanged;

  private void OnPropertyChanged([CallerMemberName] string propertyName = "")
  {
    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  }
}

그리고 그것을 사용하는 방법에 대해 수동 또는 자동으로 작업을 실행하기위한 열거 형이 있고 요일 동안 예약 할 수 있고 몇 가지 선택적 옵션이 있다고 가정 해 봅시다.

public enum StartTask
{
  Manual,
  Automatic
}

[Flags()]
public enum DayOfWeek
{
  Sunday = 1 << 0,
  Monday = 1 << 1,
  Tuesday = 1 << 2,
  Wednesday = 1 << 3,
  Thursday = 1 << 4,
  Friday = 1 << 5,
  Saturday = 1 << 6
}

public enum AdditionalOptions
{
  None = 0,
  OptionA,
  OptionB
}

이제이 클래스를 사용하는 것이 얼마나 쉬운 지 다음과 같습니다.

public class MyViewModel : ViewModelBase
{
  public MyViewModel()
  {
    StartUp = new EnumSelection<StartTask>(StartTask.Manual);
    Days = new EnumSelection<DayOfWeek>(default(DayOfWeek));
    Options = new EnumSelection<AdditionalOptions>(AdditionalOptions.None, true, AdditionalOptions.None);
  }

  public EnumSelection<StartTask> StartUp { get; private set; }
  public EnumSelection<DayOfWeek> Days { get; private set; }
  public EnumSelection<AdditionalOptions> Options { get; private set; }
}

이 클래스를 사용하여 확인란과 라디오 버튼을 쉽게 바인딩 할 수 있습니다.

<StackPanel Orientation="Vertical">
  <StackPanel Orientation="Horizontal">
    <!-- Using RadioButtons for exactly 1 selection behavior -->
    <RadioButton IsChecked="{Binding StartUp[Manual]}">Manual</RadioButton>
    <RadioButton IsChecked="{Binding StartUp[Automatic]}">Automatic</RadioButton>
  </StackPanel>
  <StackPanel Orientation="Horizontal">
    <!-- Using CheckBoxes for 0 or Many selection behavior -->
    <CheckBox IsChecked="{Binding Days[Sunday]}">Sunday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Monday]}">Monday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Tuesday]}">Tuesday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Wednesday]}">Wednesday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Thursday]}">Thursday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Friday]}">Friday</CheckBox>
    <CheckBox IsChecked="{Binding Days[Saturday]}">Saturday</CheckBox>
  </StackPanel>
  <StackPanel Orientation="Horizontal">
    <!-- Using CheckBoxes for 0 or 1 selection behavior -->
    <CheckBox IsChecked="{Binding Options[OptionA]}">Option A</CheckBox>
    <CheckBox IsChecked="{Binding Options[OptionB]}">Option B</CheckBox>
  </StackPanel>
</StackPanel>
  1. UI가로드되면 "Manual"라디오 버튼이 선택되고 "Manual"또는 "Automatic"중에서 선택을 변경할 수 있지만 둘 중 하나를 항상 선택해야합니다.
  2. 요일마다 선택이 해제되지만 그 수는 선택하거나 해제 할 수 있습니다.
  3. "옵션 A"와 "옵션 B"는 모두 처음에 체크 해제되어 있습니다. 둘 중 하나를 검사하고, 하나를 검사하면 다른 하나를 선택 취소 할 수 있지만 (RadioButtons와 유사) 이제 둘 다 선택 해제 할 수 있습니다 (WPF의 RadioButton으로 수행 할 수 없으므로 CheckBox가 사용되는 이유).

StartTask 열거 형에 {Undefined, Manual, Automatic}과 같은 3 개의 항목이 있다고 가정합니다. 사용자가 값을 설정할 때까지 기본값이 정의되지 않음으로 설정하려고합니다. 또한 : SelectedItem은 어떻게 처리됩니까? ViewModel에 SelectedStartTask가 없습니다.
user1040323

내 ViewModel에서 StartUp 속성은 EnumSelection<StartTask>객체입니다. 정의를 보면 EnumSelection<T>Value 속성이 있음 을 알 수 있습니다. 따라서 뷰 모델에는 "SelectedStartTask"가 필요하지 않습니다. 을 사용 StartUp.Value합니다. 기본값 Undefined를 사용하려면 3 번째 열거 인 AdditionalOptions를 참조하십시오. Undefined 대신 None이 있지만 원하는 이름으로 이름을 변경할 수 있습니다.
Nick

1

이것은 Checkbox 에서도 작동합니다 .

public class EnumToBoolConverter:IValueConverter
{
    private int val;
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        int intParam = (int)parameter;
        val = (int)value;

        return ((intParam & val) != 0);
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        val ^= (int)parameter;
        return Enum.Parse(targetType, val.ToString());
    }
}

단일 열거 형을 여러 확인란에 바인딩


1
나는 당신이 나를 위해 한 호의에 대해 당신에게 큰 "감사합니다"고 말합니다. 그것은 나를 위해 매력처럼 작동했습니다.
Elham Azadfar

0

Scott의 EnumToBooleanConverter를 기반으로합니다. 플래그 코드가있는 Enum에서는 ConvertBack 메서드가 작동하지 않는 것으로 나타났습니다.

다음 코드를 시도했습니다.

public class EnumHasFlagToBooleanConverter : IValueConverter
    {
        private object _obj;
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            _obj = value;
            return ((Enum)value).HasFlag((Enum)parameter);
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value.Equals(true))
            {
                if (((Enum)_obj).HasFlag((Enum)parameter))
                {
                    // Do nothing
                    return Binding.DoNothing;
                }
                else
                {
                    int i = (int)_obj;
                    int ii = (int)parameter;
                    int newInt = i+ii;
                    return (NavigationProjectDates)newInt;
                }
            }
            else
            {
                if (((Enum)_obj).HasFlag((Enum)parameter))
                {
                    int i = (int)_obj;
                    int ii = (int)parameter;
                    int newInt = i-ii;
                    return (NavigationProjectDates)newInt;

                }
                else
                {
                    // do nothing
                    return Binding.DoNothing;
                }
            }
        }
    }

내가 작업을 얻을 수있는 유일한 것은에서 캐스팅을하는 것입니다 inttargetType내가가 하드 코딩했다 그래서 NavigationProjectDates내가 사용하는 열거. 그리고 targetType == NavigationProjectDates...


보다 일반적인 Flags Enum 변환기를 편집하십시오.

    공용 클래스 FlagsEnumToBooleanConverter : IValueConverter {
        private int _flags = 0;
        공용 객체 변환 (객체 값, 유형 targetType, 객체 매개 변수, 문자열 언어) {
            if (value == null)는 false를 리턴합니다.
            _flags = (int) 값;
            타입 t = value.GetType ();
            객체 o = Enum.ToObject (t, 파라미터);
            반환 ((Enum) 값) .HasFlag ((Enum) o);
        }

        공용 객체 ConvertBack (객체 값, 유형 targetType, 객체 매개 변수, 문자열 언어)
        {
            if (value? .Equals (true) ?? false) {
                _flags = _flags | (int) 파라미터;
            }
            다른 {
                _flags = _flags & ~ (int) 파라미터;
            }
            _flags를 반환;
        }
    }

누군가가 with with Flags 코드에 추가하기 위해 내 대답을 편집 했으므로 솔직히 직접 시도하거나 사용하지 않았으며 자신의 대답으로 생각하는 것처럼 제거하는 것을 고려했습니다. 나중에 시간을 찾을 수 있다면 코드를 테스트하기 위해 무언가를 모아서 가지고있는 코드뿐만 아니라 문제에 대한 더 나은 해결책을 찾도록 도울 수 있습니다.
Scott

0

라디오 버튼을 동적으로 만들 수 있으며 ListBox변환기없이 간단하게 수행 할 수 있습니다.

구성 단계는 다음과 같습니다. ListBox를 만들고 목록 상자의 ItemsSource를 열거 형으로 설정하고 ListBox MyLovelyEnum의 SelectedItem을 VeryLovelyEnum속성에 바인딩합니다 . 그러면 각 ListBoxItem의 라디오 버튼이 생성됩니다.

  • 1 단계 : Window, UserControl 또는 Grid 등의 정적 리소스에 열거 형을 추가하십시오.
    <Window.Resources>
        <ObjectDataProvider MethodName="GetValues"
                            ObjectType="{x:Type system:Enum}"
                            x:Key="MyLovelyEnum">
            <ObjectDataProvider.MethodParameters>
                <x:Type TypeName="local:MyLovelyEnum" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>
  • 2 단계 : 목록 상자를 사용하여 Control Template각 항목을 단일 선택 단추로 채 웁니다.
    <ListBox ItemsSource="{Binding Source={StaticResource MyLovelyEnum}}" SelectedItem="{Binding VeryLovelyEnum, Mode=TwoWay}" >
        <ListBox.Resources>
            <Style TargetType="{x:Type ListBoxItem}">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <RadioButton
                                Content="{TemplateBinding ContentPresenter.Content}"
                                IsChecked="{Binding Path=IsSelected,
                                RelativeSource={RelativeSource TemplatedParent},
                                Mode=TwoWay}" />
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </ListBox.Resources>
    </ListBox>

장점은 다음과 같습니다 : 언젠가 당신의 열거 클래스 변경, 당신은 GUI (XAML 파일)를 업데이트 할 필요가없는 경우.

참조 : https://brianlagunas.com/a-better-way-to-data-bind-enums-in-wpf/

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.