如果存储库在视图模型中是不行的,如何保存绑定到 ViewModel 的 DetailView 中的数据?
我们 mvvm 爱好者都知道 Josh Smith mvvm 示例以及他如何通过将存储库对象注入到 customerViewModel 的构造函数中来将客户保存在详细客户视图中。
但视图模型不应该了解存储库。它只是一个视图模型,没有什么必须知道持久性等...
如果它在代码隐藏中设置,我如何在 DocumentViewModel 上注册我的 Action 委托 SaveDocumentDelegate?实际上,我应该在 DocumentController 中订阅委托,但是如何在 DocumentController 中实例化 DocumentView 并将其设置为 Datacontext,而不是在代码隐藏中执行此操作。我唯一想到的是在窗口中使用内容控件,并将其与文档用户控件绑定到 viewModel 和数据模板的类型,如下所示:
<UserControl.Resources>
<DataTemplate DataType="{x:Type ViewModel:DocumentViewModel}">
<View:DocumentDetailView/>
</DataTemplate>
</UserControl.Resources>
<ContentControl Content="{Binding MyDocumentViewModel}" />
但我不想使用控件来解决我的体系结构问题...
xaml:(查看第一种方法)
public partial class DocumentDetailView : UserControl
{
public DocumentDetailView()
{
InitializeComponent();
this.DataContext = new DocumentViewModel(new Document());
}
}
DocumentViewModel:
public class DocumentViewModel : ViewModelBase
{
private Document _document;
private RelayCommand _saveDocumentCommand;
private Action<Document> SaveDocumentDelegate;
public DocumentViewModel(Document document)
{
_document = document;
}
public RelayCommand SaveDocumentCommand
{
get { return _saveDocumentCommand ?? (_saveDocumentCommand = new RelayCommand(() => SaveDocument())); }
}
private void SaveDocument()
{
SaveDocumentDelegate(_document);
}
public int Id
{
get { return _document.Id; }
set
{
if (_document.Id == value)
return;
_document.Id = value;
this.RaisePropertyChanged("Id");
}
}
public string Name
{
get { return _document.Name; }
set
{
if (_document.Name == value)
return;
_document.Name = value;
this.RaisePropertyChanged("Name");
}
}
public string Tags
{
get { return _document.Tags; }
set
{
if (_document.Tags == value)
return;
_document.Tags = value;
this.RaisePropertyChanged("Tags");
}
}
}
更新:
public class DocumentController
{
public DocumentController()
{
var win2 = new Window2();
var doc = new DocumentViewModel(new DocumentPage());
doc.AddDocumentDelegate += new Action<Document>(OnAddDocument);
win2.DataContext = doc;
wind2.ShowDialog();
}
private void OnAddDocument(Document doc)
{
_repository.AddDocument(doc);
}
}
您对此想法有何看法?
we mvvm lovers all know Josh Smith mvvm sample and how he has saved the customer in the detail customer view by injecting the repository object into the customerViewModel`s constructor.
But a viewmodel should not know about repositories. Its just a model of a view nothing must being aware of persistence etc...
How can I register my Action delegate SaveDocumentDelegate on the DocumentViewModel if its set in the code-behind? Actually I should subscribe the delegate in my DocumentController but how can I instantiate the DocumentView in my DocumentController and set it as Datacontext not doing that in code-behind. Only thing that came to my mind is using a contentcontrol in the window and bind it to the type of the viewModel and datatemplate it with the Document UserControl like this:
<UserControl.Resources>
<DataTemplate DataType="{x:Type ViewModel:DocumentViewModel}">
<View:DocumentDetailView/>
</DataTemplate>
</UserControl.Resources>
<ContentControl Content="{Binding MyDocumentViewModel}" />
But I do not want to use a control to solve my architectural problems...
xaml:(view first approach)
public partial class DocumentDetailView : UserControl
{
public DocumentDetailView()
{
InitializeComponent();
this.DataContext = new DocumentViewModel(new Document());
}
}
DocumentViewModel:
public class DocumentViewModel : ViewModelBase
{
private Document _document;
private RelayCommand _saveDocumentCommand;
private Action<Document> SaveDocumentDelegate;
public DocumentViewModel(Document document)
{
_document = document;
}
public RelayCommand SaveDocumentCommand
{
get { return _saveDocumentCommand ?? (_saveDocumentCommand = new RelayCommand(() => SaveDocument())); }
}
private void SaveDocument()
{
SaveDocumentDelegate(_document);
}
public int Id
{
get { return _document.Id; }
set
{
if (_document.Id == value)
return;
_document.Id = value;
this.RaisePropertyChanged("Id");
}
}
public string Name
{
get { return _document.Name; }
set
{
if (_document.Name == value)
return;
_document.Name = value;
this.RaisePropertyChanged("Name");
}
}
public string Tags
{
get { return _document.Tags; }
set
{
if (_document.Tags == value)
return;
_document.Tags = value;
this.RaisePropertyChanged("Tags");
}
}
}
UPDATE:
public class DocumentController
{
public DocumentController()
{
var win2 = new Window2();
var doc = new DocumentViewModel(new DocumentPage());
doc.AddDocumentDelegate += new Action<Document>(OnAddDocument);
win2.DataContext = doc;
wind2.ShowDialog();
}
private void OnAddDocument(Document doc)
{
_repository.AddDocument(doc);
}
}
What do you think about that idea?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
视图模型将模型和视图连接在一起;它正是控制持久性的东西,尽管它不处理持久性。
我们通过使用服务将其与其他问题分离。
避免向视图模型添加持久性问题的一种方法是将这些问题抽象到存储库接口中,以便我们可以将其作为依赖项注入。通过这种方式,我们可以在视图模型中委托持久化工作,通常是为了响应用户与视图的交互。
The viewmodel connects the model and view together; it is exactly what controls persistence, though it does not handle persistence.
We decouple this from other concern by using services.
One way to avoid adding persistence concerns to the viewmodel is by abstracting those concerns into repository interfaces, so that we can inject it as a dependency. In this way we can delegate persistence work in the viewmodel, usually in response to the user's interaction with the view.