WPFプログラミング備忘録

WPF TextBlockクラスとコンテントプロパティについて

WPF

この記事ではTextBlockクラスのコンテントプロパティとは何かについて確認しています。

私はTextBlockクラスのコンテントプロパティはTextプロパティだと思っていたことがありますが、正しくはInlinesプロパティです。

プロパティ要素構文とコンテントプロパティ

TextBlockの使い方として以下のようなコードで文字列を表示するのはよく見かけると思います。

<TextBlock Text="これはTextBlockです。" />

これはプロパティ要素構文を使うと以下と等価です。

<TextBlock>
    <TextBlock.Text>
        これはTextBlockです。
    </TextBlock.Text>
</TextBlock>

プロパティ要素構文では<要素名.プロパティ名>と書きます。

ここで以下のコード考えてみます。このコードでも表示結果は上記のコードと同じになります。

<TextBlock>
    これはTextBlockです。
</TextBlock>

しかし重要な違いがあります。これもプロパティ要素構文を使って書き直してみましょう。

<TextBlock>
    <TextBlock.Inlines>
        これはTextBlockです。
    </TextBlock.Inlines>
</TextBlock>

実はTextBlockクラスのコンテントプロパティはTextプロパティではなくInlinesプロパティです。

実際TextBlockクラスには以下の属性が付与されています。

[System.Windows.Markup.ContentProperty("Inlines")]

詳細は以下を確認してください。

TextBlock Class (System.Windows.Controls)
Provides a lightweight control for displaying small amounts of flow content.

このContentPropertyがここで言っているコンテントプロパティのことです。そしてコンテントプロパティのプロパティ要素だけは省略できるのです。上の例で言うとTextBlock.Inlines要素は省略可能です。

他の要素もコンテントプロパティを持っています。

例をいくつか下表に示します。

要素名コンテントプロパティ
LabelContent
ButtonContent
StackPanelChildren

Contentプロパティはobject型なのでLabelやButtonにはテキストだけでなく画像なども表示させることができます。

例えばLabelに画像を表示したければ以下のようにします。

<Label>
     <Label.Content>
         <Image Source="画像ファイルのパス" />
     </Label.Content>
</Label>

コンテントプロパティのプロパティ要素は省略できるので以下のように書けます。

<Label>
    <Image Source="画像ファイルのパス" />
</Label>

TextBlock の Inlines プロパティ

TextBlockのコンテントプロパティはInlinesプロパティです。

InlinesプロパティはInlineCollection型のプロパティです。簡単に言えば複数の要素を格納できるコレクションです。

このコレクションにはRunクラス型やSpanクラス型などのオブジェクトを格納できます。

RunクラスのコンテントプロパティはTextプロパティで、SpanクラスのコンテントプロパティはInlinesプロパティです。

これによりTextBlockでは一文字単位で文字列の装飾ができるようになっています。

実際のサンプルコードを示します。

<Window x:Class="WpfContentProperty.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfContentProperty"
        mc:Ignorable="d"
        Title="MainWindow" Height="250" Width="400">
    <StackPanel>
        <StackPanel.Children><!-- コンテントプロパティを明示的に指定していますが省略可能です -->
            <TextBlock Text="これはプレーンテキストです。" Background="LightYellow" />
            <TextBlock>
                <TextBlock.Inlines><!-- コンテントプロパティを明示的に指定していますが省略可能です -->
                    これはサンプルのテキストですがRunオブジェクトに変換されています。
                    <LineBreak /><!-- 改行もできます -->
                    <Run FontSize="36" Foreground="Red">赤くて大きな</Run> テキストです。
                    <LineBreak />
                    <Span>
                        <Span.Inlines>
                            <Span FontSize="24">
                                <Span FontWeight="Bold">
                                    <Span FontStyle="Italic">
                                        <Span TextDecorations="Underline">
                                            <Span Background="Aqua">こんなこと</Span>もできます。
                                        </Span>
                                    </Span>
                                </Span>
                            </Span>
                        </Span.Inlines>
                    </Span>
                </TextBlock.Inlines>
            </TextBlock>
        </StackPanel.Children>
    </StackPanel>
</Window>

なお上記のコードは以下のコードと等価です。StackPanel、TextBlock及びSpanのコンテントプロパティは省略可能なので削除してあります。

<Window x:Class="WpfContentProperty.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:WpfContentProperty"
        mc:Ignorable="d"
        Title="MainWindow" Height="250" Width="400">
    <StackPanel>
        <TextBlock Text="これはプレーンテキストです。" Background="LightYellow" />
        <TextBlock>
            これはサンプルのテキストですがRunオブジェクトに変換されています。
            <LineBreak /><!-- 改行もできます -->
            <Run FontSize="36" Foreground="Red">赤くて大きな</Run>テキストです。
            <LineBreak />
                <Span FontSize="24">
                    <Bold>
                        <Italic>
                            <Underline>
                                <Span Background="Aqua">こんなこと</Span>もできます。
                            </Underline>
                        </Italic>
                    </Bold>
                </Span>
        </TextBlock>
    </StackPanel>
</Window>

サンプルコードの実行結果は以下のとおりです。

今回はTextBlockクラスのコンテントプロパティであるInlinesプロパティについて確認しました。

以上です。

コメント