LoginSignup
13
10

More than 5 years have passed since last update.

XAMLをアプリケーション上で表示するXAML(XAMLを表示するXAMLを表示するXAMLを表示するXAMLもあるよ)

Posted at

まえがき

MaterialDesignInXamlToolkitのサンプルを久しぶりに見てみたら、大きく変わっていて、その中に面白い動きをする部分を見つけました。
それが今回紹介するXAMLを表示するXAMLことXamlDisplayです。

XAMLを表示するXAML

なにはともあれスクリーンショット

スクリーンショット 2018-02-11 12.40.58.png

左側にXAMLの実行結果、右側にそのXAMLコードが表示されています。

上記画面のXAMLコードがこちらです。

MainWindow.xaml
<TextBlock Text="1- このTextBlockはXamlDisplayの外" />
<smtx:XamlDisplay Key="Unique1">
    <StackPanel >
        <Button Content="Some Content"/>
        <!--  コメントも表示される  -->
        <TextBlock Text="Some Text" />
    </StackPanel>
</smtx:XamlDisplay>

XamlDisplayで囲われた部分のXAMLコードが右側に表示されます。
もちろんButtonなどは正常に動作します。
またコメントも表示されます。

使用方法

まず最初にNugetからShowMeTheXAML.MSBuild を追加します。

次にApp.xaml.cs内にOnStartupのオーバーライドを追加します。

App.xaml.cs(部分)
protected override void OnStartup(StartupEventArgs e)
{
    ShowMeTheXAML.XamlDisplay.Init();
    base.OnStartup(e);
}

次に表示したい部分をXamlDisplayで囲みます。
ここで面倒なことがあり、Keyにアプリケーション内でユニークな文字列を指定する必要があります。
うーむなんとか自動化したい。

<smtx:XamlDisplay Key="UniqueKey">
    ...
</smtx:XamlDisplay>

これで囲われたXAMLが表示されます。

デザイン調整

必須ではありませんが、XAMLコード表示部分のデザインを良くするために、外部ライブラリを使用します。
NugetからShowMeTheXAML.AvalonEditを追加します。

注)記事作成時ではAvalonEditのリリース版にはバグが有り、表示が崩れています。
ですのでその修正を含んだプレスリリース版の1.0.10-ci44を使用しています。

App.Xamlにリソースを追加します。

App.xaml
<Application.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="pack://application:,,,/ShowMeTheXAML.AvalonEdit;component/Themes/xamldisplayer.xaml" />
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</Application.Resources>

これでXAMLコードが色付けされて見やすくなりました。
内部的にはAvalonEditを使用しているようです。

スクリーンショット 2018-02-11 12.56.48.png

スクリーンショット 2018-02-11 12.57.14.png

名前空間の削除

必須ではありませんが、標準ライブラリ以外を使用した部分を含めると、その名前空間も含めて表示されます。

このままですと、名前空間が長ったらしいので、それを非表示にします。
まず省略したい名前空間を含んだXamlFormatterを定義します。

<smtx:XamlFormatter x:Key="xamlFormatter">
    <smtx:XamlFormatter.NamespacesToRemove>
        <system:String>clr-namespace:ShowMeTheXAML;assembly=ShowMeTheXAML</system:String>
        <system:String>clr-namespace:ShowMeTheXAMLTest</system:String>
        <system:String>clr-namespace:System;assembly=mscorlib</system:String>
    </smtx:XamlFormatter.NamespacesToRemove>
</smtx:XamlFormatter>

それをXamlDisplayFormatterプロパティに追加します。

<smtx:XamlDisplay Key="Unique6" Formatter="{StaticResource xamlFormatter}">
...
</smtx:XamlDisplay>

これで名前空間が省略されて表示されます。

スクリーンショット 2018-02-11 13.09.24 - コピー.png

スクリーンショット 2018-02-11 13.09.24.png

使用例

文字のみ

文字のみ直接含めると、当たり前ですが左右でほとんど同じです。
スクリーンショット 2018-02-11 13.33.14.png

