web-dev-qa-db-fra.com

Boutons radio MVVM

Quelqu'un aide s'il vous plaît. J'ai un problème intéressant. J'essaie de mettre en œuvre une application MVVM et je souhaite me lier aux boutons radio, à mon avis. 

Voici mon point de vue:

<StackPanel Orientation="Horizontal" Grid.ColumnSpan="2"  >
    <RadioButton GroupName="1" IsChecked="{Binding Path=NoteGeneral, Mode=TwoWay}">General</RadioButton>
    <RadioButton GroupName="1" IsChecked="{Binding Path=NoteContact, Mode=TwoWay}" >Contact</RadioButton>
    <RadioButton GroupName="1" IsChecked="{Binding Path=NoteAddress, Mode=TwoWay}" >Address</RadioButton>
    <RadioButton GroupName="1" IsChecked="{Binding Path=NotePhone, Mode=TwoWay}" >Phone</RadioButton>
</StackPanel>

Voici mon ViewModel:

    bool _NoteGeneral;
    public bool NoteGeneral
    {
        get { return _NoteGeneral; }
        set
        {
            _NoteGeneral = value;
            OnPropertyChanged("NoteGeneral");
        }
    }

    bool _NoteContact;
    public bool NoteContact
    {
        get { return _NoteContact; }
        set
        {
            _NoteContact = value;
            OnPropertyChanged("NoteContact");
        }
    }

    bool _NoteAddress;
    public bool NoteAddress
    {
        get { return _NoteAddress; }
        set
        {
            _NoteAddress = value;
            OnPropertyChanged("NoteAddress");
        }
    }

    bool _NotePhone;
    public bool NotePhone
    {
        get { return _NotePhone; }
        set
        {
            _NotePhone = value;
            OnPropertyChanged("NotePhone");
        }
    }

Le problème est le suivant: lorsque je clique sur les différents boutons radio, le configurateur de propriétés n’est appelé que la première fois (lorsque j’exécute via le débogage). par exemple. Lorsque je clique sur NoteGeneral, NoteContact, puis à nouveau NoteGeneral, seuls les deux premiers clics mettent à jour mon modèle de vue. Je pense que quelque chose ne va pas avec ma reliure, ou peut-être que je l'aborde de manière totalement fausse. 

Quelqu'un peut-il aider?

Comment dois-je implémenter les sélections de radiobutton dans mon modèle de vue?

.NET 4 et versions ultérieures

Ce problème de liaison à RadioButton a été résolu par Microsoft lors de la publication de .NET 4. La reliure de RadioButtons fonctionne maintenant comme vous le souhaiteriez, sans aucune des solutions de contournement répertoriées ci-dessous.

38
Jose

Jetez un oeil ici

Je n'ai pas implémenté la solution fournie mais c'est logique. Le contrôle de structure sous-jacent rompt vos liaisons lorsqu'un clic est effectué. La solution consiste à remplacer la méthode qui le fait et à ne compter que sur les liaisons.

18
Jab

Jaime Rodriguez , qui travaille chez Microsoft sur WPF, publie un Q & A non abrégé sur WPF, et le dernier numéro contient un article sur RadioButtons et MVVM!

Le message se trouve à http://blogs.msdn.com/jaimer/archive/2009/09/22/wpf-discussion-090922.aspx et vous souhaitez consulter le dernier élément de ce message. J'ai testé la solution et cela fonctionne à ma satisfaction.

Cité pour plus de commodité:

J'ai travaillé sur ce problème dans .NET 3.5 SP1. Voici comment je lie les données d'un groupe de boutons radio à une propriété énumérée:

<StackPanel>
    <RadioButton Content="New folder"
        IsChecked="{Binding Path=PublishTarget,
                    Converter={StaticResource equalityConverter},
                    ConverterParameter={x:Static local:PublishTarget.NewServerFolder}, Mode=TwoWay}"
        GroupName="1" />

    <RadioButton Content="Existing folder"
        IsChecked="{Binding Path=PublishTarget,
                    Converter={StaticResource equalityConverter},
                    ConverterParameter={x:Static local:PublishTarget.ExistingServerFolder},
                    Mode=TwoWay}"
        GroupName="2" />

    <RadioButton Content="Local folder"
        IsChecked="{Binding Path=PublishTarget,
                    Converter={StaticResource equalityConverter},
                    ConverterParameter={x:Static local:PublishTarget.LocalFolder},
                    Mode=TwoWay}"
        GroupName="3" />
</StackPanel>

Définir le nom de groupe de chaque bouton radio sur une valeur unique empêche les liaisons d’être obstruées lorsque l’utilisateur clique sur un bouton radio. Ici, je compte sur la source de données pour implémenter INotifyPropertyChanged, qui indiquera aux autres boutons radio de se mettre à jour. Une approche similaire devrait fonctionner pour les boutons radio d'un ItemsControl.

15
Thomas Dufour

J'ai écrit un conseil simple pour ce problème sur mon blog.

Dans ce cas, vous devez écrire les vues View et ViewModel comme suit:

<StackPanel Orientation="Horizontal" Grid.ColumnSpan="2">
    <RadioButton IsChecked="{Binding IsGeneralNote}">General</RadioButton>
    <RadioButton IsChecked="{Binding IsContactNote}">Contact</RadioButton>
    <RadioButton IsChecked="{Binding IsAddressNote}">Address</RadioButton>
    <RadioButton IsChecked="{Binding IsPhoneNote}">Phone</RadioButton>
</StackPanel>


public enum Note
{
    General,
    Contact,
    Address,
    Phone,
}

...

    Note note = Note.General;

    public Note Note
    {
        get { return this.note; }
        set
        {
            if (this.note == value)
                return;

            this.note = value;
            OnPropertyChanged("Note");
            OnPropertyChanged("IsGeneralNote");
            OnPropertyChanged("IsContactNote");
            OnPropertyChanged("IsAddressNote");
            OnPropertyChanged("IsPhoneNote");
        }
    }

    public bool IsGeneralNote
    {
        get { return Note == Note.General; }
        set { Note = value ? Note.General : Note; }
    }

    public bool IsContactNote
    {
        get { return Note == Note.Contact; }
        set { Note = value ? Note.Contact : Note; }
    }

    public bool IsAddressNote
    {
        get { return Note == Note.Address; }
        set { Note = value ? Note.Address : Note; }
    }

    public bool IsPhoneNote
    {
        get { return Note == Note.Phone; }
        set { Note = value ? Note.Phone : Note; }
    }
...
8
Ryeol

vous devez définir UpdateSourceTrigger = "PropertyChanged" à la liaison XAML comme

 <StackPanel Grid.Column="1" Grid.Row="0" Orientation="Horizontal" HorizontalAlignment="Left" VerticalAlignment="Center">
            <RadioButton Name="rdbTimeFormat12" GroupName="TimeFormat" Content="12 Hrs" IsChecked="{Binding Radio1IsCheck,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
            <RadioButton Name="rdbTimeFormat24" GroupName="TimeFormat" Margin="40,0,0,0" Content="24 Hrs" IsChecked="{Binding Radio2IsCheck,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"/>
        </StackPanel>
0
Vijay Chauhan