Вопрос

У меня есть 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 и открыл исходный код. Проверьте диалог настроек, чтобы увидеть, как он работает.

Это было полезно?

Решение

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

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

Другие советы

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top