Displaying other views (with parameters) in MainWindow using RegionManager

1. I will use the prism’s feature to pass parameters from MainWindow to View on this page. (In the repository, the project is named NavigateToViewWithParameters.)

In preparation for the following steps, create a project with the same configuration as the UserControlView project. The project name is NavigateToViewWithParameters.

2. Right-click the Views folder of the created project and add a new item.

3. Under Add New Item, select Prism UserControl (WPF). The name of the item to be added is ViewWithParametersView. Click Add on this screen.

4. Views/ViewWithParametersView.xaml (and ViewWithParametersView.xaml.cs) and ViewModels/ViewWithParametersViewModel.cs will be added.

5. Although not related to passing parameters to the View, the color of the Accent in Material Design In XAML was changed from LightGreen to Yellow as shown in App.xaml below. The changed line is highlighted.

<prism:PrismApplication x:Class="NavigateToViewWithParameters.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:NavigateToViewWithParameters"
             xmlns:prism="http://prismlibrary.com/" >
    <Application.Resources>

        <ResourceDictionary>

            <ResourceDictionary.MergedDictionaries>

                <!-- MahApps -->
                <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Controls.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Fonts.xaml" />
                <!-- Theme setting -->
                <ResourceDictionary Source="pack://application:,,,/MahApps.Metro;component/Styles/Themes/Light.Green.xaml" />

                <!-- Material Design -->
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.LightGreen.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Yellow.xaml" />

                <!-- Material Design: MahApps Compatibility -->
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.MahApps;component/Themes/MaterialDesignTheme.MahApps.Fonts.xaml" />
                <ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.MahApps;component/Themes/MaterialDesignTheme.MahApps.Flyout.xaml" />

            </ResourceDictionary.MergedDictionaries>

            <!-- MahApps Brushes -->
            <SolidColorBrush x:Key="HighlightBrush" Color="{DynamicResource Primary700}"/>
            <SolidColorBrush x:Key="AccentBaseColorBrush" Color="{DynamicResource Primary600}" />
            <SolidColorBrush x:Key="AccentColorBrush" Color="{DynamicResource Primary500}"/>
            <SolidColorBrush x:Key="AccentColorBrush2" Color="{DynamicResource Primary400}"/>
            <SolidColorBrush x:Key="AccentColorBrush3" Color="{DynamicResource Primary300}"/>
            <SolidColorBrush x:Key="AccentColorBrush4" Color="{DynamicResource Primary200}"/>
            <SolidColorBrush x:Key="WindowTitleColorBrush" Color="{DynamicResource Primary700}"/>
            <SolidColorBrush x:Key="AccentSelectedColorBrush" Color="{DynamicResource Primary500Foreground}"/>
            <LinearGradientBrush x:Key="ProgressBrush" EndPoint="0.001,0.5" StartPoint="1.002,0.5">
                <GradientStop Color="{DynamicResource Primary700}" Offset="0"/>
                <GradientStop Color="{DynamicResource Primary300}" Offset="1"/>
            </LinearGradientBrush>
            <SolidColorBrush x:Key="CheckmarkFill" Color="{DynamicResource Primary500}"/>
            <SolidColorBrush x:Key="RightArrowFill" Color="{DynamicResource Primary500}"/>
            <SolidColorBrush x:Key="IdealForegroundColorBrush" Color="{DynamicResource Primary500Foreground}"/>
            <SolidColorBrush x:Key="IdealForegroundDisabledBrush" Color="{DynamicResource Primary500}" Opacity="0.4"/>
            <SolidColorBrush x:Key="MahApps.Metro.Brushes.ToggleSwitchButton.OnSwitchBrush.Win10" Color="{DynamicResource Primary500}" />
            <SolidColorBrush x:Key="MahApps.Metro.Brushes.ToggleSwitchButton.OnSwitchMouseOverBrush.Win10" Color="{DynamicResource Primary400}" />
            <SolidColorBrush x:Key="MahApps.Metro.Brushes.ToggleSwitchButton.ThumbIndicatorCheckedBrush.Win10" Color="{DynamicResource Primary500Foreground}" />

        </ResourceDictionary>

    </Application.Resources>
