WisdomSoft - for your serial experiences.

4.5 テキスト

テキストの表示や整形、太字や斜体などの書式設定の方法を解説します。

4.5.1 より高度な文字列の表示

ContentControl オブジェクトの Content プロパティに string 型の文字列オブジェクトを与えることによって、コントロール上のコンテンツとして文字列を表示させることができましたが、これは簡易的な文字列の表示方法であって、柔軟性は高くありません。

より自由にテキストをレイアウトするには System.Windows.Controls.TextBlock クラスを利用します。TextBlock を利用すれば、容易にテキストのデザインやレイアウトを行うことができます。

System.Windows.Controls.TextBlock クラス
System.Object 
   System.Windows.Threading.DispatcherObject 
     System.Windows.DependencyObject 
       System.Windows.Media.Visual 
         System.Windows.UIElement 
           System.Windows.FrameworkElement 
            System.Windows.Controls.TextBlock
[ContentPropertyAttribute("Inlines")] 
[LocalizabilityAttribute(LocalizationCategory.Text)] 
public class TextBlock : FrameworkElement, IContentHost, IAddChild, IServiceProvider

このクラスのコンストラクタは、パラメータを受け取りません。

TextBlock クラスのコンストラクタ
public TextBlock ()

表示するテキストは Text プロパティから設定または取得することができます。 

TextBlock クラス Text プロパティ
[LocalizabilityAttribute(LocalizationCategory.Text)] 
public string Text { get; set; }

まずは、単純に TextBlock のインスタンスを生成して、ウィンドウ上にテキストを表示させてみましょう。

コード1
using System;
using System.Windows;
using System.Windows.Controls;

class Test {
	[STAThread]
	public static void Main() {
		TextBlock textBlock = new TextBlock();
		textBlock.Text = "Kitty on your lap";

		Window wnd = new Window();
		wnd.Content = textBlock;

		Application app = new Application();
		app.Run(wnd);
	}
}
実行結果
コード1 実行結果

コード1は、テキストを設定しているだけで、それ以外のプロパティは全て既定の状態の TextBlock を表示しています。これだけでは Window オブジェクトの Content に文字列オブジェクトを直接設定した場合と差はありません。

TextBlock クラスのプロパティには、Control クラスと同様のフォントに関連するプロパティが公開されています。プロパティの名前や意味も Control クラスと同じものなので、詳細は「02_06 フォント」を参照してください。例えば FontFamily でフォントファミリを、FontSize でフォントサイズを指定することができます。

4.5.2 自動改行

既定では、TextBlock コントロールの幅が、テキストを十分に表示することができるサイズを保持していない場合、テキストの一部は TextBlock から漏れて表示されません。しかし、TextWrapping プロパティの設定を変更することで、テキストを表示する幅が十分に足りていない場合、自動的にテキストを改行させることができます。

TextBlock クラス TextWrapping プロパティ
public TextWrapping TextWrapping { get; set; }

TextWrapping プロパティには、テキストの折り返しを表す System.Windows.TextWrapping 列挙体のいずれかのメンバを設定します。

System.Windows.TextWrapping 列挙体
[LocalizabilityAttribute(LocalizationCategory.None, Readability=Readability.Unreadable)] 
public enum TextWrapping

既定では、テキストを折り返さないことを表す NoWrap メンバが設定されていますが、Wrap または WrapWithOverflow メンバを指定することで自動的にテキストが折り返すようになります。

コード2
using System;
using System.Windows;
using System.Windows.Controls;

class Test {
	[STAThread]
	public static void Main() {
		TextBlock textBlock = new TextBlock();
		textBlock.Text = "なななっ、なんてこと!一生の恥、今生の不覚だわっ!";
		textBlock.FontSize = 20;
		textBlock.TextWrapping = TextWrapping.Wrap;

		Window wnd = new Window();
		wnd.Content = textBlock;

		Application app = new Application();
		app.Run(wnd);
	}
}
実行結果
コード2 実行結果1 コード2 実行結果2

コード2は、TextWrapping プロパティに Wrap メンバを設定しています。これによって TextBlock の幅がテキストの表示に不十分な場合、テキストが自動的に改行されます。改行には禁則処理が適用されているため「。」や「っ」などが単体で改行されることはありません。

