[Feature] Add WatermarkForeground property to TextBox
Is your feature request related to a problem? Please describe.
Currently, there is no way to customize the foreground color of the watermark (placeholder) text in TextBox and related controls. The watermark text color is determined solely by the theme's default placeholder foreground resources, which change based on control state (normal, focused, disabled, pointer over).
Describe the solution you'd like
Add a WatermarkForeground property to TextBox.
public class TextBox : TemplatedControl
{
/// <summary>
/// Defines the <see cref="WatermarkForeground"/> property
/// </summary>
public static readonly StyledProperty<IBrush?> WatermarkForegroundProperty =
AvaloniaProperty.Register<TextBox, IBrush?>(nameof(WatermarkForeground));
/// <summary>
/// Gets or sets the brush that is used for the watermark text.
/// </summary>
public IBrush? WatermarkForeground
{
get => GetValue(WatermarkForegroundProperty);
set => SetValue(WatermarkForegroundProperty, value);
}
}
- Should work with both regular watermarks and floating watermarks.
Examples:
<!-- Custom watermark color -->
<TextBox Watermark="Enter your name" WatermarkForeground="Red" />
<!-- Floating watermark with custom color -->
<TextBox Watermark="Email Address"
WatermarkForeground="Green"
UseFloatingWatermark="True" />
Describe alternatives you've considered
No response
Additional context
References:
- UWP/WinUI:
PlaceholderForegroundproperty https://learn.microsoft.com/en-us/uwp/api/windows.ui.xaml.controls.textbox.placeholderforeground and https://learn.microsoft.com/en-us/windows/windows-app-sdk/api/winrt/microsoft.ui.xaml.controls.textbox.placeholderforeground - WPF: No built-in watermark, but community implementations use foreground properties
- Flutter: TextField has
hintStylewith color customization - React Native: TextInput has
placeholderTextColorprop
I wouldn't say "no" way. As an outsider, this is the type of case template selectors were supposed to solve -- setting/customizing properties in ControlTemplates, especially ones that aren't set to keyed resources that can be replaced (ie. Lightweight Styling). See:
<UserControl>
<UserControl.Styles>
<Style Selector="TextBox /template/ TextBlock#PART_Watermark">
<Setter Property="Foreground" Value="Orange" />
</Style>
</UserControl.Styles>
<StackPanel>
<TextBox Watermark="This is the watermark" />
</StackPanel>
</UserControl>
Of course, this falls apart a bit because TextBox has other selectors with higher priority when hovered, etc, and the Foreground for the watermark changes. For now, you have to hack this to increase the BindingPriority or otherwise apply a lot of conditional selectors (which override the TextBox selectors due to tree locality). See hack below:
<UserControl>
<UserControl.Styles>
<Style Selector="TextBox:not(.priorityhack) /template/ TextBlock#PART_Watermark">
<Setter Property="Foreground" Value="Orange" />
</Style>
</UserControl.Styles>
<StackPanel>
<TextBox Watermark="This is the watermark" />
</StackPanel>
</UserControl>
Notes from the API review meeting:
- We're going to accept that API as it's difficult to style properly without hacks, as mentioned above.
- Plus, we already have a precedent with
ComboBox.PlaceholderForeground.
(We might want to unify the Watermark and Placeholder naming in the future.)
The new property should be added to all controls having a Watermark property:
CalendarDatePickerTextBoxNumericUpDownAutoCompleteBox