I'm working on a WPF MVVM application. I'm showing some data in a datagrid. I've two buttons to Add and Edit the selected record. I've data in ViewModel and I've to show another window (view) and make sure that ViewModels should have no information about views. Where should I create its view and viewmodel? How to get the data back and update datagrid? How can I achieve this in MVVM? We have not yet decided to use any framework, so I've to create my own interface.
相关问题
- VNC control for WPF application
- WPF Binding from System.Windows.SystemParameters.P
- XAML: Applying styles to nested controls
- How can I add a horizontal line (“goal line”) for
- How to properly change a resource dictionary
It depends how you are handling the data. I will assume that changes made in the popup window can be accepted only when user clicks something like save in other case they should be discarded. So firstly, I would suggest using MVC approach as controller is perfect for such tasks. You build viewmodels in it, assign them o views and show the views. VM's simply keeps data and commands, commands execute methods are kept in controller. In other words you have singleton class which manages your VM's and views. You should check out Prism framework. It offers great things like view regios where you can inject different user controls on the runtime, commanding and MVC layering out of the box alongside IOC and DI patterns.
Note: This ended up being quite a long answer - please ask me if anything is unclear
The implementation of dialog windows is a contentious issue in MVVM designs, and different people use different approaches.
Like you, I've decided not to use any framework and implement most things by hand. When it comes to dialog windows, I choose to be pragmatic about my implementation of MVVM, by launching the Dialog Window from inside my ViewModel. Also, I allow each Dialog ViewModel to have a reference to the Window it is displayed in, so it can close it when appropriate (details below). This breaks some of the strict MVVM "rules", but it gets the job done.
The main downside of this is that it might break unit testing if you are testing something that goes through a dialog. However, you can go a long way without running into that problem and it has not bothered me yet.
I've built up a bit of a library of dialog ViewModels which I can easily extend. It's way too much code to post here, but I'll show you the highlights.
Base ViewModel for Dialogs
Each of my dialog windows has a ViewModel that inherits from
DialogViewModelBase
, which is similiar to my regularViewModelBase
in that it provides support forINotifyPropertyChanged
etc. The interesting part is this public method, which I call from wherever to launch the Dialog:Window launched in the above method will close when its
Window.DialogResult
property is set. This is why theDialogWindow
is a property of theDialogViewModelBase
class - when the subclassing dialogViewModel
wants to close the dialog window, it simply sets the result:Host Window for Dialog Views
The
Dialogs.Views.DialogWindow
class that theShowDialogWindow
method instantiates is defined in XAML and is a subclass ofWindow
. It has two important features. The first is that it's primary content element is simply aContentControl
that binds to the current context. This allows me to define differentViews
for different subclasses ofDialogViewModelBase
, and theDialogWindow
will host the correspondingView
based on the type of the context:The second important feature of the
DialogWindow
XAML is that it defines which dialogViews
go with which dialogViewModels
. Here is a sample:What all this does, is that I can define dialogs as subclasses to
DialogViewModelBase
and implement aView
for each, and then tellDialogWindow
whichView
itsContentControl
must show for which dialogViewModel
.Launching a Dialog and getting results
Below is a sample from one of my application
ViewModels
, in which I launch a Dialog Window that allows the user to select an Asset Type for creation:PS: I should really write a blog entry about this - when I do, I will post the link here, as the blog entry will probably have more complete code samples.