繁体   English   中英

是否使用ICommand将设置保存到App.Config中?

[英]Saving setting to the App.Config, using an ICommand or not?

我正在玩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);
    }
}

最后,有一个实现ICommand的SaveCommand,目前它基本上是空的。 我已经将命令连接到视图中的按钮。

但是基本上,现在呢? 保存值的最佳方法是什么? 我正在研究的示例太人为了吗?

我建议使用非常有用的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
        });

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM