WPF Prism framework Region became invalid?

WPF Prism framework Region became invalid?

The typical operation flow for client projects is: pop up login window => account verification success => close login window => pop up main window => work in main window.

Last updated 1/7/2021 10:53 AM
沙漠尽头的狼
5 min read
Category
WPF
Topic
WPF MVVM Framework Prism Series
Tags
.NET WPF Prism Region

The site owner has been using Prism 4 since 2015, and last year (2020 😊) also used Prism 8 for an open-source project. Today, I'd like to share a solution for handling a Prism Region problem.

Problem Description

A typical client application workflow: display login window → authenticate account → close login window → display main window → work in the main window.

Normal login flow

Normal login flow

In the main window shown in the GIF above, the left side is a tree, and the right side is a TabControl, with view injection code in a Prism module:

public class ModuleOfLogModule : IModule
	{

		public void RegisterTypes(IContainerRegistry containerRegistry)
		{
			containerRegistry.RegisterForNavigation<MainTabItemView, MainTabItemViewModel>(KEY_OF_CURRENT_MODULE);
		}
	}

The main project's TabControl serves as the view area for modules:

<TabControl
  prism:RegionManager.RegionName="{x:Static inf:RegionNames.MainTabRegion}"
/>

When clicking a menu item on the left tree, it dynamically navigates to the module view:

private void RaiseSelectedItemHandler(CustomMenuItem menuItem)
{
  // Omitted many lines of code
  region.RequestNavigate(menuItem.Key);
  // Omitted many lines of code
}

During runtime, the navigation did not work. The original approach was to display the main window directly after successful login, registering the login window view in app.xaml.cs:

protected override Window CreateShell()
{
  return Container.Resolve<LoginView>();
}

I found that others had encountered the same problem:

  1. WPF Prism framework: first login window then open main window (CSDN discussion thread, original link no longer maintained)

The discussion was active but did not provide the desired answer.

  1. prism – Region manager cannot find region in custom popup

This article suggests manually re-registering the region manager, but I did not adopt that approach.

RegionManager.SetRegionName( theNameOfTheContentControlInsideThePopup, WellKnownRegionNames.DataFeedRegion );
RegionManager.SetRegionManager( theNameOfTheContentControlInsideThePopup, theRegionManagerInstanceFromUnity );
  1. Prism MVVM application: switching main window after login

This code implements login and main window as user controls, registers a ShellView in app.xaml.cs, sets a region in the ShellView, and switches between the two user controls via navigation within that region. While the effect works and regions inside the main window function correctly, this approach is inconvenient because the custom login interface and main interface typically have different title bars and other elements. Not recommended.

A similar description for problem 3: Prism MVVM application: switching main window after login

Application scenario
    Use Prism7 to develop WPF programs with MVVM. When the program starts, it first shows a login interface for authentication, then transitions to the main layout window after successful authentication.

Design approach
    After building the WPF framework, there is a single Shell.xaml as the only stage for performers. The login form (hereinafter LoginView) and the main layout form (hereinafter MainView) are managed separately using IRegionManager, appearing at different times as needed. All operations are done by their respective ViewModels (VM).
    1. When the program starts, the Shell activates LoginView via its ViewModel using RegionManager's Add method. (Note by site owner: after successful login, the LoginView is deactivated and the MainView is activated via the Add method)

Solution Adopted by the Site Owner

Baidu provided almost no suitable solution, and this problem troubled me for several days (working 2-3 hours each night; I no longer work with WPF in my daily job).

Fortunately, I have a scientific internet connection and found an answer on YouTube: Adding a Prism Login Screen.

Adding a Prism Login Screen

The solution's code is simple. Add the following code in app.xaml.cs to show the login window before initializing the shell (InitializeShell, where shell refers to the main window registered via CreateShell()). After successful authentication, call base.InitializeShell(shell):

protected override void InitializeShell(Window shell)
{
  LoginView loginView = new LoginView();
  if (loginView.ShowDialog() == true)
  {
    var shellVM = shell.DataContext as MainWindowViewModel;
    shellVM.InitData();
    base.InitializeShell(shell);
  }
  else
  {
    Application.Current.Shutdown(-1);
  }
}

Discussion

This solution still has a problem: before calling InitializeShell(Window shell), I found during debugging that module views have already been initialized. Ideally, modules should be initialized only after successful login. Feel free to leave your thoughts and suggestions on the Dotnet9 website.

Keep Exploring

Related Reading

More Articles