Radiobuttons Ischecked property is not working in wpf mvvm

I am unable to bind two radiobuttons to my xaml form and IsChecked property with same group names for which I also used nullabletoboolconverters. however, the radiobuttons ischecked property does not get changed in my code(it is not at all hitting the breakpoint, once we hit the first radiobutton after second one) and I am binding ischecked properties of two of them seperately as I need to set the visibility of some other panel on the form based on the radiobuttons property.

the following is my xaml code and later is my viewmodel.cs code for radiobutton properties:

   <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");

            }
        }
    }

the following is my Converter code:

  [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);
    }
}

Someone please help me resolving my issue thanks in advance..


Personally I wouldn't code associated RadioButtons like this at all. Since the selection behavior you want is the same used for a ListBox , I find it easiest to simply use a ListBox that is styled to use RadioButtons for each item.

The code-behind typically will contain

  • ObservableCollection<string> Options
  • string SelectedOption
  • and I will use this style for the 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>
    

    The style is applied like this:

    <ListBox ItemsSource="{Binding Options}"
             SelectedValue="{Binding SelectedOption}"
             Style="{StaticResource RadioButtonListBoxStyle}" />
    

    You can also use something else instead of a String for the collection, such as a ChildViewModel , then set your related View based on the current item, which means you don't have to bother with the Visibility of the associated panel in your ViewModel either.

    <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>
    

    But as for your actual problem, I can think of 3 reasons it might be behaving incorrectly.

    The first is outlined in Jay's answer: you are setting IsChecked2 to false in your setter for IsChecked1 , and IsChecked2 sets IsChecked1 to false in its setter, so the end result is both values are false.

    The second is it might be a problem with your converter. You said it a comment it was working correctly without the converter, so I think that may be part of the problem.

    And last of all, I believe changing grouped RadioButtons will trigger an IsOptionA.IsSelected = false for the old item and an IsOptionB.IsSelected = true for the newly selected item, and its possible those two are getting crossed somewhere.


    A couple of issues here.

  • You don't need a converter. Make IsRadioButton1 and IsRadioButton2 properties of type bool? , and the TwoWay Binding will suffice, or just leave it as bool if tri-state is not applicable for you.
  • The logic in your setters appears to be incorrect. In both cases, you are setting the value of the other RadioButton to false , so if IsRadioButton1 is true and you then set IsRadioButton2 to true , the setter will call IsRadioButton = false , and then that setter will call IsRadioButton2 = false . They will both end up being false .
  • You probably want this to read if(value) IsRadioButton2 = false;


    edit

    Actually, as I recall, RadioButton is not meant to be bound to a bool property the way a CheckBox is. I think you bind all of the RadioButton s to one property, and use a Converter with a ConverterParameter to set the property. I'll find an example and post in a minute.


    Okay, here is one solution, using a derived RadioButton class that behaves purely with bindings: http://blogs.msdn.com/b/mthalman/archive/2008/09/04/wpf-data-binding-with-radiobutton.aspx

    Here is a related SO question & answers: MVVM: Binding radio buttons to a view model?

    链接地址: http://www.djcxy.com/p/44666.html

    上一篇: 将设置绑定到一组RadioButton

    下一篇: Radibuttons Ischecked属性在wpf mvvm中不起作用