Question

J'ai un ViewModel qui encapsule certaines propriétés en cours de modification dans une boîte de dialogue d'options. Je ne peux pas les enregistrer dans les paramètres tant qu’ils n’auront pas appuyé sur le bouton Ok, ce qui entraînera l’appel de validation sur ce ViewModel particulier.

Une propriété unique dans mon ViewModel ressemble à ceci:

public bool SomeProperty
{
    get
    {
        return m_SomeProperty;
    }
    set
    {
        if (m_SomeProperty != value)
        {
            m_SomeProperty = value;
            NotifyPropertyChanged("SomeProperty");
        }
    }
}
private bool m_SomeProperty = Properties.Settings.Default.SomeProperty;

Donc, l'implémentation normale de Commit serait de faire ceci:

public void Commit()
{
    Properties.Settings.Default.SomeProperty = m_SomeProperty;
    // Add other properties here...
}

Ce n'est pas si grave, mais la raison pour laquelle je n'aime pas cela, c'est que si vous ajoutez une nouvelle propriété, vous devez ajouter du code correspondant à deux endroits. J'essaie d'éviter cela quand c'est possible.

Au début, je pensais pouvoir déclarer un événement privé appelé OnCommit et demander à la méthode Commit de générer cet événement et de faire en sorte que le code de chaque propriété ajoute un gestionnaire d'événement pour cet événement et effectue l'écriture dans les paramètres. Je ne sais pas comment faire cela sans ajouter les gestionnaires d’événements dans le constructeur, ce qui n’aide en rien la situation.

Des idées? Quelqu'un a-t-il un moyen élégant de faire ce que j'essaie de faire?

MODIFIER : Merci à sixlettervariables pour la réponse. Je me suis inspiré de cette idée pour l’intégrer à SoapBox Core et l’utiliser à la source pour obtenir le résultat. Consultez la boîte de dialogue Options pour voir comment cela fonctionne.

Était-ce utile?

La solution

Peut-être maintenir une liste des actions à exécuter?

private List<Action> commitActions = new List<Action>();

public bool SomeProperty
{
    get
    {
        return m_SomeProperty;
    }
    set
    {
        if (m_SomeProperty != value)
        {
            m_SomeProperty = value;
            lock (commitActions)
            {
                commitActions.Add(
                    () => Properties.Settings.Default.SomeProperty = value);
            }
            NotifyPropertyChanged("SomeProperty");
        }
    }
}

Mettez ensuite à jour votre code Commit pour parcourir les actions.

public void Commit()
{
    List<Action> commits;
    lock (commitActions)
    {
        commits = new List<Action>(commitActions);
        commitActions.Clear();
    }

    foreach (var commit in commits)
    {
        commit();
    }
}

Autres conseils

Pourriez-vous utiliser la réflexion pour déterminer les propriétés de votre classe et les parcourir?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top