RadioButtons с поведением привязаны к одному свойству

  • У меня мало RadioButtons, и я не хочу связывать "IsChecked" свойство каждого из них к уникальному свойству в коде.
  • Я хочу иметь одно свойство вроде "CurrentSelected" и в соответствии с чтобы установить "IsChecked".
  • Кроме того, я не хочу использовать преобразователи.
  • Я попытался использовать поведение "ChangePropertyAction", но он выглядит как он работает только в одном направлении. вот мой код:

    <RadioButton
        x:Name="UpRadioButton"
        Margin="5"
        Content="Up"
        >
        <i:Interaction.Triggers>
            <ei:DataTrigger Binding="{Binding IsChecked, ElementName=UpRadioButton}" Value="True">
                <ei:ChangePropertyAction TargetObject="{Binding Mode=OneWay}" PropertyName="SelectedDirection" Value="{x:Static Enums:DirectionEnum.Up}" />
            </ei:DataTrigger>
        </i:Interaction.Triggers>
    </RadioButton>
    
    <RadioButton
        x:Name="DownRadioButton"
        Margin="5"
        Content="Down"
        >
        <i:Interaction.Triggers>
            <ei:DataTrigger Binding="{Binding IsChecked, ElementName=DownRadioButton}" Value="True">
                <ei:ChangePropertyAction TargetObject="{Binding Mode=OneWay}" PropertyName="SelectedDirection" Value="{x:Static Enums:DirectionEnum.Down}" />
            </ei:DataTrigger>
        </i:Interaction.Triggers>
    </RadioButton>
    
    <RadioButton
        x:Name="LeftRadioButton"
        Margin="5"
        Content="Left"
        >
        <i:Interaction.Triggers>
            <ei:DataTrigger Binding="{Binding IsChecked, ElementName=LeftRadioButton}" Value="True">
                <ei:ChangePropertyAction TargetObject="{Binding Mode=OneWay}" PropertyName="SelectedDirection" Value="{x:Static Enums:DirectionEnum.Left}" />
            </ei:DataTrigger>
        </i:Interaction.Triggers>
    </RadioButton>
    
    <RadioButton
        x:Name="RightRadioButton"
        Margin="5"
        Content="Right"
        >
        <i:Interaction.Triggers>
            <ei:DataTrigger Binding="{Binding IsChecked, ElementName=RightRadioButton}" Value="True">
                <ei:ChangePropertyAction TargetObject="{Binding Mode=OneWay}" PropertyName="SelectedDirection" Value="{x:Static Enums:DirectionEnum.Right}" />
            </ei:DataTrigger>
        </i:Interaction.Triggers>
    </RadioButton>               
    

моя модель просмотра очень проста: MainViewModel.cs

public class MainViewModel : ViewModelBase
{ 
    private DirectionEnum _selectedDirection;

    public DirectionEnum SelectedDirection
    {
        get { return _selectedDirection; }
        set
        {
            if (_selectedDirection != value)
            {
                _selectedDirection = value;
                RaisePropertyChanged();
            }
        }
    }
    public MainViewModel()
    {     
        SelectedDirection = DirectionEnum.Up;            
    }  
}

как вы можете видеть из кода, "Up" RadioButton должен быть уже проверен... Что мне не хватает?

Ответ 1

Общим решением для меня является использование ListBox, который содержит поведение выбора, и перезаписывать шаблон для рисования элементов в качестве RadioButtons.

Мой шаблон XAML обычно выглядит примерно так:

<Style x:Key="RadioButtonListBoxStyle" TargetType="{x:Type ListBox}">
    <Setter Property="BorderBrush" Value="Transparent"/>
    <Setter Property="KeyboardNavigation.DirectionalNavigation" Value="Cycle" />
    <Setter Property="ItemContainerStyle">
        <Setter.Value>
            <Style TargetType="{x:Type ListBoxItem}" >
                <Setter Property="Margin" Value="2, 2, 2, 0" />
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <Border Background="Transparent">
                                <RadioButton
                                    Content="{TemplateBinding ContentPresenter.Content}" VerticalAlignment="Center"
                                    IsChecked="{Binding Path=IsSelected,RelativeSource={RelativeSource TemplatedParent},Mode=TwoWay}"/>

                            </Border>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Setter.Value>
    </Setter>
</Style>

Стиль применяется следующим образом:

<ListBox ItemsSource="{Binding Directions}"
         SelectedValue="{Binding SelectedDirection}"
         Style="{StaticResource RadioButtonListBoxStyle}" />

Я считаю, что это намного более чистое решение для управления поведением сгруппированных RadioButtons, чем поддержание большого количества свойств IsChecked в моем коде или использование конвертеров.