RegionManagerを使ったMainWindowへの他のViewの表示(Parameter付き)
1. UserControlViewプロジェクトに対し、MainWindowからViewにパラメータを渡して表示する機能を追加していきます。(リポジトリでは、変更済みのプロジェクトの名称をNavigateToViewWithParametersとしています。)
以降の手順の準備として、UserControlViewプロジェクトと構成が同じでプロジェクト名がNavigateToViewWithParametersのプロジェクトを作成しておきます。
2. 作成したプロジェクトのViewsフォルダを右クリックし、新しい項目を追加します。
3. 新しい項目の追加でPrism UserControl (WPF)を選択します。追加する項目の名前はViewWithParametersViewにしました。この画面で追加をクリックします。
4. NavigateToViewWithParametersプロジェクトにViews/ViewWithParametersView.xaml(およびViewWithParametersView.xaml.cs)とViewModels/ViewWithParametersViewModel.csが追加されます。
5. Viewへのパラメータ渡しとは関係ありませんが、Material Design In XAMLのAccentのカラーを下記のApp.xamlのようにLightGreenからYellowに変更しました。変更した行をハイライト表示しています。
<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. デザインの変更とViewへのParameter渡しの準備のため、Views/MainWindow.xamlを下記のように変更します。
<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>
一番外側のGridタグを外し、全体をStackPanel内に配置するようにしました。StackPanel内の三行目にコラム数が2のUniformGridを用意し、同じ大きさのボタンを左右に並べて配置するようにしました。
ViewWithParametersViewに渡す変数をDateTimeLabelからDateTimeTextに変更しました。DateTimeTextの文字列をユーザーが書き換えられるよう、LabelからTextBoxに変更しました。
Show Huge Label ViewボタンのStyleをStyle=”{StaticResource MaterialDesignRaisedLightButton}”のように指定しました。デフォルトのButtonより少し薄い配色のボタンになっています。また、Show View with ParametersボタンのStyleをStyle=”{StaticResource MaterialDesignRaisedSecondaryButton}”としました。アクセントとして指定した黄色のボタンになっています。
7. ViewWithParametersViewをMainWindowViewModel.csからRequestNavigateメソッドで表示できるようにするため、App.xaml.csにハイライトした行を追加します。
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. 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);
}
}
}
19-24行目では変数名の末尾をLabelからTextに変更しています。MainWindow.xamlでLabelからTextBoxに変更したため、変更後のプログラムではDateTimeTextに現在時刻をセットして表示するだけでなく、TextBoxの内容を編集することもできます。
28行目でViewWithParametersViewを表示するボタンのCommandにバインドするDelegateCommandを用意しています。34行目でボタンが押されたときに呼び出されるメソッドShowViewWithParametersButtonExecuteをパラメータとしてこのDelegateCommandをインスタンス化しています。
48-53行目がメソッドShowViewWithParametersButtonExecuteです。50行目でパラメータを格納するNavigationParameters型のparametersオブジェクトを生成しています。51行目でparametersオブジェクトにnameof(ViewWithParametersViewModel.ParameterText)をKey、DateTimeTextをValueとするパラメータを格納しています。52行目でRequestNavigateを呼んでViewWithParametersViewをMainWindow.xamlのContentControlに表示します。このとき、第3引数としてparametersオブジェクトを与え、パラメータをViewWithParametersViewに渡しています。
9. 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));
}
}
}
MainWindowViewModelのメソッド_regionManager.RequestNavigate(“ContentRegion”, nameof(ViewWithParametersView), parameters)で渡された引数parametersを受け取ることができるようにするため、6行目でインターフェイスINavigationAwareを実装しています。
21-24, 26-29, 31-34行目でINavigationAwareの3つのメソッドを実装しています。
OnNavigatedToメソッドはRequestNavigateでViewが表示されるときに実行されるメソッドです。33行目のようにキーをnameof(ParameterText)として、string型のValueを取得してParameterTextにセットしています。MainWindowViewModel.csの51-52行目でparametersインスタンスにセットしたKey、Value形式のパラメータのValueを取得しています。
IsNavigationTargetメソッドはViewが表示されなくなった後も以前の値を保持するか否かをbool値で返します。今回の実装の場合、どちらでも結果は変わりませんが、値を保持するtrueを返すことにしました。
OnNavigatedFromはViewが表示されなくなる直前に実行されるメソッドです。Viewの終了処理等を記述します。今回の実装では何も行いません。
13-18行目はViewWithParametersViewが受け取ったパラメータ文字列を格納する変数とプロパティを用意しています。プロパティParameterTextをViewWithParametersView.xamlでTextBlockのTextとバインドし、受け取ったパラメータ文字列をViewWithParametersViewに表示するようにします。
10. 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>
- プロパティParameterTextをTextBlockのTextとバインドし、ParameterTextの値が表示されるようにしています。
- Foreground=”{StaticResource AccentColorBrush4}”で表示する文字の色を指定しています。
- TextWrapping=”Wrap”で、文字列がViewからはみ出すときは折り返すようにしています。
- FontSize=”50″でフォントサイズを指定しています。
11. プログラムをデバッグ実行し、Show Huge Label Viewボタンをクリックすると下記のように表示されます。
12. Show View with Parametersボタンをクリックすると下記のように表示されます。DateTimeTextの文字列がMainWindowからViewWithParametersViewに渡され、ViewWithParametersView内に表示されます。
13. 時刻を表示しているTextBoxに適当な文字列を追加します。
14. もう一度Show View with Parametersボタンをクリックすると下記のように表示されます。文字列を追加されたDateTimeTextの文字列がMainWindowからViewWithParametersViewに渡され、ViewWithParametersView内に表示されます。







