WPF の Label でアンダーバーが消える理由と回避方法

WPF の Label にアンダーバー(_)を含む文字列を表示しようとすると、画面上で消えてしまうことがあります。この原因と 3 つの回避方法を解説します。

概要

WPF の Label コントロールに _ (アンダーバー)を含む文字列を設定すると、その文字が画面に表示されず消えてしまうことがある。
これは WPF の仕様によるものであり、原因と代表的な回避方法を整理する。


前提・対象環境


問題

LabelContent にアンダーバーを含む文字列(例: my_variable)を設定したとき、画面には myvariable のようにアンダーバーが欠落した状態で表示される。
また、_F のように書くと F に下線が付いた状態で表示されることがある。
バインドしている文字列データにアンダーバーが含まれている場合でも同様に消えてしまうため、動的なデータ表示でも問題が発生する。


原因・背景

Label は内部で AccessText というコントロールを使ってテキストを描画している。
AccessText はアンダーバーをアクセスキー(Alt キーと組み合わせてフォーカス移動を行うショートカット機能)の目印として解釈する。

具体的な挙動は以下のとおりである。

入力文字列 画面上の表示 解釈
_File File F がアクセスキーとして登録される
my_var myvar v がアクセスキーとして登録される
name_ name アンダーバーが末尾で消える

このため、データにアンダーバーが含まれているだけで、意図しない表示崩れが起きる。


解決方法

回避方法は主に 3 つある。用途に合わせて使い分けることを推奨する。


実装例

方法 1:アンダーバーを 2 つ重ねてエスケープする

__ と 2 つ続けて書くことで、画面に 1 つのアンダーバーが表示される。
XAML 側で静的に文字列を設定しているケースに向いている。

<Label Content="my__variable" />

方法 2:TextBlock コントロールに変更する

アクセスキー機能や Target プロパティによるフォーカス制御が不要であれば、LabelTextBlock に変更するのがベストプラクティスである。
TextBlockAccessText を使わないため、アンダーバーをそのまま表示できる。

<TextBlock Text="my_variable" />

バインドの場合も同様にそのまま動作する。

<TextBlock Text="{Binding VariableName}" />

方法 3:ContentTemplate で TextBlock を使う

Label を維持しつつ、動的バインドのデータにアンダーバーが含まれる場合でも正しく表示するには、ContentTemplateTextBlock を指定する。
これにより、LabelContentAccessText ではなく TextBlock で描画させることができる。

<Label Content="{Binding VariableName}">
    <Label.ContentTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding}" />
        </DataTemplate>
    </Label.ContentTemplate>
</Label>

アプリ全体で統一したい場合は、このテンプレートをスタイルとして定義する方法もある。

<Style x:Key="PlainLabel" TargetType="Label">
    <Setter Property="ContentTemplate">
        <Setter.Value>
            <DataTemplate>
                <TextBlock Text="{Binding}" />
            </DataTemplate>
        </Setter.Value>
    </Setter>
</Style>

注意点


代替案・比較

方法 メリット デメリット 適するケース
方法 1: __ でエスケープ XAML 1 箇所の修正で簡単 動的データには ViewModel 側の処理が必要 静的な文字列に個別で対処したい場合
方法 2: TextBlock に変更 最もシンプルで軽量 LabelTarget 機能は使えない 表示専用でアクセスキーが不要な場合
方法 3: ContentTemplate を変更 動的バインドにも対応できる コード量が増える Label を維持しつつ動的表示が必要

まとめ

WPF の Label でアンダーバーが消えるのは、内部の AccessText がアンダーバーをアクセスキーの目印として解釈するためである。

用途に応じて上記 3 つを使い分けることで、アンダーバーの表示崩れを確実に回避できる。