web-dev-qa-db-fra.com

Détermination du radiobutton coché à partir de la zone de groupe dans WPF après MVVM

J'ai un groupbox avec des radiobuttons. Comment puis-je savoir lequel est coché? J'utilise WPF et suivant MVVM.

<GroupBox Name="grpbx_pagerange" Header="Print Range">
    <Grid >
        <RadioButton Name="radbtn_all" Content="All Pages" GroupName="radios_page_range" IsChecked="True"  />
        <RadioButton x:Name="radbtn_curr" Content="Current Page" GroupName="radios_page_range"  />
        <RadioButton Name="radbtn_pages" Content="Page Range" GroupName="radios_page_range" />

        ....

</GroupBox>

À présent, une solution envisageable consistait à lier la propriété IsChecked de chaque composant RadioButton à une propriété de ViewModel, puis à effectuer une autre sorte de logique dans ViewModel pour déterminer le radiobutton sélectionné.

Mais y a-t-il une autre manière élégante?

13
Bhramar

vous pouvez lier RadioButton.Command de Radiobuttons à une commande de votre ViewModel et envoyer un CommandParameter unique pour identifier le bouton qui a appelé la commande dans commandhandler.

<RadioButton Command="{Binding MyCommand}" CommandParameter="Radio1"/>
<RadioButton Command="{Binding MyCommand}" CommandParameter="Radio2"/>
<RadioButton Command="{Binding MyCommand}" CommandParameter="Radio3"/>

dans le gestionnaire de commandes, recherchez le paramètre permettant d'identifier le radiobutton.

Merci

29
Nitin

Vous pouvez créer une variable enum contenant les valeurs des objets RadioButton sous forme de noms (approximativement), puis lier la propriété IsChecked à une propriété du type de cette enum à l'aide de EnumToBoolConverter.

public enum Options
{
    All, Current, Range
}

Puis dans votre modèle de vue ou code derrière:

private Options options = Options.All; // set your default value here

public Options Options
{ 
    get { return options; }
    set { options = value; NotifyPropertyChanged("Options"); }
}

Ajoutez la Converter:

[ValueConversion(typeof(Enum), typeof(bool))]
public class EnumToBoolConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null || parameter == null) return false;
        string enumValue = value.ToString();
        string targetValue = parameter.ToString();
        bool outputValue = enumValue.Equals(targetValue, StringComparison.InvariantCultureIgnoreCase);
        return outputValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null || parameter == null) return null;
        bool useValue = (bool)value;
        string targetValue = parameter.ToString();
        if (useValue) return Enum.Parse(targetType, targetValue);
        return null;
    }
}

Enfin, ajoutez les liaisons dans l'interface utilisateur, en définissant la variable ConverterParameter appropriée:

<RadioButton Content="All Pages" IsChecked="{Binding Options, Converter={
    StaticResource EnumToBoolConverter}, ConverterParameter=All}" />
<RadioButton Content="Current Page" IsChecked="{Binding Options, Converter={
    StaticResource EnumToBoolConverter}, ConverterParameter=Current}" />
<RadioButton Content="Page Range" IsChecked="{Binding Options, Converter={
    StaticResource EnumToBoolConverter}, ConverterParameter=Range}" />

Vous pouvez maintenant savoir ce qui est défini en consultant la variable Options dans votre modèle de vue ou votre code arrière. Vous pourrez également définir la variable RadioButton cochée en définissant la propriété Options.

18
Sheridan

Si vous utilisez la propriété Tag sur les boutons d’options (booléen, entier, chaînes) comme dans son XAML

<StackPanel Orientation="Horizontal" Margin="10,10, 0, 0">
    <RadioButton Name="rP0" Content="Low  " Tag="0" />
    <RadioButton Name="rP1" Content="Normal" Tag="1" IsChecked="True" />
    <RadioButton Name="rP2" Content="Medium" Tag="2" />
    <RadioButton Name="rP3" Content="High" Tag="3" />
</StackPanel>

Ensuite, vous pouvez utiliser la fonction suivante pour obtenir la valeur sélectionnée (bouton)

int priority = SelectedRadioValue<int>(0, rP0, rP1, rP2, rP3);

public T SelectedRadioValue<T>(T defaultValue, params RadioButton[] buttons)
{
    foreach (RadioButton button in buttons)
    {
        if (button.IsChecked == true)
        {
            if (button.Tag is string && typeof(T) != typeof(string))
            {
                string value = (string) button.Tag;
                return (T) Convert.ChangeType(value, typeof(T));
            }

            return (T)button.Tag;
        }
    }

    return defaultValue;
}
1
victor

Il existe un autre moyen MVVM de résoudre ce problème à l'aide de la propriété IsChecked

Voici le XAML

<Page>
<Page.Resources>
<DataTemplate x:Key="ChoiceItemTemplate">
<RadioButton Content="{Binding individualRadioButtonText}"
     IsTabStop="True"
     GroupName="choice"
     IsChecked="{Binding IsChecked, Mode=TwoWay}"/>
 </DataTemplate>
</Page.Resources>


 <StackPanel>
  <TextBlock Text="{Binding ChoiceQuestion}" />
 <ItemsControl  ItemsSource="{Binding ListOfAnswerOptions}"
                ItemTemplate="{StaticResource ChoiceItemTemplate}" />
 </StackPanel>
</Page>

Votre modèle sera quelque chose comme ça

 public class RadioButtonQuestion
 {
    public string ChoiceQuestion { get; set; }
    public string answer { get; set; }
    public List<AnswerOption> ListOfAnswerOptions { get; set; }
 }

 public class AnswerOption
 {
    public string individualRadioButtonText { get; set; }
    public bool IsChecked { get; set; }
 }

ViewModel ressemblera à quelque chose comme ça (La logique de sélection)

RadioButtonQuestion r = new RadioButtonQuestion();
var selectedElement = rbuttonQuestion.answerOptions.FirstOrDefault(c => c.IsChecked);
r.answer = selectedElement.individualRadioButtonText;

Donc, si vous définissez le contexte de données de la vue sur ce modèle de vue. Vous devez être capable de le faire fonctionner.

J'espère que ça aide.

1
HelpMatters