views:

30

answers:

1

Hi!

I am building an module for an application that is based on MVVM, CAL and PRISM. I'm fairly new to these concepts, and trying to get my head around all the patterns and right now I'm struggling with the following problem:

I am in the need of creating multiple instances of the same View. Each one of the views need to bind to it's own ViewModel containing data for that specific view. A little more detailed, this is my scenario:

I need to display multiple instances of a OrdersDetailsView.xaml within a region placed in OrdersView.xaml. I have an OrdersView XAML that contains an ItemsControl tag defined like this:

<ItemsControl x:Name="OrdersItemsControl" BorderThickness="0" 
cal:RegionManager.RegionName="OrdersRegion" Margin="0,10,0,10">

As you can understand - within the ItemsControl in my OrdersView I want to display multiple instances of a OrderDetailsView. I'm able to add one OrderDetailsView in the hardcoded way described below, but what is the right/preferred way to instanciate and load multiple views and data into the region?

Dim OrdersRegion = _RegionManager.Regions("OrdersRegion")
Dim view = _Container.Resolve(Of OrdersDetailsView)()
Dim viewmodel = _Container.Resolve(Of OrdersDetailsViewModel)()

view.ApplyModel(viewmodel)
OrdersRegion.Add(view, "OrdersDetailsView")
OrdersRegion.Activate(view) 

EDIT:

Why is this code giving me 2 OrdersDetailsView BOTH with Orders ZZZ, I would have hoped that I got one view with Orders XXX and one with Orders ZZZ:

    Dim OrdersRegion = _RegionManager.Regions("OrdersRegion")

    Dim viewX = _Container.Resolve(Of OrdersDetailsView)()
    Dim viewmodelX = _Container.Resolve(Of OrdersDetailsViewModel)()

    viewmodelX.OrdersName = "Orders XXX"
    viewX.ApplyModel(viewmodelX)


    Dim viewZ = _Container.Resolve(Of OrdersDetailsView)()
    Dim viewmodelZ = _Container.Resolve(Of OrdersDetailsViewModel)()

    viewmodelZ.OrdersName = "Orders ZZZ"
    viewZ.ApplyModel(viewmodelZ)

    OrdersRegion.Add(viewX, "OrdersDetailsViewX")
    OrdersRegion.Add(viewZ, "OrdersDetailsViewZ")

EDIT2:

Public Sub Initialize() Implements Microsoft.Practices.Composite.Modularity.IModule.Initialize
    RegisterServices()

    container.Resolve(Of IOrdersView)()
    container.Resolve(Of IOrdersViewModel)()
    container.Resolve(Of IOrdersDetailsView)()
    container.Resolve(Of IOrdersDetailsViewModel)()

End Sub

Private Sub RegisterServices()
    container.RegisterType(Of IOrdersViewModel, OrdersViewModel)(New ContainerControlledLifetimeManager())
    container.RegisterType(Of IOrdersView, OrdersView)()

    container.RegisterType(Of IOrdersDetailsViewModel, OrdersDetailsViewModel)(New ContainerControlledLifetimeManager())
    container.RegisterType(Of IOrdersDetailsView, OrdersDetailsView)()
End Sub
+1  A: 

Hi,

Yes this is the right way of doing it. Of course, you will have to repeat this code to created new V-VM pairs:

Dim view = _Container.Resolve(Of OrdersDetailsView)()
Dim viewmodel = _Container.Resolve(Of OrdersDetailsViewModel)()

view.ApplyModel(viewmodel)

Also, there is no need to call Activate, as all views are active when the host control is an ItemsControl (AllActiveRegion).

I hope this helps.

Damian Schenkelman
Damian, Thnx, I'm slowly getting there! Please have a look at my EDIT in the intial post above and see if you're able to help me!
Mcad001
How are the views and VMs being registered. Use the GetHashCode method to check that they are not the same instance.
Damian Schenkelman
Please see EDIT2 above for how the views and VMs are being registered, seems correct to me..
Mcad001
The problem is that you are using ContainerControlledLifetimeManager(), which registers the VM as a singleton. Thus, you have a single VM being shared between two different views. Remove the LifetimeManager and your code will start working as expected.
Damian Schenkelman
THANX! You're spot on..
Mcad001