Radiobuttons Ischecked属性在wpf mvvm中不起作用

时间:2012-08-27 12:50:30

标签: wpf mvvm

我无法将两个radiobuttons绑定到我的xaml表单和IsChecked属性,其中我也使用了nullabletoboolconverters。然而,我的代码中的radiobuttons缺血特性没有改变(一旦我们在第二个之后击中第一个放射性按钮,它根本没有达到断点)并且我正在绑定其中两个的缺血性质,因为我需要设置基于radiobuttons属性的表单上其他面板的可见性。

以下是我的xaml代码,后来是我的viewmodel.cs radiobutton属性代码:

   <RadiobuttonSelectedConverter x:Key="CheckedSelection"/>// declaring my converter class in my resource dictionary.

  <StackPanel Orientation="Horizontal" Grid.Column="0" Grid.Row="3" Margin="10,5,0,0">
        <RadioButton GroupName="RadiosGroup" IsChecked="{Binding IsRadioButton1,Mode=TwoWay,
             Converter={StaticResource CheckedSelection}, ConverterParameter=true}">
                    First</RadioButton>
        <RadioButton GroupName="RadiosGroup" 
                     Margin="40,0,0,0" IsChecked="{Binding IsRadioButton2,Mode=TwoWay, 
            Converter={StaticResource CheckedSelection}, ConverterParameter=true}">Second</RadioButton>
    </StackPanel>



    private bool _isRadioButton1;

    public bool IsRadioButton1
    {
        get
        {
            return _isRadioButton1;
        }
        set
        {
            if _isRadioButton1!= value)
            {
                _isRadioButton1= value;

                IsRadioButton2= false;
                OnPropertyChanged("IsRadioButton1");

            }
        }
    }


    private bool _isRadioButton2;

    public bool IsRadioButton2
    {
        get
        {
            return _isRadioButton2;
        }
        set
        {
            if (_isRadioButton2 != value)
            {
                _isRadioButton2 = value;

              IsRadioButton1= false;
              OnPropertyChanged("IsRadioButton2");

            }
        }
    }

以下是我的转换器代码:

  [ValueConversion(typeof(bool?), typeof(bool))]
public class RadiobuttonSelectedConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool param = bool.Parse(parameter.ToString());
        if (value == null)
        {
            return false;
        }
        else
        {
            return !((bool)value ^ param);
        }
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        bool param = bool.Parse(parameter.ToString());
        return !((bool)value ^ param);
    }
}

有人请先帮助我解决我的问题..

2 个答案:

答案 0 :(得分:6)

就我个人而言,我根本不会像这样编码关联的RadioButtons。由于您想要的选择行为与ListBox使用的相同,因此我发现最简单的方法就是使用ListBox来为每个项目设置RadioButtons样式。

代码隐藏通常包含

  • ObservableCollection<string> Options
  • string SelectedOption

我会将此样式用于ListBox

<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 Options}"
         SelectedValue="{Binding SelectedOption}"
         Style="{StaticResource RadioButtonListBoxStyle}" />

您还可以使用其他内容代替String进行收藏,例如ChildViewModel,然后根据当前项设置相关的视图,这意味着您无需费心使用Visibility中关联面板的ViewModel

<DockPanel>
    <ListBox ItemsSource="{Binding OptionViewModels}"
             SelectedValue="{Binding SelectedViewModel}"
             Style="{StaticResource RadioButtonListBoxStyle}"
             DockPanel.Dock="Left">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <TextBlock Text="{Binding DisplayName}" />
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>

    <ContentControl Content="{Binding SelectedViewModel}" />
</DockPanel>

但至于你的实际问题,我可以想到它可能表现不正确的3个原因。

第一部分在Jay's answer中列出:您在IsChecked2的设置器中将IsChecked1设置为false,并且IsChecked2IsChecked1设置为false setter,所以最终结果是两个值都是假的。

第二个问题是转换器可能存在问题。你说这是一个评论它没有转换器正常工作,所以我认为这可能是问题的一部分。

最后,我认为更改分组RadioButtons会触发旧项目的IsOptionA.IsSelected = false和新选择的项目的IsOptionB.IsSelected = true,这两者可能会越过某处。

答案 1 :(得分:1)

这里有几个问题。

  1. 您不需要转换器。设置IsRadioButton1类型的IsRadioButton2bool?属性,TwoWay Binding就足够了,或者如果是三态,则将其保留为bool不适合你。
  2. 您的二传手中的逻辑似乎不正确。在这两种情况下,您都要将其他RadioButton的值设置为false,因此如果IsRadioButton1true,则您将IsRadioButton2设置为{{1} ,} setter将调用true,然后该setter将调用IsRadioButton = false。它们最终都会成为IsRadioButton2 = false
  3. 您可能希望阅读false


    修改

    实际上,正如我记得的那样,if(value) IsRadioButton2 = false;并不意味着以RadioButton的方式绑定到bool属性。我认为您将所有CheckBox绑定到一个属性,并使用RadioButton Converter 来设置属性。我会在一分钟内找到一个例子和帖子。


    好的,这是一个解决方案,使用派生的ConverterParameter类,它纯粹使用绑定:http://blogs.msdn.com/b/mthalman/archive/2008/09/04/wpf-data-binding-with-radiobutton.aspx

    这是一个相关的SO问题&amp;答案:MVVM: Binding radio buttons to a view model?