4.5.3 テキストの配置

既定で、テキストは左揃えで表示されますが、TextAlignment プロパティの値を変更することで、テキストを中央揃えや右揃えで表示させることができます。

TextBlock クラス TextAlignment プロパティ
public TextAlignment TextAlignment { get; set; }

TextAlignment プロパティには System.Windows.TextAlignment 列挙体のいずれかのメンバを設定します。

System.Windows.TextAlignment 列挙体
[LocalizabilityAttribute(LocalizationCategory.None, Readability=Readability.Unreadable)] 
public enum TextAlignment

TextAlignment 列挙体には、以下のメンバが用意されています。

  • Left - 左揃え
  • Center - 中央揃え
  • Right - 右揃え
  • Justify - 両端揃え

これらのメンバを TextAlignment に設定することで、テキストの配置を変更することができます。

コード3
using System;
using System.Windows;
using System.Windows.Controls;

class Test {
	[STAThread]
	public static void Main() {
		TextBlock textBlock = new TextBlock();
		textBlock.Text = "雑でした";
		textBlock.FontSize = 20;
		textBlock.TextAlignment = TextAlignment.Center;

		Window wnd = new Window();
		wnd.Content = textBlock;

		Application app = new Application();
		app.Run(wnd);
	}
}
実行結果
コード3 実行結果

コード3は、TextBlock オブジェクトの TextAlignment プロパティに Center を設定しています。実行結果のように、テキストはコントロールの中央に揃えて表示されます。

4.5.4 インライン要素

これまでの TextBlock によるテキスト出力は真新しいものではありませんでした。こうしたテキストの表示作業は、従来の System.Windows.Forms 名前空間の Label コントロールでも可能です。しかし、WPF の TextBlock は HTML で表示するテキストのように、より自由度の高い書式付きのテキストを表示することができいます。

フォントの設定で、テキスト全体のフォントスタイルやサイズを変更することは容易ですが、テキストの一部だけを太字で強調したり、斜体にするというシナリオを想定してください。もしくは、テキストの一部分をハイパーリンクで表示することができればより便利になるかもしれません。HTML とブラウザを使えばこれらの作業は容易ですが、アプリケーション内でこうしたテキストを描画するのは、従来のプログラミング手法では簡単ではありません。

しかし、TextBlock クラスを用いればテキストをさらに細かい部品に分けて、構造的に管理することができます。テキストの個々の要素は Inlines プロパティで管理されます。 

TextBlock クラス Inlines プロパティ
public InlineCollection Inlines { get; }

Inlines プロパティから、テキストの要素の配列を管理する InlineCollection クラスのオブジェクトを取得することができます。このオブジェクトに、テキストの要素を表す System.Windows.Documents.Inline クラスのオブジェクトを設定します。

System.Windows.Documents.Inline クラス
System.Object 
   System.Windows.Threading.DispatcherObject 
     System.Windows.DependencyObject 
       System.Windows.ContentElement 
         System.Windows.FrameworkContentElement 
           System.Windows.Documents.TextElement 
            System.Windows.Documents.Inline
public abstract class Inline : TextElement

Inline クラスは、テキストの要素を表す抽象クラスです。テキストや太字、斜体、アンダーラインなどの階層構造は、この Inline クラスを継承するサブクラスによって実装されます。

Inline を継承するサブクラスは様々ですが、太字や斜体を表現するクラスは、他の Inline オブジェクトを階層的に保有することが可能な System.Windows.Documents.Span クラスを継承しています。

System.Windows.Documents.Span クラス
System.Object 
   System.Windows.Threading.DispatcherObject 
     System.Windows.DependencyObject 
       System.Windows.ContentElement 
         System.Windows.FrameworkContentElement 
           System.Windows.Documents.TextElement 
             System.Windows.Documents.Inline 
              System.Windows.Documents.Span
[ContentPropertyAttribute("Inlines")]
public class Span : Inline

