LoginSignup
26
16

More than 3 years have passed since last update.

UWP 版の Prism の Prism.Uno を試してみよう

Posted at

XAML 系プラットフォーム(WPF、Xamarin.Forms、UWP)でよく使われてる MVVM フレームワークの Prism ですが、UWP 版の Prism は一時期削除されましたが、Prism v8 (現在はプレビュー段階) で WPF 版の Prism をベースに UWP に移植されました。削除された昔の UWP 用 Prism は、どちらかというと Xamarin.Forms の Prism を踏襲していましたが、WPF のほうに寄せてきました。

試してみよう

UWP プロジェクトを新規作成します。そして Prism.Unity.Uno のプレビュー版のパッケージを追加します。
そして、Views 名前空間に Shell という名前でページを作成します。XAML は以下のようにして、とりあえず ContentRegion が 1 つあるだけにしました。

Shell.xaml
<Page
    x:Class="HelloPrismApp.Views.Shell"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloPrismApp.Views"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:regions="using:Prism.Regions"
    mc:Ignorable="d"
    Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">

    <Grid Padding="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
        </Grid.RowDefinitions>
        <TextBlock Text="MyApp"
                   Style="{StaticResource HeaderTextBlockStyle}" />
        <ContentControl Grid.Row="1" 
                        regions:RegionManager.RegionName="ContentRegion" />
    </Grid>
</Page>

MainPage.xaml は不要なので削除して App.xaml を以下のように PrismApplication を継承するようにします。

App.xaml
<prism:PrismApplication
    x:Class="HelloPrismApp.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:prism="using:Prism.Unity"
    xmlns:local="using:HelloPrismApp">

</prism:PrismApplication>

App.xaml.csPrismApplication を継承するようにします。CreateShell メソッドで Shell をコンテナから取得するようにすれば OK です。

App.xaml.cs
using HelloPrismApp.Views;
using Prism.Ioc;
using Prism.Unity;
using Windows.UI.Xaml;

namespace HelloPrismApp
{
    sealed partial class App : PrismApplication
    {
        public App()
        {
            this.InitializeComponent();
        }

        protected override UIElement CreateShell() => Container.Resolve<Shell>();

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
        }
    }
}

実行すると以下のようになります。Shell が表示されました。

image.png

画面の中身を作ろう

Prism は Shell の Region に対して View をモジュールから差し込むことが出来ます。やってみましょう。UWP のクラスライブラリを HelloPrismApp.Main という名前で作って Prism.Uno パッケージ(プレビュー)を追加します。

クラスライブラリ側に ViewModels フォルダーを作って適当に VM を作ります。

TopViewModel.cs
using Prism.Commands;
using Prism.Mvvm;
using System;

namespace HelloPrismApp.Main.ViewModels
{
    public class TopViewModel : BindableBase
    {
        private string _message;
        public string Message
        {
            get { return _message; }
            set { SetProperty(ref _message, value); }
        }

        private DelegateCommand _updateMessageCommand;
        public DelegateCommand UpdateMessageCommand =>
            _updateMessageCommand ?? (_updateMessageCommand = new DelegateCommand(ExecuteUpdateMessageCommand));

        private void ExecuteUpdateMessageCommand()
        {
            Message = DateTime.Now.ToString();
        }
    }
}

View も作ります。UserControl です。ViewModelLocator を設定して ViewModel が DataContext に設定されるようにします。

TopView.xaml
<UserControl
    x:Class="HelloPrismApp.Main.Views.TopView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:HelloPrismApp.Main.Views"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:viewModels="using:Prism.Mvvm"
    viewModels:ViewModelLocator.AutoWireViewModel="True"
    mc:Ignorable="d"
    d:DesignHeight="300"
    d:DesignWidth="400">

    <StackPanel>
        <TextBlock Text="{x:Bind ViewModel.Message, Mode=OneWay}"
                   Style="{StaticResource BodyTextBlockStyle}" />
        <Button Content="Update message"
                Command="{x:Bind ViewModel.UpdateMessageCommand}" />
    </StackPanel>
</UserControl>

TopView.xaml.cs に ViewModel プロパティも生やしておきます。

TopView.xaml.cs
using HelloPrismApp.Main.ViewModels;
using Windows.UI.Xaml.Controls;

namespace HelloPrismApp.Main.Views
{
    public sealed partial class TopView : UserControl
    {
        private TopViewModel ViewModel => (TopViewModel)DataContext;
        public TopView()
        {
            this.InitializeComponent();
        }
    }
}

最後に MainModule クラスを作って View の登録と View を Region に追加します。

MainModule.cs
using HelloPrismApp.Main.ViewModels;
using HelloPrismApp.Main.Views;
using Prism.Ioc;
using Prism.Modularity;
using Prism.Regions;

namespace HelloPrismApp.Main
{
    public class MainModule : IModule
    {
        public void OnInitialized(IContainerProvider containerProvider)
        {
            var regionManager = containerProvider.Resolve<IRegionManager>();
            regionManager.RequestNavigate("ContentRegion", "TopView");
        }

        public void RegisterTypes(IContainerRegistry containerRegistry)
        {
            containerRegistry.RegisterForNavigation<TopView, TopViewModel>();
        }
    }
}

モジュールが出来たのでアプリ本体のほうに参照を追加して App.xaml.cs にモジュールを登録します。

App.xaml.cs
using HelloPrismApp.Main;
using HelloPrismApp.Views;
using Prism.Ioc;
using Prism.Modularity;
using Prism.Unity;
using Windows.UI.Xaml;

namespace HelloPrismApp
{
    sealed partial class App : PrismApplication
    {
        public App()
        {
            this.InitializeComponent();
        }

        protected override UIElement CreateShell() => Container.Resolve<Shell>();

        protected override void RegisterTypes(IContainerRegistry containerRegistry)
        {
        }

        protected override void ConfigureModuleCatalog(IModuleCatalog moduleCatalog)
        {
            base.ConfigureModuleCatalog(moduleCatalog);
            moduleCatalog.AddModule<MainModule>();
        }
    }
}

実行すると ShellTopView が表示されています。コマンドもちゃんと動いているので ViewModel もちゃんと設定されてますね。

prism.gif

まとめ

個人的な予想ですが順当に進化していくと Windows UI Library 3.0 にも対応していくと思います。
そうなってくると理想的には UWP の他に Win32 の WinUI 3.0 にも対応してくれるのではないかと期待しています。

そうなると ViewModel レイヤーより下のレイヤーは WPF/UWP/WinUI3.0 で共有化して View だけ差し替えとかもできるかもしれません。特に WPF と WinUI 3.0 の Win32 はかなり共有できないかなぁと期待してます。

ということで、これからもちょくちょく Prism の状態をウォッチしていこうと思います。

26
16
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
26
16