简体   繁体   中英

Click RadioButton and second radioButton doesn't unmark wpf

I have 2 radioButton, when i choose one, I send the name of the role

 <StackPanel Grid.Column="2" Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Top" Margin="0,10,0,0">
        <RadioButton x:Name="UserRadioButton" IsChecked="{Binding AuthRequstModel.IsEndUser, Mode=OneWayToSource}" Content="End User" />
        <RadioButton x:Name="DeveloperRadioButton" IsChecked="{Binding AuthRequstModel.IsAppDeveloper, Mode=OneWayToSource}" Margin="15,0,0,0" Content="App Developer"/>
    </StackPanel>

in view i write the properties,

 public string Role
    {
        get => role;
        private set
        {
            role = value;
            NotifyPropertyChanged("Role");
        }
    }

    public bool IsEndUser
    {
        get => Role == "EndUser";
        set
        {
            Role = "EndUser";
            NotifyPropertyChanged("EndUser");
        }
    }

    public bool IsAppDeveloper
    {
        get => Role == "AppDeveloper";
        set
        {
            Role = "AppDeveloper";
            NotifyPropertyChanged("AppDeveloper");
        }
    }

when i choose end user , role will be and user.

In viewModel I write the property

public AuthRequestModel AuthRequstModel
    {
        get => authRequstModel;
        set => Set(ref authRequstModel, value);
    }

it work okey, i take the right role name, but in UI when i click first it mark, when click second it mark, BUT the first doesn't unmark and it the big problem,

i try all Mode (one time - doesn't send the role, oneway - doesn't send the role, oneWayToSource - send uncorrect role(if i click many time between role, send wrong role)

two ways correct data But UI work uncorrectly problem

How fix that ?

First problem is that IsEndUser and IsAppDeveloper setters fired also when the value changed to false. so If you do click On "End User" radiobutton this will fire two setters:

  1. IsEndUser with value true
  2. IsAppDeveloper with value false

IsAppDeveloper will be fired second so on UI it will be ok but in data Role will be set to "AppDeveloper" ( remember you clicked on EndUser );

Second you have a typo when you notify property change, instead of:

NotifyPropertyChanged("EndUser");

should be

NotifyPropertyChanged("IsEndUser");

the same typo with AppDeveloper

You need to check for value to be true before changing Role property and to fix a typo when calling NotifyPropertyChanged:

   public bool IsEndUser
    {
        get => Role == "EndUser";
        set
        {
            if(value)
              Role = "EndUser";
            NotifyPropertyChanged("IsEndUser");
        }
    }

    public bool IsAppDeveloper
    {
        get => Role == "AppDeveloper";
        set
        {
            if(value)
               Role = "AppDeveloper";
            NotifyPropertyChanged("IsAppDeveloper");
        }

Below is additional answer that you may not need.

A better solution may be to use an enum and enum to boolean converter.

For example:

EnumToBooleanConverter class:

public class EnumToBooleanConverter : IValueConverter
{

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string parameterString = parameter as string;
        if (parameterString == null || value == null)
            return DependencyProperty.UnsetValue;

        if (Enum.IsDefined(value.GetType(), value) == false)
            return DependencyProperty.UnsetValue;

        object parameterValue = Enum.Parse(value.GetType(), parameterString);

        return parameterValue.Equals(value);
    }

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        string parameterString = parameter as string;
        if (parameterString == null)
            return DependencyProperty.UnsetValue;

        var enumTargetType = targetType;

        if (targetType.IsGenericType && targetType.GetGenericTypeDefinition() == typeof(Nullable<>))
        {
            enumTargetType = targetType.GetGenericArguments().First();
        }

        return Enum.Parse(enumTargetType, parameterString);
    }

}

An enum:

public enum Role { EndUser, AppDeveloper }

Change in xaml:

<StackPanel Grid.Column="2" Grid.Row="1" Orientation="Horizontal" VerticalAlignment="Top" Margin="0,10,0,0">
    <RadioButton IsChecked="{Binding Path=AuthRequstModel.Role, Converter={StaticResource enumBooleanConverter}, ConverterParameter=EndUser}" Content="End User" />
    <RadioButton IsChecked="{Binding Path=AuthRequstModel.Role, Converter={StaticResource enumBooleanConverter}, ConverterParameter=AppDeveloper}" Margin="15,0,0,0" Content="App Developer"/>
</StackPanel>

Change in view model:

private Role role;
public Role Role
    {
        get => role;
        set
        {
            role = value;
            NotifyPropertyChanged("Role");
        }
    }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM