XAML での空白の処理
XAML の言語規則では、XAML プロセッサの実装によって重要な空白を処理する必要があると定められています。 ここでは、これらの XAML 言語規則について説明します。また、XAML プロセッサの Windows Presentation Foundation (WPF) 実装およびシリアル化用の XAML ライターで定義されている追加の空白処理についても説明します。
このトピックは、次のセクションで構成されています。
- 空白の定義
- 空白の標準化
- 内部テキスト内の空白、および文字列プリミティブ
- 空白の保持
- 東アジア言語の文字
- 空白とテキスト コンテンツ モデル
- 関連トピック
空白の定義
XML と同様に、XAML の空白文字は、スペース、ラインフィード、およびタブです。 これらは、それぞれ Unicode 値の 0020、000A、および 0009 に対応します。
空白の標準化
既定では、XAML プロセッサで XAML ファイルを処理する場合、次に示す空白の標準化が行われます。
東アジア言語の文字間のラインフィード文字は削除されます。 この用語の定義については、後の「東アジア言語の文字」を参照してください。
すべての空白文字 (スペース、ラインフィード、タブ) は、スペースに変換されます。
連続した複数のスペースはすべて削除され、1 つのスペースに置換されます。
開始タグの直後にあるスペースは削除されます。
終了タグの直前にあるスペースは削除されます。
"既定" とは、xml:space 属性の既定値で表される状態に対応します。
内部テキスト内の空白、および文字列プリミティブ
前の正規化規則は、XAML 要素内で検出された内部テキストに適用されます。 正規化の後、XAML プロセッサはすべての内部テキストを適切な型に次のように変換します。
プロパティの型がコレクションでなく、直接的に Object 型でない場合、XAML プロセッサはその型の型コンバーターを使用して、その型への変換を試みます。 その際、変換に失敗すると、コンパイル時のエラーが発生します。
プロパティの型がコレクションで、内部テキストが連続している (間に要素タグがない) 場合、その内部テキストは単一の String として解析されます。 そのコレクション型が String を受け入れない場合にも、コンパイル時のエラーが発生します。
プロパティの型が Object である場合、その内部テキストは単一の String として解析されます。 その内部テキストの中に要素タグが含まれている場合には、コンパイル時のエラーが発生します。これは、Object 型は単一のオブジェクト (String など) を示しているためです。
プロパティの型がコレクションであり、内部テキストが連続していないことがあります。この場合、最初の部分文字列は String に変換されてコレクション項目として追加されます。中間にある要素はコレクション項目として追加され、この要素の後に続く部分文字列 (存在する場合) は 3 番目の String 項目としてコレクションに追加されます。
空白の保持
ソース XAML で空白を保持し、XAML プロセッサによる空白の標準化の影響を受けずに最終的に表示されるようにするには、いくつかの手法があります。
xml:space="preserve" : 空白を保持する必要がある要素のレベルでこの属性を指定します。 この場合、コード編集アプリケーションが配置された要素を視覚的にわかりやすい入れ子として "美しく表示する" ために追加したスペースも含めて、すべての空白が保持されます。 ただし、これらのスペースが表示されるかどうかは、スペースを含んでいる要素のコンテンツ モデルによって決まります。 オブジェクト モデルの大多数では、属性の設定にかかわらず、空白が重要な空白と見なされることはないため、xml:space="preserve" をルート レベルで指定しないでください。 グローバルに xml:space を設定すると、一部の実装で XAML 処理 (特にシリアル化) のパフォーマンスに影響することがあります。 この属性は、文字列内の空白を表示する要素のレベル、または空白が重要なコレクションである要素のレベルでのみ設定することをお勧めします。
エンティティおよび改行しないスペース : XAML では、テキスト オブジェクト モデル内に任意の Unicode エンティティを配置できます。 非区切りスペース (UTF-8 エンコーディングでは  ) など、専用のエンティティを使用できます。 非区切りスペース文字をサポートするリッチ テキスト コントロールも使用できます。 インデントなどのレイアウト特性をシミュレートするためにエンティティを使用する場合には、パネルや余白の適切な使用など、エンティティの実行時出力が、一般的なレイアウト システムにおけるインデントの生成機能を使用した場合よりも多くの要因に基づいて変化するため、注意が必要です。 たとえば、エンティティはフォントにマッピングされ、ユーザーのフォント選択に応じてサイズが変わる可能性があります。
東アジア言語の文字
"東アジア言語の文字" は、U+20000 ~ U+2FFFD および U+30000 ~ U+3FFFD の範囲の Unicode 文字のセットとして定義されています。 このサブセットは、"CJK 表意文字" と呼ばれることもあります。 詳細については、http://www.unicode.org を参照してください。
空白とテキスト コンテンツ モデル
実際には、空白の保持は、すべてのコンテンツ モデルのサブセットに関してのみ問題になります。 このサブセットは、ある種のシングルトン String 型、専用の String コレクション、または IList や ICollection<T> コレクションでの String と他の型の組み合わせをとることのできるコンテンツ モデルから構成されます。
WPF での空白とテキスト コンテンツ モデル
説明しやすくするために、このセクションの残りの部分では、WPF によって定義された特定の型を参照します。 このトピックで説明する空白の処理機能は、.NET Framework XAML サービスと WPF の両方で一般的に使用されています。 これらの動作を実際に見るには、いくつかの WPF XAML マークアップを使用して、オブジェクト グラフでその結果を確認し、再度マークアップにシリアル化してください。
文字列をとることのできるコンテンツ モデルの場合でも、これらのコンテンツ モデル内での既定の動作では、残っているすべての空白は、重要な空白としては扱われません。 たとえば、ListBox は IList を使用しますが、空白 (各 ListBoxItem の間のライン フィードなど) は保持も表示もされません。 ライン フィードを ListBoxItem 項目の文字列間の区切り記号として使用しても、まったく機能しません。ライン フィードで区切られた文字列は、1 つの文字列および 1 つの項目として扱われます。
空白を重要な空白として扱うコレクションは、通常はフロー ドキュメント モデルの一部です。 空白の保持動作をサポートする主なコレクションには、InlineCollection があります。 このコレクション クラスは WhitespaceSignificantCollectionAttribute を使用して宣言されます。この属性が検出されると、XAML プロセッサはコレクション内の空白を重要な空白として扱います。 xml:space="preserve" と、WhitespaceSignificantCollectionAttribute を指定したコレクション内の空白の組み合わせでは、すべての空白は保持され、表示されます。 xml:space="default" と、WhitespaceSignificantCollectionAttribute 内の空白の組み合わせでは、前に説明した空白の初期正規化が行われます。この場合、一定の位置に 1 つの空白が残され、その空白は保持され、表示されます。 どちらの動作が望ましいかは、開発者の意図によって異なります。そのため、xml:space は、必要な動作が有効となるように、選択的に使用する必要があります。
また、フロー ドキュメント モデルで改行を意味する特定のインライン要素では、空白が重要なコレクションでも、余分なスペースを挿入しないように注意する必要があります。 たとえば、LineBreak 要素の用途は HTML の <BR/> タグと同じですが、マークアップの読みやすさのために、LineBreak は通常、追加されたライン フィードによって後続のテキストから区切られます。 そのラインフィードは、標準化されて後続の行の先頭のスペースとなることはできません。 その動作を有効にするために、LineBreak 要素のクラス定義は TrimSurroundingWhitespaceAttribute を適用します。これが XAML プロセッサによって解釈されて、LineBreak を囲む空白が常にトリミングされます。