</prism:PrismApplication>

6. To change the design and prepare for passing the parameters to the View, change Views/MainWindow.xaml as follows.

<metro:MetroWindow x:Class="NavigateToViewWithParameters.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:metro="http://metro.mahapps.com/winfx/xaml/controls"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="{Binding Title}" Height="350" Width="525" >
    <StackPanel>
        <TextBox FontSize="16" Text="{Binding DateTimeText}" />
        <Button Content="Update Time" Command="{Binding DateTimeUpdateButton}"/>
        <UniformGrid Columns="2">
            <Button Content="Show Huge Label View" Command="{Binding ShowHugeLabelButton}"
                    Style="{StaticResource MaterialDesignRaisedLightButton}"/>
            <Button Content="Show View with Parameters" Command="{Binding ShowViewWithParametersButton}"
                    Style="{StaticResource MaterialDesignRaisedSecondaryButton}"/>
        </UniformGrid>
        <ContentControl prism:RegionManager.RegionName="ContentRegion" />
    </StackPanel>
</metro:MetroWindow>

The outermost Grid tag is removed and the entire controls are placed in a StackPanel. A UniformGrid with 2 columns is prepared in the third row of the StackPanel and 2 buttons are placed.

Changed the variable passed to ViewWithParametersView from DateTimeLabel to DateTimeText. Changed the Control from Label to TextBox so that users can modify DateTimeText.

“Show Huge Label View” button’s Style is specified as Style=”{StaticResource MaterialDesignRaisedLightButton}”. The button has a slightly lighter color than the default Button. I also set the Style for “Show View with Parameters” button to Style=”{StaticResource MaterialDesignRaisedSecondaryButton}”. The button is yellow, specified as an accent.

7. Add the highlighted line to App.xaml.cs to allow ViewWithParametersView to be displayed with the IRegionManager’s RequestNavigate method.

using NavigateToViewWithParameters.Views;
using Prism.Ioc;
using System.Windows;

namespace NavigateToViewWithParameters
{
    /// <summary>
    /// Interaction logic for App.xaml
    /// </summary>
    public partial class App
    {
        protected override Window CreateShell()
        {
            return Container.Resolve<MainWindow>();
        }

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<HugeLabelView>();
            containerRegistry.RegisterForNavigation<ViewWithParametersView>();
        }
    }
}

8. Change or add the highlighted lines below in MainWindowViewModel.cs.

using Prism.Commands;
using Prism.Mvvm;
using Prism.Regions;
using NavigateToViewWithParameters.Views;

namespace NavigateToViewWithParameters.ViewModels
{
    public class MainWindowViewModel : BindableBase
    {
        private readonly IRegionManager _regionManager;

        private string _title = "Prism NavigateToViewWithParameters";
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        private string _dateTimeText = System.DateTime.Now.ToString();
        public string DateTimeText
        {
            get { return _dateTimeText; }
            set { SetProperty(ref _dateTimeText, value); }
        }

        public DelegateCommand DateTimeUpdateButton { get; }
        public DelegateCommand ShowHugeLabelButton { get; }
        public DelegateCommand ShowViewWithParametersButton { get; }

        public MainWindowViewModel(IRegionManager regionManager)
        {
            DateTimeUpdateButton = new DelegateCommand(DateTimeUpdateButtonExecute);
            ShowHugeLabelButton = new DelegateCommand(ShowHugeLabelButtonExecute);
            ShowViewWithParametersButton = new DelegateCommand(ShowViewWithParametersButtonExecute);
            _regionManager = regionManager;
        }

        private void DateTimeUpdateButtonExecute()
        {
            DateTimeText = System.DateTime.Now.ToString();
        }

        private void ShowHugeLabelButtonExecute()
        {
            _regionManager.RequestNavigate("ContentRegion", nameof(HugeLabelView));
        }

        private void ShowViewWithParametersButtonExecute()
        {
            var parameters = new NavigationParameters();
            parameters.Add(nameof(ViewWithParametersViewModel.ParameterText), DateTimeText);
            _regionManager.RequestNavigate("ContentRegion", nameof(ViewWithParametersView), parameters);
        }
    }
}

