I am brand new to both wpf and MVVM. I have a Mainwindow that has two views left side has a usercontrol with a listbox and the list box has a edit button inside of it. On the right I have another view that contains all my controls for viewing and editing the record. I can select an item in the list box and edit my record since using binding it automatically populates by the selectedItem object. What I want to do is when the user hits the edit button show the view on the right if they hit another button contained in the list box then show that view on the right and close the previous view. I think I am missing a big concept here since most of the examples are to simplistic and just show one view. I really dont want to have to do it in the code behind. I have looked at John smiths tab and would like to do something similur without the tabs though. Any help would be greatly appreciated.
It sounds like both views need to share the same context (ie ViewModel) then they will stay in synch automaticall by the magic of dependency properties...
I would probably try setting it up so that clicking either button (View or Edit) sets the DataContext of the right frame. The RightFrame View gets displayed using DataTemplates based on the DataContext.
So your xaml would be something like this:
<DataTemplate DataType={x:Type MyEditingViewModel}>
<!-- Editing Object View -->
</DataTemplate>
<DataTemplate DataType={x:Type MyViewingViewModel}>
<!-- Viewing Object View -->
</DataTemplate>
and your button click events would be something like this:
private void EditButton_Click(object sender, EventArgs e)
{
RightFrame.DataContext = new MyEditingViewModel((sender as Button).DataContext)
}
private void ViewButton_Click(object sender, EventArgs e)
{
RightFrame.DataContext = new MyViewingViewModel((sender as Button).DataContext)
}
So basically, what you're trying to do is have your view model decide which view it should be presented in, and make that decision in response to user choice.
How I do this sort of thing:
My view model exposes a view style property, which is an enumerable. In the view for the view model (usually a user control), I implement a DockPanel
to contain each style of view. Each DockPanel
is assigned a style, and the styles are defined like this:
<Style x:Key="Style_View1" TargetType="DockPanel">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ViewStyle}" Value="View1">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
<Style x:Key="Style_View2" TargetType="DockPanel">
<Setter Property="Visibility" Value="Collapsed"/>
<Style.Triggers>
<DataTrigger Binding="{Binding ViewStyle}" Value="View2">
<Setter Property="Visibility" Value="Visible"/>
</DataTrigger>
</Style.Triggers>
</Style>
(Obviously you don't need to use a DockPanel
if a Grid
or StackPanel
is more appropriate for your scenario. And you can implement a different user control for each style of view if you want to keep your code nicely segmented.)
So as long as the value of ViewStyle
is one that there's a corresponding style for, that view style will be visible. Since all of the styles set Visibility
to Collapsed
by default, there will only ever be at most one view style visible.
There are lots of ways of selecting the view style - create a command for each one and bind it to buttons, create a group of radio buttons and use a value converter, set the view style in response to other properties in the view model - whatever works.