namespace ScienceProgram
{
public abstract class BaseViewModel : INotifyPropertyChanged
{
#region Usual Boiler-plate stuff for BindableBase
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
#endregion
#region Properties (All scientific parameters and calculations )
public double ParamA { get; set; }
public double ParamB { get; set; }
// ...
// Lots of parameters //
// ...
public double ParamA23 { get; set; }
public double TotalLength()
{
return ParamA + ParamB + ParamA23;
}
// ...
// Lots of other methods
// ...
#endregion
}
}
namespace ScienceProgram
{
public abstract class BaseViewModel : INotifyPropertyChanged
{
// Global Parameter // Shared across ViewModels //
public static ScienceParameters scienceParameters = new ScienceParameters ();
#region Usual Boiler-plate stuff for BindableBase
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
#endregion
}
}
namespace ScienceProgram
{
public class UserInputView1ViewModel : BaseViewModel
{
#region User Input
private double _paramA;
public double ParamA
{
get { return _paramA; }
set
{
_paramA = value;
OnPropertyChanged("ParamA");
// Store Value //
scienceParameters.ParamA = value;
}
}
}
}
#endregion
非常感谢。
答案 0 :(得分:1)
您已经关闭。我看到您正在复制可能会导致维护问题的数据存储的区域。根据您所说的,我认为您不需要拥有BaseViewModel的方法(但是,如果您按照此处的回答进行操作,那么我将向您展示如何使BaseViewModel与其用途相比更加有用)。
如果我的理解正确,您有多个视图,因为您希望用户按“ NEXT”进入下一个导航视图。每个视图都有一个关联的ViewModel。但在幕后,您希望将所有属性收集到一个类实例中。
对我来说,这里的最佳实践是学习MVVM体系结构。 MVVM的主要学习是了解“关注点分离”。主要是,您的数据(即用户的所有输入值,也称为“模型”)与您在UI中提供给它们的Views和ViewModels无关。阅读相关内容,您会更好地掌握这种良好做法。
这就是我要怎么做。
1)创建一个Model类(ScienceParameters.cs),它将保存您希望用户输入的所有属性。示例:
public class ScienceParameters
{
public double ParamA { get; set; }
public double ParamB { get; set; }
// ...
// Lots of parameters //
// ...
public double ParamA23 { get; set; }
public double TotalLength()
{
return ParamA + ParamB + ParamA23;
}
}
然后在提供给用户的每个UI上,向他们显示一个视图和一个关联的ViewModel,使他们可以访问此数据的“查看/获取”或“存储/设置”部分。示例:
public class UserInput1ViewModel: INotifyPropertyChanged
{
public UserInput1ViewModel(ScienceParameters model)
{
this.Model = model;
}
public ScienceParameters Model { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public double ParamA
{
get { return this.Model.ParamA; }
set
{
// Store the user's data directly into the Model, not the ViewModel!
this.Model.ParamA = value;
OnPropertyChanged(nameof(this.ParamA)); // <-- avoid magic words like "ParamA" in quotes, this is bad coding and can cause maintenance issues.
}
}
}
public class UserInput2ViewModel: INotifyPropertyChanged
{
public UserInput2ViewModel(ScienceParameters model)
{
this.Model = model;
}
public ScienceParameters Model { get; private set; }
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
public double ParamB
{
get { return this.Model.ParamB; }
set
{
this.Model.ParamB = value;
OnPropertyChanged(nameof(this.ParamB));
}
}
}
额外功劳:
如果要消除在每个ViewModel中编写PropertyChanged垃圾的重复性,则将其放入BaseViewModel。
public class BaseViewModel : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
然后从您的ViewModels中删除所有那些PropertyChanged行,并使用基来定义每个ViewModel:
public class UserInput1ViewModel: BaseViewModel
{
// ...
}