是否使用ICommand将设置保存到App.Config
本文关键字:保存 App Config 设置 ICommand 是否 | 更新日期: 2023-09-27 18:28:42
我在玩MVVM,了解模式中涉及的内容。我正在编写的第一个应用程序是一个非常小的应用程序,它基本上显示来自App.Config.的2个设置
我的目标是能够在单击按钮时写入此app.config。
我的问题在于,我不知道如何连接一个命令来将这项工作委托给它,或者这是否是正确的方法。
我的App.config非常直接:
<configuration>
<appSettings>
<add key="duration" value="100" />
<add key="operators" value="10" />
</appSettings>
</configuration>
模型看起来像:
get
{
// try to parse the setting from the configuration file
// if it fails return the default setting 0
int durationSetting = 0;
Int32.TryParse(ConfigurationManager.AppSettings["duration"], out durationSetting);
return durationSetting;
}
set
{
var config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.AppSettings.Settings.Remove("duration");
config.AppSettings.Settings.Add("duration", Convert.ToString(value));
ConfigurationManager.RefreshSection("appSettings");
config.Save();
}
}
所以,模型负责实际的数据访问,这就是我们想要的,对吧?
此外,我有一个ViewModel(ViewModelBase实现INotifyPropertyChanged):
public class SettingsViewModel : ViewModelBase
{
private Settings Settings { get; set; }
private SaveCommand saveCommand = new SaveCommand();
public ICommand SaveCommand
{
get
{
return saveCommand;
}
}
public SettingsViewModel(Settings settings)
{
if (settings == null)
throw new ArgumentNullException("Settings", "Settings cannot be null");
Settings = settings;
}
public int Duration
{
get { return Settings.Duration; }
set
{
if (Settings.Duration != value)
{
Settings.Duration = value;
RaisePropertyChanged("Duration");
}
}
}
该视图是一个xaml用户控件,实例化如下:
public partial class MainWindow : Window
{
public SettingsViewModel SettingsViewModel { get; set; }
public MainWindow()
{
InitializeComponent();
DataContext = this;
Settings settings = new Settings();
SettingsViewModel = new SettingsViewModel(settings);
}
}
最后还有一个SaveCommand,它实现了ICommand,在这一点上它基本上是空的。我已将命令连接到视图中的一个按钮。
但基本上,现在呢?处理保存值的最佳方法是什么?我正在做的这个例子太做作了吗?
我建议使用非常有用的MVVM Light工具包。
基本上,您将公开一个ICommand
公共属性,该属性返回RelayCommand
:的实例
private RelayCommand myCommand;
public ICommand MyCommand
{
get
{
return this.myCommand;
}
}
...
// in constructor of the view model:
this.myCommand = new RelayCommand(this.MyCommandImplementation);
...
private void MyCommandImplementation()
{
// Save your parameters here from your model
}
代码中的奇怪之处在于,您实际上已经将设置保存在名为Duration
的公共属性的setter中。相反,您可以做的(防止每次修改属性时保存)是简单地在ViewModel中使用一个私有变量:
private int duration;
public int Duration
{
get { return this.duration; }
set
{
if (this.duration != value)
{
this.duration = value;
RaisePropertyChanged("Duration");
}
}
}
因此,当您修改绑定到Duration
属性的UI字段时,您只更新私有duration
字段。因此,您只能将其保存到MyCommandImplementation
方法中的app.config文件中。
private void MyCommandImplementation()
{
this.Settings.Duration = this.Duration;
}
还要注意,您的Settings
管理有点复杂(您删除了设置,然后又添加了设置,为什么?)。最后一件事:在您的视图中,您当前正在使用视图本身作为数据上下文。您必须指定您的ViewModel:
this.SettingsViewModel = new SettingsViewModel(settings);
this.DataContext = this.SettingsViewModel;
此外,我不认为实例化您的模型是您的视图的职责。我会从ViewModel中实例化Settings
。
您所需要做的就是在类中实现ICommand接口,并将SaveCommand属性设置为此类的实例。您可以使用一些第三方命令类,如棱镜库的DelegateCommand或RelayCommand。有关ICommand的示例实现,请参阅以下网页;http://weblogs.asp.net/fredriknormen/archive/2010/01/03/silverlight-4-make-commanding-use-lesser-code.aspx
则将要采取的行动应登记在命令中;
this.SaveCommand= new SaveCommand((o) =>
{
//change the model
});