Span クラスも Inline を継承するクラスの 1 つですが、Span は、別の Inline オブジェクトを保有することができる性質を持ちます。太字や斜体を表現するには、目的の書式の対象となる Inline オブジェクトを含む必要があるため Span を継承します。これによって、HTML のように木構造的に Inline オブジェクトを組み合わせることができます。

Span クラスを継承するクラスには、太字を表す System.Windows.Documents.Bold クラス、斜体を表す System.Windows.Documents.Italic クラス、下線を表す System.Windows.Documents.Underline クラス、そしてハイパーリンクを表す System.Windows.Documents.Hyperlink クラスなどがあります。この場では、これらのクラスを代表して Bold クラスの宣言を紹介します。他の Span を継承するクラスも、Bold クラスとほとんど同じように利用することができます。 

System.Windows.Documents.Bold クラス
System.Object 
   System.Windows.Threading.DispatcherObject 
     System.Windows.DependencyObject 
       System.Windows.ContentElement 
         System.Windows.FrameworkContentElement 
           System.Windows.Documents.TextElement 
             System.Windows.Documents.Inline 
               System.Windows.Documents.Span 
                System.Windows.Documents.Bold
public class Bold : Span

Bold クラスのコンストラクタには、Bold オブジェクトが保有する子インラインを指定することができます。このオブジェクトが保有している子インラインは、太字として表示されることになります。

Bold クラスのコンストラクタ
public Bold ()
public Bold (Inline childInline)

childInline に、子インラインとなる Inline オブジェクトを設定します。Italic や Underline クラス、Hyperlink クラスも Inline のサブクラスなので、太字や斜体、下線、ハイパーリンクを組み合わせたスタイルのテキストを表示するには、これらのオブジェクトを階層的に保有させます。

これら、Span 系クラスの最終的な子インラインとなるのは、指定した書式テ表示するべきテキストです。何もフォーマットされていない単純なテキストをインラインで表すには System.Windows.Documents.Run クラスを使います。

System.Windows.Documents.Run クラス
System.Object 
   System.Windows.Threading.DispatcherObject 
     System.Windows.DependencyObject 
       System.Windows.ContentElement 
         System.Windows.FrameworkContentElement 
           System.Windows.Documents.TextElement 
             System.Windows.Documents.Inline 
              System.Windows.Documents.Run
[ContentPropertyAttribute("Text")] 
public class Run : Inline

Run クラスのコンストラクタには、Run オブジェクトが表すテキストを設定することができます。

Run クラスのコンストラクタ
public Run ()
public Run (string text)

Run オブジェクトが表すテキストは Text プロパティで設定・取得することができます。

Run クラス Text プロパティ
public string Text { get; set; }

例えば、Bold クラスのオブジェクトの子インラインに Run オブジェクトを設定すれば、Run に設定されているテキストが太字で表示されることになります。HTML で表現するならば <B>Run オブジェクトのテキスト</B> という関係になります。Bold の子インラインに Italic を設定し、Italic の子インラインに Run を設定したならば <B><I>Run オブジェクトのテキスト</I></B> という関係になります。

コード4
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;

class Test {
	[STAThread]
	public static void Main() {
		TextBlock textBlock = new TextBlock();
		textBlock.FontSize = 16;
		String text = "I have no interest in ordinary humans.\n";

		textBlock.Inlines.Add(new Run(text));
		textBlock.Inlines.Add(new Bold(new Run(text)));
		textBlock.Inlines.Add(new Italic(new Run(text)));
		textBlock.Inlines.Add(new Underline(new Run(text)));
		textBlock.Inlines.Add(new Hyperlink(new Run(text)));

		
		textBlock.Inlines.Add(
			new Bold(new Italic(
				new Underline(new Hyperlink(new Run("\n" + text)))
			))
		);

		Window wnd = new Window();
		wnd.Content = textBlock;

		Application app = new Application();
		app.Run(wnd);
	}
}
実行結果
コード4 実行結果

コード4は、TextBlock のインラインに、様々な Span 系のオブジェクトを追加しています。ウィンドウに表示されるテキストの上から順番に、通常のテキスト、太字、斜体、下線、ハイパーリンク、そして一番下が以上の全ての要素を組み合わせたものとなります。ハイパーリンクはクリックすることができ、左クリックすることで Click イベントを発生させます。