Pergunta

Eu tenho um ViewModel que encapsula algumas propriedades que estão sendo editados em um diálogo de opções. Eu não pode realmente salvar-lhes as configurações até que atingiu o botão Ok, o que vai acabar chamando Commit neste ViewModel particular.

A única propriedade em minha aparência ViewModel como esta:

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;

Assim, a implementação normal para Commit seria fazer isso:

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

Isto não é tão ruim, mas a razão pela qual eu não gosto disso é que se você adicionar uma nova propriedade, você tem que adicionar código para ele em dois lugares. Eu tento evitar que, quando possível.

No começo eu pensei que eu poderia declarar um evento privado chamado OnCommit e ter a Commit raise método esse evento, e tem o código para cada propriedade adicionar um manipulador de eventos para o evento e fazer a escrita para as configurações de lá, mas eu don 't sabe como fazer isso sem adicionar os manipuladores de eventos no construtor de qualquer maneira, o que não ajuda a situação.

Todas as idéias? Alguém tem uma maneira elegante de fazer o que estou tentando fazer?

Editar : Graças a sixlettervariables para a resposta. Tomei essa idéia e incorporou em SoapBox Núcleo e código aberto o resultado. Confira o diálogo Opções para ver como ele funciona.

Foi útil?

Solução

Talvez manter uma lista de Actions para executar?

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");
        }
    }
}

Em seguida, atualize o seu código Commit para percorrer as ações.

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

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

Outras dicas

Você poderia usar o reflexo para determinar quais propriedades de sua classe tem e iterate através deles?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top