2020.12月上旬
C# その2 Advent Calendar 2020 12 / 7
21年7月追記
この記事に対して補足していただいたので、リンクを貼ります。
「WPF の XAML デザイナーに Prism の Region の内容を表示させたい」をやってみた
はじめに
私は、Visual Studioを使ってWPFデスクトップアプリケーションを開発しています。
開発の過程で困ったことが起きました。
その困ったことが、半分解決したので記事にしようと思いました。
同じことで困っている方の一助になれば幸いです。
また一方で「こうやればいい」というアドバイスも頂ければ嬉しいです。
前提
本題へ入る前に前提を説明します。
私が開発するWPFアプリケーションではPrismライブラリを使っています。
今回はとくに、Prismの機能の1つであるRegion機能1にまつわる話です。
Window
にUserControl
を埋め込んで表示する場合、私はこう書きます。
Window
のContentControl
タグの箇所に、PrismUserControl2
が表示されます。
ビュー
<Window>
...
<ContentControl prism:RegionManager.RegionName="ContentRegion" />
...
</Window>
ビューモデル
...
readonly IRegionManager _regionManager;
public MainWindowViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
_regionManager.RegisterViewWithRegion("ContentRegion", typeof(Views.PrismUserControl2));
}
...
困ったこと(本題)
PrismのRegion機能を使う場合、XAMLビューアーにUserControl
が表示されません。
これが困ったことです。
開発が進むにつれて、「あれ?このWindow
のココってどういう表示なんだっけ?」となります。
例をつかって説明します
例として、まず表示させたいUserControl
をつくります。
単なる青い背景のつまらない画面です。
<UserControl x:Class="DataContextTest_NETCore3Prism.Views.PrismUserControl2"
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"
Background="Blue" Width="64" Height="64"
>
<Grid Margin="10">
<TextBlock Text="本番" />
</Grid>
</UserControl>
青い背景のUserControl
をWindow
に埋め込みます。
ビュー(ちょっとネタバレを含んでる)
<Window x:Class="DataContextTest_NETCore3Prism.Views.MainWindow"
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"
Title="{Binding Title}" Height="350" Width="525"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:v="clr-namespace:DataContextTest_NETCore3Prism.Views"
xmlns:vm="clr-namespace:DataContextTest_NETCore3Prism.ViewModels"
d:DataContext="{d:DesignInstance Type=vm:MainWindowViewModel}">
<StackPanel>
<ContentControl prism:RegionManager.RegionName="ContentRegion" />
</StackPanel>
</Window>
ビューモデル(一部抜粋)
readonly IRegionManager _regionManager;
public MainWindowViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
_regionManager.RegisterViewWithRegion("ContentRegion", typeof(Views.PrismUserControl2));
}
願わくは、このプレビュー画面が真っ白じゃなくて、UserControl(青い四角)が表示されてほしい。
もちろん実行ボタンを押せば、正常にUserControlが表示されます。
(単なる青い四角を表示させた)
半分解決された
WPFの参考文献を検索すると、okazuki殿の記事によくたどり着きます。
そしてだいたいのことが解決されます。
本件は、@okazuki殿のツイートをきっかけに解決しました。
関連するマイクロソフトのドキュメントはこちらです::Visual Studio の XAML デザイナーでデザイン時のデータを使用する
どうやって半分解決されたか
デザイン時のみ有効な識別子を使うことで、Region機能とは別のルートでWindow
にUserControl
を表示させました
表示させたいUserControl
をXAML内で2回重複して書くことになります。
デザイン時のみ有効な識別子d
を使うために、XAMLにおまじないを書いておきます。
おまじない
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
実際のコード
<Window x:Class="DataContextTest_NETCore3Prism.Views.MainWindow"
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"
Title="{Binding Title}" Height="350" Width="525"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:v="clr-namespace:DataContextTest_NETCore3Prism.Views"
xmlns:vm="clr-namespace:DataContextTest_NETCore3Prism.ViewModels"
d:DataContext="{d:DesignInstance Type=vm:MainWindowViewModel}">
<StackPanel>
<!--仮-->
<d:ContentControl>
<v:PrismUserControl2/>
</d:ContentControl>
<!--本番-->
<ContentControl prism:RegionManager.RegionName="ContentRegion" />
</StackPanel>
</Window>
デザイン時にもUserControl
(青い四角)が表示されるようになりました。
半分解決されていないこと
私が個人的に趣味で行う分には、すべて解決済みです。
しかし、会社人の私としては、上記の方法が使えません。
よって、半分(=趣味)は解決しましたが、もう半分(出社中の私)としては解決しておりません。
会社にいる私が解決できない理由は、以下2つの要件を満たす環境がないからです。
- 上記の機能は、Visual Studio 2019以降で有効
- 上記の機能は、.NET Coreで有効
前述した公式ドキュメントの要件に書かれています。
デザイン時のデータには、Visual Studio 2019 バージョン 16.7 以降が必要です。
.NET Core および UWP 用の Windows Presentation Foundation (WPF) を対象とする Windows デスクトップ プロジェクトがサポートされていること。
(引用元:https://docs.microsoft.com/ja-jp/visualstudio/xaml-tools/xaml-designtime-data?view=vs-2019)
まったく同じことを .NET Framework 4.6.1で行うと、エラーが表示されます。
MainWindow.xamlに、解決できない型が含まれています。
はやく .NET5が社内標準になってほしいです。
以上です。
読んでいただきたき、ありがとうございました。