<TextBlock Text="3- このTextBlockはXamlDisplayの外" />
<smtx:XamlDisplay Key="Unique3">
    AAAA
</smtx:XamlDisplay>

もう少し複雑な場合

GridやMenuなど組み合わせて、少し複雑にした場合がこちらです。

スクリーンショット 2018-02-12 12.31.14.png

<TextBlock Text="2- このTextBlockはXamlDisplayの外" />
<smtx:XamlDisplay Key="Unique2" Padding="5">
    <Grid Width="300">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="Auto" />
            <ColumnDefinition Width="*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="Auto" />
            <RowDefinition />
            <RowDefinition Height="Auto" />
        </Grid.RowDefinitions>
        <Menu Grid.Row="0" Grid.ColumnSpan="2">
            <MenuItem Header="File" />
            <MenuItem Header="Edit" />
        </Menu>
        <CheckBox Grid.Row="1" Grid.Column="0"
            Content="Some Text1" />
        <Calendar Grid.Row="1" Grid.Column="1" />
        <Button Grid.Row="2" Grid.ColumnSpan="2"
            Content="BUTTON" />
    </Grid>
</smtx:XamlDisplay

動的な変更

表示されたXAMLコードはアプリケーション開始時の状態で固定されます。
ですので、ButtonClickイベントなどで要素を動的に変更しても追従はしません。

スクリーンショット 2018-02-12 12.09.16.png

スクリーンショット 2018-02-12 12.09.21.png

ButtonのクリックイベントでTextBlockの文字列を変更しています。
左側の文字列は"Some Text1"→"changed"に変わっていますが、右側のXAMLでは"Some Text1"のままです。

XAMLを表示するXAMLを表示するXAMLを表示するXAML

ではこのXAMLを表示するXamlDisplayをさらにXamlDisplayで囲ったらどうなるでしょうか?
さらにはこのXamlを表示するXamlDisplayをさらにXamlDisplayで囲ってさらにXamlDisplayで囲うとどうなるか?。

こうなります。

スクリーンショット 2018-02-11 13.38.01.png

XAMLを表示するXAMLを表示するXAMLを表示するXAMLのコード
<TextBlock Text="4XAMLを表示するXAMLを表示するXAMLを表示するXAML- このTextBlockはXamlDisplayの外" />
<smtx:XamlDisplay Key="Unique4-1">
    <StackPanel>
        <TextBlock Text="4-1" />
        <smtx:XamlDisplay Key="Unique4-2">
            <StackPanel>
                <TextBlock Text="4-2" />
                <smtx:XamlDisplay Key="Unique4-3">
                    <StackPanel>
                        <TextBlock Text="4-3" />
                        <smtx:XamlDisplay Key="Unique4-4">
                            <TextBlock Text="4-4" />
                        </smtx:XamlDisplay>
                    </StackPanel>
                </smtx:XamlDisplay>
            </StackPanel>
        </smtx:XamlDisplay>
    </StackPanel>
</smtx:XamlDisplay>

MaterialDesignInXamlToolkitのデモ

MaterialDesignInXamlToolkitではControlTemplateを使用して見た目を大きく変えています。

<⬣>ボタンをクリックすると、その左側の要素のXAMLコードがPopupで表示されます。
スクリーンショット 2018-02-11 13.51.38.png

見た目を大きく変えたい場合は、こちらを参考にすると良いと思います。

全体ソースコード

今回のサンプルコード全体をGithubにあげておきます。
https://github.com/soi013/ShowMeTheXAMLTest/tree/master

参考

MaterialDesignInXamlToolkit-MainDemo.wpf
Keboo/ShowMeTheXAML

環境

VisualStudio2017
.NET Framework 4.7
C#7.1
ShowMeTheXAML 1.0.10-ci44
ShowMeTheXAML.AvalonEdit 1.0.10-ci44
ShowMeTheXAML.MSBuild 1.0.10-ci44

13
10
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
13
10