【问题标题】:Bind RadioButtons to single property?将 RadioButtons 绑定到单个属性?
【发布时间】:2015-02-17 21:18:15
【问题描述】:
  • 我的 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;            
    }  
}

从代码中可以看出,“向上”单选按钮应该已经被选中... 我错过了什么?

【问题讨论】:

  • 它可能只能以一种方式工作,因为您的绑定只是一种方式......另外,转换器有什么问题?有一个对这个很棒
  • 转换器需要维护...
  • 一般来说代码也是如此......这是你的选择,但在我的书中说你不喜欢转换器,因为它们需要“维护”是一个非常糟糕的理由/借口。
  • Bradley,请参考 Rachel 建议的解决方案。难道你不认为它比持有 2 路转换器更优雅吗?
  • 我是否个人认为它更优雅?不。对于动态数据,我可以看到它,但如果您从一开始就知道单选按钮的数据,ValueEqualsConverter非常优雅/简单的。

标签: c# wpf xaml behavior


【解决方案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 属性或使用转换器要干净得多。

【讨论】:

  • Rachel,您的解决方案非常完美。谢谢
  • 在尝试了一段时间后,我终于找到了你的另一篇文章,它解释了为什么它不适用于 DisplayMemberPath - stackoverflow.com/a/7487670/3195477 很高兴你也更新了那个!
猜你喜欢
  • 1970-01-01
  • 2020-12-02
  • 2012-10-26
  • 1970-01-01
  • 1970-01-01
  • 2016-02-08
  • 1970-01-01
  • 2010-09-28
相关资源
最近更新 更多