In lines 19-24, the variable name is changed from Label to Text. Because the control was changed from Label to TextBox in MainWindow.xaml, the modified program not only sets the current time to DateTimeText, but also allows users to edit the contents of the TextBox.

In line 28, I prepare a DelegateCommand bound to the Command of the Button that displays ViewWithParametersView. In line 34, the DelegateCommand is instantiated by using the method ShowViewWithParametersButtonExecute, which is called when the button is pressed, as a parameter.

Lines 48-53 are the method ShowViewWithParametersButtonExecute. Line 50 creates a parameters object of type NavigationParameters to store the parameters. In line 51, a parameter is stored in the parameters object with nameof(ViewWithParametersViewModel.ParameterText) as the Key and DateTimeText as the Value.
Line 52 calls RequestNavigate to display ViewWithParametersView at the ContentControl of MainWindow.xaml. At this time, the parameters object is given as the third argument and the parameters are passed to ViewWithParametersView.

9. Change or add the following highlighted lines in ViewWithParametersViewModel.cs.

using Prism.Mvvm;
using Prism.Regions;

namespace NavigateToViewWithParameters.ViewModels
{
    public class ViewWithParametersViewModel : BindableBase, INavigationAware
    {
        public ViewWithParametersViewModel()
        {

        }

        private string _parameterText = string.Empty;
        public string ParameterText
        {
            get { return _parameterText; }
            set { SetProperty(ref _parameterText, value); }
        }


        public bool IsNavigationTarget(NavigationContext navigationContext)
        {
            return true;
        }

        public void OnNavigatedFrom(NavigationContext navigationContext)
        {

        }

        public void OnNavigatedTo(NavigationContext navigationContext)
        {
            ParameterText = navigationContext.Parameters.GetValue<string>(nameof(ParameterText));
        }
    }
}

In order to receive parameters passed from the method _regionManager.RequestNavigate(“ContentRegion”, nameof(ViewWithParametersView), parameters), an interface INavigationAware is implemented in line 6.

Lines 21-24, 26-29, and 31-34 implement the three methods of INavigationAware.

The OnNavigatedTo method is executed when the View is displayed by RequestNavigate. The value of the parameter set in MainWindowViewModel.cs is acquired.

The IsNavigationTarget method returns a bool value indicating whether to retain the previous value or not after the View is closed. In this program, the result is the same in either case. I have chosen to return true.

OnNavigatedFrom is a method executed just before the View is closed. In this implementation, nothing is done.

Lines 13-18 prepare a variable and a property to store a parameter string received by ViewWithParametersView. The property ParameterText is bound to TextBlock’s Text in ViewWithParametersView.xaml so that the received parameter string is displayed on ViewWithParametersView.

10. Add the following highlighted lines to ViewWithParametersView.xaml

<UserControl x:Class="NavigateToViewWithParameters.Views.ViewWithParametersView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:prism="http://prismlibrary.com/"             
             prism:ViewModelLocator.AutoWireViewModel="True">
    <Grid>
        <TextBlock Text="{Binding ParameterText}" FontSize="50"
                   Foreground="{StaticResource AccentColorBrush4}"
                   TextWrapping="Wrap"/>
    </Grid>
</UserControl>
  • The property ParameterText is bound to TextBlock’s Text so that the value of ParameterText is displayed.
  • Foreground=”{StaticResource AccentColorBrush4}” specifies the color of the text to be displayed.
  • TextWrapping=”Wrap” is used to wrap strings when they extend beyond the View.
  • FontSize=”50″ specifies the font size.

11. Launch the program and click the “Show Huge Label View” button to see the following.

12. When “Show View with Parameters” button is clicked, the following is displayed. The DateTimeText string is passed from MainWindow to ViewWithParametersView and displayed on ViewWithParametersView.

13. Add any letters to the TextBox.

14. Click “Show View with Parameters” button again and you will see the following. The DateTimeText string to which some letters were added is passed from MainWindow to ViewWithParametersView and displayed in ViewWithParametersView.