There is a lot of things going on here. There are two parts to your question (if I'm not missing anything).
- How to forward a double-click action to a Command in your ViewModel
- How to open a "workspace" in this sample (a workspace is just a tab, in this case).
How to DoubleClick a ListViewItem, MVVM Style
There are a number of ways, but this question on SO sums it up pretty well:
http://stackoverflow.com/questions/1035023/firing-a-double-click-event-from-a-wpf-listview-item-using-mvvm
I personally use MarlonGrech's attached behaviors, so I will show you how to do that:
<ListView
AlternationCount="2"
DataContext="{StaticResource CustomerGroups}"
...>
<ListView.ItemContainerStyle>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="acb:CommandBehavior.Event"
Value="MouseDoubleClick" />
<Setter Property="acb:CommandBehavior.Command"
Value="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type UserControl}, Path=DataContext.EditCustomerCommand}" />
<Setter Property="acb:CommandBehavior.CommandParameter"
Value="{Binding}" />
</Style>
</ListView.ItemContainerStyle>
</ListView>
This would bind to your EditCustomerCommand (which would be a RelayCommand) that you would need to setup in your AllCustomersViewModel.
Add a New Workspace
This one is more tricky. You'll notice that MainWindowViewModel has a AddWorkspace, but we really don't have a reference to that ViewModel from AllCustomersViewModel.
I decided the best way to do this (for me) would be to create another interface called "IWorkspaceCommands" that AllCustomersViewModel would use to create new workspaces. This is mainly to contrast with the previous answerer's suggestion of the Messenger approach. If you prefer the Messenger approach, you can use that here instead.
MainWindowViewModel would actually implement this and pass itself in when it created AllCustomersViewModel.
public interface IWorkspaceCommands
{
void AddWorkspace(WorkspaceViewModel view);
}
And here is the basic implementation of the interface. This includes a check to see if the view is already open, as requested (really simple!):
#region IWorkspaceCommands Members
public void AddWorkspace(WorkspaceViewModel view)
{
if (!Workspaces.Contains(view))
{
Workspaces.Add(view);
}
SetActiveWorkspace(view);
}
#endregion
And finally, here is that RelayCommand I was telling you about in your AllCustomersViewModel (along with some constructor modifications):
IWorkspaceCommands _wsCommands;
public AllCustomersViewModel(CustomerRepository customerRepository, IWorkspaceCommands wsCommands)
{
_wsCommands = wsCommands;
EditCustomerCommand = new RelayCommand(EditCustomer);
...
}
public void EditCustomer(object customer)
{
CustomerViewModel customerVM = customer as CustomerViewModel;
_wsCommands.AddWorkspace(customerVM);
}
That's pretty much it. Because you are dealing with a reference to the same ViewModel that was used to create the AllCustomersViewModel, when you edit it in one screen, it updates in the other without eventing or messaging (nice!, but probably not robust enough).
There's a slight problem with the ComboBox not auto-selecting the value for company/person, but that is left as an exercise for the reader.
As part of my package today, I'm including a fully functional demo at no extra charge.
http://dl.getdropbox.com/u/376992/MvvmDemoApp.zip
Hope this helps,
Anderson