This article is currently in the process of being translated into Japanese (~84% done).
The TextBlock control - Inline formatting
直前の記事ではTextBlockの単純文字列を表示し、必要なら折返し表示する基本機能を見てきました。テキストを表示するのにデフォルトではない色を使いましたが、TextBlockのすべてのテキストに静的な色を定義するだけでなく、もっと他のことをしたいならどうでしょうか。
幸いなことにTextBlockコントロールはインラインコンテンツをサポートしています。インラインクラスからの継承で全て構成されているような小さなコントロールは、大きなテキストの一部分のようにしてインラインで描画できます。執筆時点でサポートされているのは AnchoredBlock, Bold, Hyperlink, InlineUIContainer, Italic, LineBreak, Run, Span, Underlineです。そのほとんどを以下の例で示します。
ボールド、イタリック、アンダーライン
多分これらは最も単純なタイプのインラインエレメントです。その名前で何をするのかは想像がつくと思いますが、短い例でそれらの使い方を示します。
<Window x:Class="WpfTutorialSamples.Basic_controls.TextBlockInlineSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TextBlockInlineSample" Height="100" Width="300">
<Grid>
<TextBlock Margin="10" TextWrapping="Wrap">
TextBlock with <Bold>bold</Bold>, <Italic>italic</Italic> and <Underline>underlined</Underline> text.
</TextBlock>
</Grid>
</Window>
HTMLと同じように、テキストをBoldタグで囲むだけでボールドテキストを表示できます。他も同様です。これでアプリケーションで多様な表示を簡単に作成できます。
この3つの全てのタグは単にSpanエレメントの子クラスです。それらは所定の効果を得るためにSpanエレメントの特定のプロパティを設定しています。例えば、BoldタグはSapnエレメントに含まれるFontWeightプロパティを設定しているだけです。Italicエレメントも同様にFontStyleを設定しています。
改行
単純にテキストに改行を挿入します。前章のLineBreakエレメントを使った例を見て下さい。
ハイパーリンク
Hyperlinkエレメントはテキストにリンクを張ることが出来ます。それは現在のWindowsのテーマに合ったスタイルで描画されます。普通は赤のホバー効果と手の形のマウスカーソルを伴うアンダーラインの付いた青文字です。リンク先のURLを定義するためにNavigateUriプロパティを使います。以下に例を示します。
<Window x:Class="WpfTutorialSamples.Basic_controls.TextBlockHyperlinkSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TextBlockHyperlinkSample" Height="100" Width="300">
<Grid>
<TextBlock Margin="10" TextWrapping="Wrap">
This text has a <Hyperlink RequestNavigate="Hyperlink_RequestNavigate" NavigateUri="https://www.google.com">link</Hyperlink> in it.
</TextBlock>
</Grid>
</Window>
HyperlinkはWPFのPage内部でもページ間の移動に使われています。その場合は例で示したようなRequestNavigateイベントの特別なハンドルは無くてよいが、通常のWPFアプリケーションから外部URLへの移動の場合、このイベントとProcessクラスが少し必要になります。RequestNavigateイベントをサブスクライブすることにより、コードビハインド内の以下のような単純なイベントハンドラを使ってデフォルトブラウザでリンクされたURLを起動できます。
private void Hyperlink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
{
System.Diagnostics.Process.Start(e.Uri.AbsoluteUri);
}
Run
Runエレメントは全ての有効なSpanプロパティを使って文字列をスタイル出来ますが、Spanエレメントは他のインラインエレメントを含んでいるかもしれないので、Runエレメントはプレーンなテキストだけから成ります。これはSpanエレメントをより柔軟なものとし、その結果、ほとんどのケースでの論理的な選択となります。
Span
Spanエレメントはデフォルトでは特定の描画を行いません。しかし、フォントのサイズやスタイル、太さ、前景色、背景色などのほとんど全ての描画を設定できます。Spanエレメントの素晴らしいところは、他のインラインエレメントを内部に追加して、テキストとスタイルの高度な組み合わせも簡単に行えることです。次の例ではインラインSpinエレメントの多くの可能性を示すために、たくさんのSpinエレメントを使っています。
<Window x:Class="WpfTutorialSamples.Basic_controls.TextBlockSpanSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TextBlockSpanSample" Height="100" Width="300">
<Grid>
<TextBlock Margin="10" TextWrapping="Wrap">
This <Span FontWeight="Bold">is</Span> a
<Span Background="Silver" Foreground="Maroon">TextBlock</Span>
with <Span TextDecorations="Underline">several</Span>
<Span FontStyle="Italic">Span</Span> elements,
<Span Foreground="Blue">
using a <Bold>variety</Bold> of <Italic>styles</Italic>
</Span>.
</TextBlock>
</Grid>
</Window>
このように、シチュエーションによっては他になにも合理的なエレメントがないときや、テキストのフォーマットを始める時の空白のキャンバスが欲しいだけなら、Spanエレメントが最適です。
C#/コードビハインドからのテキストフォーマット
これまで見たようにXAMLによるテキストフォーマッティングは非常に簡単ですが、C#/コードビハインドからフォーマッティングしたいケースもあるでしょう。これは少し面倒になりますが、どのようにすればよいのか例を示します。
<Window x:Class="WpfTutorialSamples.Basic_controls.TextBlockCodeBehindSample"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TextBlockCodeBehindSample" Height="100" Width="300">
<Grid></Grid>
</Window>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Media;
namespace WpfTutorialSamples.Basic_controls
{
public partial class TextBlockCodeBehindSample : Window
{
public TextBlockCodeBehindSample()
{
InitializeComponent();
TextBlock tb = new TextBlock();
tb.TextWrapping = TextWrapping.Wrap;
tb.Margin = new Thickness(10);
tb.Inlines.Add("An example on ");
tb.Inlines.Add(new Run("the TextBlock control ") { FontWeight = FontWeights.Bold });
tb.Inlines.Add("using ");
tb.Inlines.Add(new Run("inline ") { FontStyle = FontStyles.Italic });
tb.Inlines.Add(new Run("text formatting ") { Foreground = Brushes.Blue });
tb.Inlines.Add("from ");
tb.Inlines.Add(new Run("Code-Behind") { TextDecorations = TextDecorations.Underline });
tb.Inlines.Add(".");
this.Content = tb;
}
}
}
これは可能性があり素晴らしく、この例のようにする必要がある場合もあるでしょう。しかし、この例はおそらくXAMLをさらによく理解する助けになります。