我有一个ViewModel,它封装了一些在选项对话框中编辑的属性。我实际上无法将它们保存到设置中,直到它们点击Ok按钮,这将最终在此特定ViewModel上调用Commit。
我的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方法引发该事件,并让每个属性的代码为事件添加一个事件处理程序并在那里写入设置,但我不知道不知道如何在构造函数中添加事件处理程序时如何做到这一点,这对情况没有帮助。
有什么想法吗?有没有人有一种优雅的方式去做我想做的事情?
编辑:感谢sixlettervarariables的答案。我接受了这个想法并将其合并到SoapBox Core并开源了结果。查看选项对话框以了解其工作原理。
答案 0 :(得分:4)
也许维护一个要执行的Action
列表?
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();
}
}
答案 1 :(得分:0)
您是否可以使用反射来确定您的类具有哪些属性并通过它们进行迭代?