C#
.NET
WPF
VisualStudio
Xaml

XAML上で自身のクラス名を取得するMarkupExtension

More than 1 year has passed since last update.

概要

XAMLだけで自身のクラス名を取得するMarkupExtensionの説明です。
例えばMainWindow.xaml内であれば"MainWindow"という文字列を自動で取得できます。
コード(C#)で書くなら、this.GetType().Nameですが、XAMLだけでやる方法が簡単には分からなかったので紹介します。

使用方法

WindowのTitleと内部のTextBlockに後述するMarkupExtensionを指定します。

MainWindow.xaml
<Window
    x:Class="WpfApp3.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:WpfApp3"
    Width="300" Height="100"
    Title="{local:RootName}" >
    <TextBlock Text="{local:RootName}"/>
</Window>

結果

直接文字列で指定していなくても、"MainWindow"と表示されます。
スクリーンショット 2017-08-02 12.14.52.png

MarkupExtension実装

RootNameExtension.cs
[MarkupExtensionReturnType(typeof(string))]
public class RootNameExtension : MarkupExtension
{
    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        var provideValueTarget = serviceProvider.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider;
        var rootObj = provideValueTarget?.RootObject;
        return rootObj?.GetType().Name;
    }
}

注意点

デザイナ時には反映されません。
これは実行時とデザイン時ではserviceProviderが異なるからです。

スクリーンショット 2017-08-02 12.14.45.png

環境

VisualStudio2017
.NET Framework 4.6
C#6