How to access dynamically loaded xap ViewModel?

May 26, 2011 at 8:00 AM
Edited May 26, 2011 at 9:52 AM

Jeremy,

I've made simple example for dynamic loading xap module. Dynamic module have his own ViewModel with sigle public property named "Text".
With simple button click I want to retrieve value of Text property. Can you guide me how to? 

using System.ComponentModel.Composition;
using System.Windows.Controls;
using Jounce.Core.View;
using Jounce.Core.ViewModel;
using Jounce.Framework.View;

namespace JounceDynamicDemo.Views
{
    [ExportAsView("MainView", IsShell = true)]
    public partial class MainView
    {
        public const string MAIN = "MainView";

        public MainView()
        {
            InitializeComponent();
        }

        [Export]
        public ViewModelRoute Binding
        {
            get { return ViewModelRoute.Create("MainViewModel", "MainView"); }
        }

        [Export]
        public ViewXapRoute DynamicViewXapRoute
        {
            get { return ViewXapRoute.Create("DynamicView", "DynamicView.xap"); }
        }

        [Import]
        public ViewRouter ViewRouter { get; set; }

        public void ConfigureRoute()
        {
            ViewRouter.RouteViewInXap("DynamicView", "DynamicView.xap");
        }

        private void btnGetText_Click(object sender, System.Windows.RoutedEventArgs e)
        {
            UserControl dynamicUC = ViewRouter.ViewModelRouter.GetNonSharedView("DynamicView", DataContext);
            var dynamicVM = ViewRouter.ViewModelRouter.GetNonSharedViewModel("DynamicViewModel");
// How to Cast to DynamicViewModel??? //string text = dynamicVM.Text; } } }
VS 2010 solution is avaliable here. Any sample or a hint welcome! Thanks in advance!
Coordinator
May 26, 2011 at 12:06 PM

So by definition, a view model would be associated with a view. If you are just using it to hold properties, you'd use some other class or construct.

I'm trying to figure out what the goal is. If "DynamicViewModel" is in another XAP file, and "DynamicView" is in another XAP file, then a few questions:

The main question is whether the view is shown at some point first. Assuming this is true to populate the view model. In that case, you'd have a view XAP route, and raising the navigation for the view would automatically load the XAP, view, and view model. In that case you can simply interrogate the router and pull it.

As for casting ... if you aren't referencing the XAP, you obviously don't have a type at run time to cast to. In that case, you have a few options.

1. Do you REALLY need it to be dynamic? Are you building a dynamic XAP just to be dynamic or is there an identified need?

2. Use an interface - define the view models with an interface that you CAN reference, then cast the dynamic view model to the interface and interrogate it that way

3. Use dynamic - dynamic vm = yada yada and then vm.Text.

Hope this helps, let me know if I missed anything!

May 26, 2011 at 12:52 PM

Jeremy thanks for very fast response!

My goal is create simple application framework based on Jounce which can dynamically loads xap modules (from menu for example). Separated modules holds entities (like Customers, Employees, Orders, etc). From application framework I must have access to loaded module's viewmodel to set properties (Customer's Firstname, Lastname, etc). Idea with common interface which is referenced from application framework and each module was very good and solves problem for now.

Do you now have a picture what is my goal?

Thank you!

Coordinator
May 26, 2011 at 1:07 PM

Sure and that's very doable. There are quick start examples of dynamically loading views. You probably want something like a manifest however so you can pre-build your tabs or menu items and just trigger the load when selected - obviously you're not going to "discover" the menu items because the other XAPs haven't loaded yet.

The other thing to keep in mind is view models do not synchronize data, they synchronize view state. You should never query a view model to say "what is the customer name." You would have a customer model for that. The model can be shared, and you might either have a "current customer" or you might have a message sent with the model details, but you'd never query a view model for that information. The only reason to directly talk to another view model is to send a message to prepare it for something it needs to do with the view.

May 26, 2011 at 1:35 PM

Thank you!

Oct 7, 2013 at 1:03 PM
Edited Oct 7, 2013 at 1:14 PM
Hi