locked
[WP8.1]RadioButtons binding on Windows Phone 8.1 RRS feed

  • Question

  • Hi. I have some problem with binding my RadioButton property IsChecked. I have two RadioButton's on the grid, which Visibility binded to a property on my viewmodel. What i want to achieve is to always setting first RadioButton to Checked state, when grid is become visible. After some time spended on this problem and good advice from StackOverflow i found a solution for my problem and it working now as designed.

    Problem is this solution is strange and i dont know how it works. Here i made simple sample for demonstrating this issue(link to OneDrive - http://1drv.ms/1cN2Bay).

    As i am imagine how it should work: when i am pressed the button, its changing value of State property and Grid with RadioButtons became visible and through EnumToBooleanConverter first RadioButton became Checked. Then when i check second RadioButton and press Back it should set both buttons to Unchecked state. And when my Grid with RadioButtons will became visible again first will be checked.

    But on practice this is don't working and if i check second RadioButton binding to IsChecked corrupting and dont working anymore. To workaround this i should set Mode=TwoWay to the binding of IsChecked property of my RadioButton. Then if i check second RadioButton fires ConvertBack(which don't changing my property on ViewModel) and binding continues working.

    So why i should set Mode=TwoWay in my binding if Convertback in fact do nothing?

    P.S. Working steps in sample:

    1. Press Show radio buttons.

    2. First radio button should be checked.

    3. Check second radio button.

    4. Press Back(hardware button).

    5. Repeat step 1. First radio button should be checked always, when grid became visible.

    Thursday, June 11, 2015 10:32 AM

Answers

  • In the ConvertBack of your EnumToBoolConverter you must check the value and only convert to your enum if the value is true.

        public object ConvertBack(object value, Type targetType, object parameter, string culture)
            {
                if (value == null) return null;
                if (parameter == null) return null;
    
                bool isChecked = (bool)value;
                if (isChecked)
                    return Enum.Parse(typeof(PageState), parameter.ToString(), false);
    
                return parameter.Equals(value.ToString());
            }

    The mode of the binding of your RadioButtons must be set to TwoWay to allow the values to go back to your view model. This is the case for both of your RadioButtons

    You should group your RadioButtons together using the Group property. 

    <RadioButton Group="StateGroup" />
    The group property is what tells other RadioButtons to uncheck if another is checked. so set this on all of your RadioButtons that bind to the same property


    • Edited by skendrotMVP Thursday, June 11, 2015 7:53 PM add reason for Group property
    • Marked as answer by Danil_Kachanov Monday, June 22, 2015 1:05 PM
    Thursday, June 11, 2015 7:51 PM

All replies

  • I'm not sure if I missed something, but that solution seems very complicated to me.

    I would bind the visibility of the grid to a propfull in the viewmodel.

    Also bind the IsChecked of the radiobutton to a property in the viewmodel.

    Set that checked property when the grid becomes visible.

    Missing out inotifypropertychanged etc  for clarity:

            private Visibility gridVisibility;
    
            public Visibility GridVisibility
            {
                get { return gridVisibility; }
                set 
                { 
                    gridVisibility = value;
                    if (gridVisibility == Visibility.Visible)
                        IsRadio1Checked = true;
                }
            }
            public bool IsRadio1Checked { get; set; }

    That way as the grid becomes visible, the radio button with IsChecked bound to IsRadioChecked becomes checked.

    ( When you implement INPC, make the binding twoway etc etc.)

    You can also probably lose your visbilityconverter and set GridVisibility from a propfull for state.


    Hope that helps.

    Technet articles: WPF: Change Tracking; All my Technet Articles

    Thursday, June 11, 2015 11:06 AM
  • You are right, but i have already one property on the viewmodel for this goal and i dont want to create another one property for so minor task, especially when i can do it without it. My viewmodel is already very big and complicated and i dont want do it worst.

    And any way this bug(?) in platform should be fixed, if it is really bug.


    Thursday, June 11, 2015 2:38 PM
  • I think that code in your viewmodel + converter would be simplified by replacing it with the one property you add.

    .

    As it is, I don't think it's a WinRT bug,

    You might indeed need twoway on those bindings.

    Some properties default to oneway, some to twoway.

    OneWay is view to viewmodel. ( This is a simplification but true for this markup ).

    Twoway makes changes in the viewmodel propagate to the view.

    If you don't mark a binding twoway when it defaults as oneway then you can change the viewmodel property and raise property changed but the view won't read it.

    You also need the convertback for when you change data in the view.

    Convert is Source to Target.

    ConvertBack is Target to Source.

    Target is the property you have the binding on in the view.

    Source is the property in your viewmodel which is bound. (In this case).

    This is quite well explained in the WPF docs:

    https://msdn.microsoft.com/en-us/library/ms752347(v=vs.110).aspx

    There's probably a uwa equivalent somewhere but I can't find it and it's the same anyhow.


    Hope that helps.

    Technet articles: WPF: Change Tracking; All my Technet Articles


    • Edited by Andy ONeill Thursday, June 11, 2015 3:30 PM
    Thursday, June 11, 2015 3:30 PM
  • Andy, You have OneWay and TwoWay backwards.

    • OneWay: Default. Allows changes from the source (ViewModel) to change the target (View). Changes from the target (view) will not go back to the source (ViewModel)
    • TwoWay : Not default. Allows changes from target to change the source and changes to the source to change the target

    When you want changes to go back to your DataContext/ViewModel (source) you have to set mode to TwoWay

    Thursday, June 11, 2015 7:47 PM
  • In the ConvertBack of your EnumToBoolConverter you must check the value and only convert to your enum if the value is true.

        public object ConvertBack(object value, Type targetType, object parameter, string culture)
            {
                if (value == null) return null;
                if (parameter == null) return null;
    
                bool isChecked = (bool)value;
                if (isChecked)
                    return Enum.Parse(typeof(PageState), parameter.ToString(), false);
    
                return parameter.Equals(value.ToString());
            }

    The mode of the binding of your RadioButtons must be set to TwoWay to allow the values to go back to your view model. This is the case for both of your RadioButtons

    You should group your RadioButtons together using the Group property. 

    <RadioButton Group="StateGroup" />
    The group property is what tells other RadioButtons to uncheck if another is checked. so set this on all of your RadioButtons that bind to the same property


    • Edited by skendrotMVP Thursday, June 11, 2015 7:53 PM add reason for Group property
    • Marked as answer by Danil_Kachanov Monday, June 22, 2015 1:05 PM
    Thursday, June 11, 2015 7:51 PM