LoginSignup
7
6

More than 1 year has passed since last update.

【WPF】XAMLビューアーにRegionの内容を表示させたい【Prism】

Last updated at Posted at 2020-12-04

2020.12月上旬

C# その2 Advent Calendar 2020 12 / 7

21年7月追記

この記事に対して補足していただいたので、リンクを貼ります。
「WPF の XAML デザイナーに Prism の Region の内容を表示させたい」をやってみた

はじめに

私は、Visual Studioを使ってWPFデスクトップアプリケーションを開発しています。
開発の過程で困ったことが起きました。
その困ったことが、半分解決したので記事にしようと思いました。

同じことで困っている方の一助になれば幸いです。
また一方で「こうやればいい」というアドバイスも頂ければ嬉しいです。

前提

本題へ入る前に前提を説明します。
私が開発するWPFアプリケーションではPrismライブラリを使っています。
今回はとくに、Prismの機能の1つであるRegion機能1にまつわる話です。
WindowUserControlを埋め込んで表示する場合、私はこう書きます。
WindowContentControlタグの箇所に、PrismUserControl2が表示されます。

ビュー

MainWindow

<Window>
    ...
    <ContentControl prism:RegionManager.RegionName="ContentRegion" />
    ...
</Window>

ビューモデル

MainWindowViewModel
...
readonly IRegionManager _regionManager;
public MainWindowViewModel(IRegionManager regionManager)
{
    _regionManager = regionManager;
    _regionManager.RegisterViewWithRegion("ContentRegion", typeof(Views.PrismUserControl2));
}
...

困ったこと(本題)

PrismのRegion機能を使う場合、XAMLビューアーにUserControlが表示されません
これが困ったことです。

開発が進むにつれて、「あれ?このWindowのココってどういう表示なんだっけ?」となります。

例をつかって説明します

例として、まず表示させたいUserControlをつくります。
単なる青い背景のつまらない画面です。

PrismUserControl2
<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>

1204_011.png

青い背景のUserControlWindowに埋め込みます。

ビュー(ちょっとネタバレを含んでる)

MainWindow
<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>

ビューモデル(一部抜粋)

MainWindowViewModel
readonly IRegionManager _regionManager;
public MainWindowViewModel(IRegionManager regionManager)
{
    _regionManager = regionManager;
    _regionManager.RegisterViewWithRegion("ContentRegion", typeof(Views.PrismUserControl2));
}

願わくは、このプレビュー画面が真っ白じゃなくて、UserControl(青い四角)が表示されてほしい。
1204_010.png

もちろん実行ボタンを押せば、正常にUserControlが表示されます
(単なる青い四角を表示させた)
1204_020.png

半分解決された

WPFの参考文献を検索すると、okazuki殿の記事によくたどり着きます。
そしてだいたいのことが解決されます。

本件は、@okazuki殿のツイートをきっかけに解決しました。
関連するマイクロソフトのドキュメントはこちらです::Visual Studio の XAML デザイナーでデザイン時のデータを使用する

どうやって半分解決されたか

デザイン時のみ有効な識別子を使うことで、Region機能とは別のルートでWindowUserControlを表示させました
表示させたいUserControlをXAML内で2回重複して書くことになります

デザイン時のみ有効な識別子dを使うために、XAMLにおまじないを書いておきます。

おまじない

MainWindow
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"

実際のコード

MainWindow
<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(青い四角)が表示されるようになりました。

1204_030.png

半分解決されていないこと

私が個人的に趣味で行う分には、すべて解決済みです。
しかし、会社人の私としては、上記の方法が使えません。
よって、半分(=趣味)は解決しましたが、もう半分(出社中の私)としては解決しておりません。

会社にいる私が解決できない理由は、以下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に、解決できない型が含まれています。

1204_040.png

はやく .NET5が社内標準になってほしいです。

以上です。
読んでいただきたき、ありがとうございました。

7
6
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
7
6