4.5 テキスト
4.5.1 より高度な文字列の表示
ContentControl オブジェクトの Content プロパティに string 型の文字列オブジェクトを与えることによって、コントロール上のコンテンツとして文字列を表示させることができましたが、これは簡易的な文字列の表示方法であって、柔軟性は高くありません。
より自由にテキストをレイアウトするには System.Windows.Controls.TextBlock クラスを利用します。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
このクラスのコンストラクタは、パラメータを受け取りません。
public TextBlock ()
表示するテキストは Text プロパティから設定または取得することができます。
[LocalizabilityAttribute(LocalizationCategory.Text)] public string Text { get; set; }
まずは、単純に TextBlock のインスタンスを生成して、ウィンドウ上にテキストを表示させてみましょう。
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は、テキストを設定しているだけで、それ以外のプロパティは全て既定の状態の TextBlock を表示しています。これだけでは Window オブジェクトの Content に文字列オブジェクトを直接設定した場合と差はありません。
TextBlock クラスのプロパティには、Control クラスと同様のフォントに関連するプロパティが公開されています。プロパティの名前や意味も Control クラスと同じものなので、詳細は「02_06 フォント」を参照してください。例えば FontFamily でフォントファミリを、FontSize でフォントサイズを指定することができます。
4.5.2 自動改行
既定では、TextBlock コントロールの幅が、テキストを十分に表示することができるサイズを保持していない場合、テキストの一部は TextBlock から漏れて表示されません。しかし、TextWrapping プロパティの設定を変更することで、テキストを表示する幅が十分に足りていない場合、自動的にテキストを改行させることができます。
public TextWrapping TextWrapping { get; set; }
TextWrapping プロパティには、テキストの折り返しを表す System.Windows.TextWrapping 列挙体のいずれかのメンバを設定します。
[LocalizabilityAttribute(LocalizationCategory.None, Readability=Readability.Unreadable)] public enum TextWrapping
既定では、テキストを折り返さないことを表す NoWrap メンバが設定されていますが、Wrap または WrapWithOverflow メンバを指定することで自動的にテキストが折り返すようになります。
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は、TextWrapping プロパティに Wrap メンバを設定しています。これによって TextBlock の幅がテキストの表示に不十分な場合、テキストが自動的に改行されます。改行には禁則処理が適用されているため「。」や「っ」などが単体で改行されることはありません。
4.5.3 テキストの配置
既定で、テキストは左揃えで表示されますが、TextAlignment プロパティの値を変更することで、テキストを中央揃えや右揃えで表示させることができます。
public TextAlignment TextAlignment { get; set; }
TextAlignment プロパティには System.Windows.TextAlignment 列挙体のいずれかのメンバを設定します。
[LocalizabilityAttribute(LocalizationCategory.None, Readability=Readability.Unreadable)] public enum TextAlignment
TextAlignment 列挙体には、以下のメンバが用意されています。
- Left - 左揃え
- Center - 中央揃え
- Right - 右揃え
- Justify - 両端揃え
これらのメンバを TextAlignment に設定することで、テキストの配置を変更することができます。
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は、TextBlock オブジェクトの TextAlignment プロパティに Center を設定しています。実行結果のように、テキストはコントロールの中央に揃えて表示されます。
4.5.4 インライン要素
これまでの TextBlock によるテキスト出力は真新しいものではありませんでした。こうしたテキストの表示作業は、従来の System.Windows.Forms 名前空間の Label コントロールでも可能です。しかし、WPF の TextBlock は HTML で表示するテキストのように、より自由度の高い書式付きのテキストを表示することができいます。
フォントの設定で、テキスト全体のフォントスタイルやサイズを変更することは容易ですが、テキストの一部だけを太字で強調したり、斜体にするというシナリオを想定してください。もしくは、テキストの一部分をハイパーリンクで表示することができればより便利になるかもしれません。HTML とブラウザを使えばこれらの作業は容易ですが、アプリケーション内でこうしたテキストを描画するのは、従来のプログラミング手法では簡単ではありません。
しかし、TextBlock クラスを用いればテキストをさらに細かい部品に分けて、構造的に管理することができます。テキストの個々の要素は Inlines プロパティで管理されます。
public InlineCollection Inlines { get; }
Inlines プロパティから、テキストの要素の配列を管理する InlineCollection クラスのオブジェクトを取得することができます。このオブジェクトに、テキストの要素を表す 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.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.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 オブジェクトが保有する子インラインを指定することができます。このオブジェクトが保有している子インラインは、太字として表示されることになります。
public Bold ()
public Bold (Inline childInline)
childInline に、子インラインとなる Inline オブジェクトを設定します。Italic や Underline クラス、Hyperlink クラスも Inline のサブクラスなので、太字や斜体、下線、ハイパーリンクを組み合わせたスタイルのテキストを表示するには、これらのオブジェクトを階層的に保有させます。
これら、Span 系クラスの最終的な子インラインとなるのは、指定した書式テ表示するべきテキストです。何もフォーマットされていない単純なテキストをインラインで表すには 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 オブジェクトが表すテキストを設定することができます。
public Run ()
public Run (string text)
Run オブジェクトが表すテキストは Text プロパティで設定・取得することができます。
public string Text { get; set; }
例えば、Bold クラスのオブジェクトの子インラインに Run オブジェクトを設定すれば、Run に設定されているテキストが太字で表示されることになります。HTML で表現するならば <B>Run オブジェクトのテキスト</B> という関係になります。Bold の子インラインに Italic を設定し、Italic の子インラインに Run を設定したならば <B><I>Run オブジェクトのテキスト</I></B> という関係になります。
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は、TextBlock のインラインに、様々な Span 系のオブジェクトを追加しています。ウィンドウに表示されるテキストの上から順番に、通常のテキスト、太字、斜体、下線、ハイパーリンク、そして一番下が以上の全ての要素を組み合わせたものとなります。ハイパーリンクはクリックすることができ、左クリックすることで Click イベントを発生させます。