1

I am making a DotVVM application, in which I want to display either logout button or login form on every page. Therefore I made custom control that uses ViewModel to handle login, or logout. Since I want this control on every page I put it inside my .master page.

My DotMaster Page looks like this:

@viewModel MyApp.ViewModels.AppViewModelBase, MyApp
<!DOCTYPE html>
<html>
   <head>
      <meta charset="utf-8" />
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>{{value:Title}}</title>
   </head>
   <body>
       <nav class="navbar navbar-inverse navbar-default">
           ...
           <cc:LoginPanel DataContext="{value: LoginSection}"></cc:LoginPanel>
           ...
       </nav>
       ...
   </body> 
</html>

Coresponding ViewModel AppViewModelBase looks like this.

using System.Threading.Tasks;
using DotVVM.Framework.ViewModel;
using MyApp.ViewModels.Login;

namespace MyApp.ViewModels
{
   public class AppViewModelBase : DotvvmViewModelBase
   {
      public string SubpageTitle { get; set; }

      public string Title { get { return string.Format("{0} - {1}", LogoText, SubpageTitle); } }

      public LoginSection LoginSection { get; set; } = new LoginSection();
      ...
   }
}

My LoginSection ViewModel also inherits from DotvvmViewModelBase, the problem is, the Context property of LoginSection is never filled and remains null. Am I supposed to set the Context of inner ViewModels manualy? I also noticed that Context of AppViewModelBase is not set in it's base constructor, but somewhere later on.

What is the best practice for this use case?

Mylan719
  • 93
  • 9

1 Answers1

1

In current version of DotVVM (0.8.6-pre), the Context property of the page viewmodel is set by the framework (before the Init method is called).

However, if the viewmodel contains other objects, those Context is not set (mostly because of performance reasons - we'd have to browse the viewmodel using reflection and analyze each property).

For now, I recommend to pass the Context property to the child object in the Init phase.

public override Task Init()
{
    LoginSection.Context = Context;
}

However, in future versions we are planning add some mechanism to inject these framework objects automatically.

Tomáš Herceg
  • 1,595
  • 1
  • 13
  • 18