开发者

Writing a maintainable commit method

I have a ViewModel that encapsulates some properties that are being edited in an options dialog. I can't actually save them to the settings until they hit the Ok button, which will end up calling Commit on this particular ViewModel.

A single property in my ViewModel looks like this:

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;

So the normal implementation for Commit would be to do this:

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

This isn't so bad, but the reason I don't like this is that if you add a new property, you have to add code for it in two places. I try to avoid that when possible.

At first I thought I could declare a private event called OnCommit and have the Commit method raise that event, and have the code for each property add an event handler for the event and do the writing to 开发者_高级运维the settings there, but I don't know how to do that without adding the event handlers in the constructor anyway, which doesn't help the situation.

Any ideas? Does anyone have an elegant way to do what I'm trying to do?

EDIT: Thanks to sixlettervariables for the answer. I took that idea and incorporated it into SoapBox Core and open sourced the result. Check out the Options Dialog to see how it works.


Perhaps maintain a list of Actions to execute?

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

Then update your Commit code to loop through the actions.

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

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


Could you use reflection to determine which properties your class has and iterate through them?

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