I'm looking into using MVVM and while I understand it for the most part, there is one thing I can't get my head around.
Imagine I have a View and ViewModel combination that show a list of foobars. When the user selects a foobar in the list and clicks the edit button I want the foobar to be shown in a popup dialog window so it can be edited. This dialog window (the view) will have its own associated ViewModel.
I understand that the button can be bound to a command on the list ViewModel, but from here how do I instantiate the foobar editor?
1) Do I have to send a message back to the View, which will open the dialog window? If so, doesn't this defeat the purpose of having the command?
2) How does the foobar get passed into the ViewModel for the editor? If it is by its constructor, doesn't this make it hard to declare the ViewModel in XAML?
I feel that this is the last piece of the puzzle that is preventing me from using MVVM and I'd really like to get a nice decoupled solution to this.
Thanks Matt
I would perhaps do it in the following way:
The need for a clone comes from the fact that the user doesn't want to see the changes in the foobar list until he accepts the changes in the edit dialog. If however online editing is okay, the clone is not needed.
The changes are propagated automatically.
PS: although I am MVVM's proponent, I am not sure that my solution is an orthodox one from pure MVVM point of view.
This article from codeproject shows a WPF Dialog control that does exactly what you need. The reason this implementation is necessary is that you can't put a Window inside the visual tree of any other control. Which means out of the box WPF doesn't let you create a dialog inside a window. So the above article creates a subclass ContentControl that creates a window.
Anyways, you put this in your FooBarList View
<dialog:Dialog Content="{Binding Path=DialogViewModel}" />
You make sure you have something like this in a resource dictionary somewhere:
<Style TargetType="{x:Type dialog:Dialog}">
<Style.Triggers>
<Trigger Property="HasContent" Value="True">
<Setter Property="Showing" Value="True" />
</Trigger>
</Style.Triggers>
</Style>
and just write something like this(For WPF to work you need to implement INotifyPropertyChanged):
public Class FooBarListViewModel
{
IList<FooBar> FooBarList {get;set;}
FooBar SelectedFooBar {get;set;}
ViewModelBase DialogViewModel {get;set;}
public EditFooBar(object param)
{
DialogViewModel = FooBar;
}
}
To link the View to edit the FooBar to the FooBar ViewModel just do something like this(preferably in the Application.Resources so it's global)
<DataTemplate DataType={x:Type vm:FooBarViewModel}>
<vw:FooBarView/>
</DataTemplate>
(Or optionally: Use an IValueConverter to Convert get your View from a ViewModel like this post shows)
And then you're set. May sound like a lot, but it really frees you up a lot.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With