我正试图使用MVVM模式。我有一个Model和一个ViewModel,我们叫它们ModelA和ViewModelA:
模型
public ObservableCollection<RVTLinkWrapper> CollectRVTLinks()
{
var revitLinkInstances = new FilteredElementCollector(Doc)
.OfClass(typeof(RevitLinkInstance))
.WhereElementIsNotElementType()
.Cast<RevitLinkInstance>()
.Select(x => new RVTLinkWrapper(x));
return new ObservableCollection<RVTLinkWrapper>(revitLinkInstances);
}
ViewModelA
private ObservableCollection<RVTLinkWrapper> rvtLinks;
public ObservableCollection<RVTLinkWrapper> RVTLinks { get; set; }
public ViewModelA(ModelA model)
{
Model = model;
RVTLinks = Model.CollectRVTLinks();
}
ViewModelA构造函数从模型调用CollectRVTLinks,创建RVTLinks。我以后在我的A型(在我的MVVM中)内获得RVTLinks是否可以,如果是,如何正确地做?
在这种情况下,我应该如何在模型和ViewModel之间交换数据?
我不确定这是你想要的,但这里有一些通用的mvvm建议。
根据我的经验,你发布的代码是一个坏主意。
视图、视图模型和模型之间应该具有最小的具体依赖关系,因为您可以合理地管理它们。该模型通常来自基于rest的web服务。
其他的选择是可用的,但我建议automapper将数据从一个模型传输到视图模型,然后再返回。
获取一个dto类,使用automapper将其数据复制到一个新的视图模型实例中。
要提交更改吗?使用automapper将视图模型数据复制到模型dto的新实例中。将dto传递给服务更新数据库或其他。
这减少了类的责任。视图模型使数据适应于视图。不需要"知道"关于你父亲的任何事。dto是纯粹的dto。自适应逻辑进入自动配置器配置。如果你需要调整你的视图和视图模型,那么也许只有它们会改变。如果模型被其他应用程序共享并更改,则限制视图和视图模型的更改。
同样,如果你正在编辑一些东西,那么你已经设置了首先使用automapper将你的视图模型深度克隆到一个新的实例。如果验证失败,您可以将该副本删除,而原始数据仍然可以。
您有多个选择。我不完全确定你对这个问题的意图是什么,但这里有一些大致的想法:
选项1 -让集合驻留在模型中
ModelA.cs
public ObservableCollection<RVTLinkWrapper> RVTLinks { get; } = new();
public void Add(RVTLinkWrapper item)
{
RVTLinks.Add(item);
}
public void CollectRVTLinks()
{
var revitLinkInstances = new FilteredElementCollector(Doc)
.OfClass(typeof(RevitLinkInstance))
.WhereElementIsNotElementType()
.Cast<RevitLinkInstance>()
.Select(x => new RVTLinkWrapper(x));
RVTLinks.Clear();
foreach(var item in revitLinkInstances)
{
RVTLinks.Add(item);
}
}
ViewModelA.cs
public ViewModelA(ModelA model)
{
Model = model;
Model.CollectRVTLinks();
}
ViewA.xaml
< ... ItemsSource="{Binding Model.RVTLinks}"> ...
在应用程序后面
//add a new item
Model.AddRVTLink(rvtLink);
//reload collection
Model.CollectRVTLinks();
选项2 -在更改时重新加载集合
ModelA.cs
public IEnumerable<RVTLinkWrapper> CollectRVTLinks()
{
var revitLinkInstances = new FilteredElementCollector(Doc)
.OfClass(typeof(RevitLinkInstance))
.WhereElementIsNotElementType()
.Cast<RevitLinkInstance>()
.Select(x => new RVTLinkWrapper(x));
return revitLinkInstances;
}
ViewModelA.cs
public ObservableCollection<RVTLinkWrapper> RVTLinks { get; } = new();
public ViewModelA(ModelA model)
{
Model = model;
var revitLinkInstances = Model.CollectRVTLinks();
UpdateLinks(revitLinkInstances);
}
private void UpdateLinks(IEnumerable<RVTLinkWrapper> revitLinkInstances)
{
RVTLinks.Clear();
foreach(var item in revitLinkInstances)
{
RVTLinks.Add(item);
}
}
ViewA.xaml
< ... ItemsSource="{Binding Model.RVTLinks}"> ...
在应用程序后面
//reload collection when something changes
var revitLinkInstances = Model.CollectRVTLinks();
UpdateLinks(revitLinkInstances);