Написание поддерживаемого метода коммита - PullRequest
2 голосов
/ 21 октября 2009

У меня есть ViewModel, которая инкапсулирует некоторые свойства, которые редактируются в диалоге параметров. На самом деле я не могу сохранить их в настройках, пока они не нажмут кнопку «ОК», что в конечном итоге вызовет «Фиксация» для этой конкретной модели представления.

Единственное свойство в моей ViewModel выглядит так:

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;

Таким образом, нормальная реализация для Commit будет заключаться в следующем:

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

Это не так уж плохо, но причина, по которой мне это не нравится, заключается в том, что если вы добавляете новое свойство, вы должны добавить код для него в двух местах. Я стараюсь избегать этого, когда это возможно.

Сначала я подумал, что мог бы объявить частное событие OnCommit и заставить метод Commit вызывать это событие, и чтобы код для каждого свойства добавил обработчик события для события и сделал запись в настройки там, но я не в любом случае не знаю, как это сделать, не добавляя обработчики событий в конструктор, что не помогает ситуации.

Есть идеи? У кого-нибудь есть элегантный способ сделать то, что я пытаюсь сделать?

РЕДАКТИРОВАТЬ : Спасибо Sixlettervariables за ответ. Я взял эту идею и включил ее в SoapBox Core и открыл исходный код. Проверьте диалог настроек, чтобы увидеть, как он работает.

Ответы [ 2 ]

4 голосов
/ 21 октября 2009

Возможно вести список Action s для выполнения?

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

Затем обновите код Commit, чтобы выполнить цикл действий.

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

    foreach (var commit in commits)
    {
        commit();
    }
}
0 голосов
/ 21 октября 2009

Не могли бы вы использовать отражение, чтобы определить, какими свойствами обладает ваш класс, и пройти через них?

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...