Why WPF Label Hides Underscores and How to Fix It

When a string containing an underscore (_) is set on a WPF Label, the character disappears from the screen. This article explains the cause and three ways to work around it.

Overview

When a string containing _ (underscore) is set as the Content of a WPF Label control, the underscore is not rendered and disappears from the display.
This behavior is by design in WPF. This article explains the cause and the representative workarounds.


Prerequisites / Environment


Problem

When a string containing an underscore (for example, my_variable) is set on a Label’s Content, the screen displays myvariable with the underscore missing.
When the string contains _F, the letter F is rendered with an underline instead of showing _F as-is.
The same issue occurs with dynamically bound data: if the bound string contains an underscore, it is silently dropped from the display.


Cause / Background

Label internally uses a control called AccessText to render its text.
AccessText interprets underscores as markers for access keys — the shortcut feature that moves focus to a control when the corresponding Alt key combination is pressed.

The specific rendering behavior is as follows:

Input string Rendered output Interpretation
_File File F is registered as an access key
my_var myvar v is registered as an access key
name_ name Trailing underscore is silently dropped

As a result, any underscore in the bound data causes unintended display corruption.


Solution

There are three main workarounds. Choose the one that fits the situation.


Implementation

Workaround 1: Escape underscores by doubling them

Writing __ renders a single underscore on screen.
This approach is suitable when the string is set statically in XAML.

<Label Content="my__variable" />

Workaround 2: Replace Label with TextBlock

If the access-key feature and the Target property for focus navigation are not needed, replacing Label with TextBlock is the best practice.
TextBlock does not use AccessText, so underscores are displayed as-is.

<TextBlock Text="my_variable" />

Dynamic binding works the same way without any special handling.

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

Workaround 3: Customize ContentTemplate to use TextBlock

To keep Label while correctly rendering bound strings that contain underscores, set a ContentTemplate that uses TextBlock for the content.
This causes Label to render its Content through TextBlock instead of AccessText.

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

For application-wide consistency, the template can be extracted into a shared style.

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

Notes


Alternatives / Comparison

Approach Advantage Disadvantage Best suited for
Workaround 1: Escape with __ Simple one-line XAML change Requires replacement logic in code for dynamic data Fixing individual static strings in XAML
Workaround 2: Switch to TextBlock Simplest and most lightweight Label’s Target feature is unavailable Display-only text where access keys are unused
Workaround 3: Override ContentTemplate Handles dynamic bound data correctly More verbose XAML Keeping Label with dynamic string binding

Summary

Underscores disappear in WPF Label because the internal AccessText control interprets them as access-key markers.

Choosing the right approach based on the use case ensures that underscores are always displayed correctly.