views:

1487

answers:

3

Hi All,

Hopefully quite a simple one, having my first try at WPF with Prism V2 using M-V-VM and so far finding everything pretty awsome. My Shell is pretty simple, Ribbon Control at the Top, DataGrid of Help desk tickets on the left, and a TabControl on the right.

When a user opens the selected ticket from the datagrid, I want the Ticket to open as a Tab on the Tab Control. I know in order to do that I need to add and then activate the View to the region using the RegionManager. But doing this from the ViewModel doesn't seem correct to me, although I could do it using DI (DepenecyInjection) it still rings alarms in my head about giving the ViewModel some knowledge about a View.

To Add to this, different modules will also be adding other views (Contact, Client etc) into the TabControl, I'd like to use DataTemplates to get the TabControl to display the View Correctly, can anyone give me any pointers for this as well.

Many Thanks Ben

Full answers please, not just links. It's what StackOverflow is for!

A: 

Commands are the way to do this - you'll send a command to yourself, called "RequestBringTicketIntoView"; it will bubble up to the Window, where you handle it. Read Josh Smith's article:

http://joshsmithonwpf.wordpress.com/2008/03/18/understanding-routed-commands/

Paul Betts
I don't think thats quite it. What I'd like is for an action to add a new instance of a View along with ViewModel to a different Region in the shell. You can't use Routed Commands with the M-V-VM pattern, and as the new View will need to know what to show in the new View I think it needs to be done in the ViewModel.
TheDuke
"You can't use Routed Commands with the M-V-VM pattern"Why not?
Paul Betts
Correct me if I'm wrong, I'm only going by something I read a while ago. Routed Commands bubble up the Visual Tree. The ViewModel in the M-V-VM patter is not part of the Visual Tree, and is not meant to know anything about it.
TheDuke
+1  A: 

MVVM + Services = Ultimate Power!

A service is just an interface that's well known and is registered in your IOC container. When the ViewModel needs to do something outside of itself, like say open a tabbed document, it uses the service. Then the service is implemented as needed for the particular program.

For example:

public interface IDocumentService
{
    void OpenDocument(IViewModel viewModel);
}

internal class DocumentService:IDocumentService
{
    public void OpenDocument(IViewModel viewModel)
    {
        // Implement code to select the View for the ViewModel,
        // and add it to your TabControl.
    }
}

{
    // Somewhere in your ViewModel...
    // Make sure you can get the IDocumentService
    IDocumentService docService = ioc.Get<IDocumentService>();
    docService.OpenDocument(new TicketViewModel());
}
Cameron MacFarland
Its the right direction, thanks.
TheDuke
A: 

Hi The Duke,

I try to do the same thing.

My Shell is simple, Ribbon Control at the Top and just a TabControl on the bottom.

When a user click on a ribbon button, I want to add a TabItem on the TabControl.

Today, I use datatemplate for the TabItem and Binding between a collection of View-Models and the TabControl to do that. The problem is that when the user select a TabItem in the tabcontrol, the view in my TabItem is loaded again.

So Can you explain how you solved your problem ? How did you do the link between the datacontext of the TabItem and the ViewModel (specific for each Item) ?

Geoblack