How to change TextBox placeholder text color for a specific item, not global

MSDN lists the styles and patterns for the TextBox class here . I can override these theme resources by creating a ResourceDictionary in App.xaml as follows:

 <Application.Resources> <ResourceDictionary> <ResourceDictionary.ThemeDictionaries> <ResourceDictionary x:Key="Default"> <SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush" Color="Yellow"/> </ResourceDictionary> </ResourceDictionary.ThemeDictionaries> </ResourceDictionary> </Application.Resources> 

but this will affect every TextBox in my application. How to install this theme only for a specific item?

I tried to put this dictionary in Page.Resources and even TextBox.Resources for TextBox , to which I want to apply it, but it does not work.

I really don't want to override Template to change this property.


EDIT . Heena's answer is close, but I would also like to set different colors for light and dark themes, because my text box has a transparent background color.

I managed to achieve this by saving Foreground="{ThemeResource TextBoxPlaceholderTextThemeBrush}" as part of the Template (in other words, the default template complies with the MSDN standard), and then specify in the page resources:

 <Page.Resources> <ResourceDictionary.ThemeDictionaries> <ResourceDictionary x:Key="Light"> <SolidColorBrush x:Key="TextBoxPlaceholderTextThemeBrush" Color="Blue"/> </ResourceDictionary> ... </ResourceDictionary.ThemeDictionaries> </Page.Resources> 

but now it means that I have to put the huge ControlTemplate text editor for the text field in my page resources, which in any case is an exact duplicate by default!

Is this TextBoxPlaceholderTextThemeBrush to how TextBoxPlaceholderTextThemeBrush resolved from a ControlTemplate ? that is, why does it detect my user dictionary by having a ControlTemplate defined in the same resource dictionary?

How should this be done? Should I just subclass the text field so that all this XAML can be moved to another file (even if it is intended for only one text field)?

+6
source share
2 answers

Assuming you are using the MSDN Style text box

Resource Remove the Foreground property from the Contencontrol in the template <ContentControl Foreground="{ThemeResource TextBoxPlaceholderTextThemeBrush}"/>

 <Page.Resources> <!--From MSDN : Default style for Windows.UI.Xaml.Controls.TextBox --> <Style x:Key="MsdnTextboxStyle" TargetType="TextBox"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="TextBox"> ..... ..... <ContentControl x:Name="PlaceholderTextContentPresenter" Grid.Row="1" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" IsTabStop="False" Grid.ColumnSpan="2" Content="{TemplateBinding PlaceholderText}" IsHitTestVisible="False"/> </ControlTemplate> </Setter.Value> </Setter> </Style> </Page.Resources> 

Xaml

  <StackPanel Orientation="Horizontal"> <TextBox PlaceholderText="PlaceholderText here..." Style="{StaticResource MsdnTextboxStyle}" Margin="20" Foreground="Red" Height="30" Width="120"> <TextBox.Resources> <Style TargetType="ContentControl"> <Setter Property="Foreground" Value="Green"/> </Style> </TextBox.Resources> </TextBox> <TextBox PlaceholderText="PlaceholderText here..." Style="{StaticResource MsdnTextboxStyle}" Margin="20" Foreground="Red" Height="30" Width="120"> <TextBox.Resources> <Style TargetType="ContentControl"> <Setter Property="Foreground" Value="Red"/> </Style> </TextBox.Resources> </TextBox> <TextBox PlaceholderText="PlaceholderText here..." Style="{StaticResource MsdnTextboxStyle}" Margin="20" Foreground="Red" Height="30" Width="120"> <TextBox.Resources> <Style TargetType="ContentControl"> <Setter Property="Foreground" Value="Blue"/> </Style> </TextBox.Resources> </TextBox> </StackPanel> 

enter image description here

Update

Resource

Remove the Foreground property from the Contencontrol in the template <ContentControl Foreground="{ThemeResource TextBoxPlaceholderTextThemeBrush}"/>

 <Page.Resources> <ResourceDictionary> <ResourceDictionary.ThemeDictionaries> <ResourceDictionary x:Key="Default"> <SolidColorBrush x:Key="ContentControlForeGround" Color="Red"></SolidColorBrush> <SolidColorBrush x:Key="ContentControlForeGround1" Color="Yellow"></SolidColorBrush> </ResourceDictionary> <ResourceDictionary x:Key="Light"> <SolidColorBrush x:Key="ContentControlForeGround" Color="Blue"></SolidColorBrush> <SolidColorBrush x:Key="ContentControlForeGround1" Color="SkyBlue"></SolidColorBrush> </ResourceDictionary> <ResourceDictionary x:Key="Dark"> <SolidColorBrush x:Key="ContentControlForeGround" Color="Green"></SolidColorBrush> <SolidColorBrush x:Key="ContentControlForeGround1" Color="Chocolate"></SolidColorBrush> </ResourceDictionary> </ResourceDictionary.ThemeDictionaries> <Style x:Key="TextBoxStyle1" TargetType="TextBox"> ..... <ContentControl x:Name="PlaceholderTextContentPresenter" Grid.ColumnSpan="2" Content="{TemplateBinding PlaceholderText}" IsHitTestVisible="False" IsTabStop="False" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}" Grid.Row="1"/> ...... </Style> </ResourceDictionary> </Page.Resources> 

Xaml

 <StackPanel Orientation="Horizontal"> <TextBox Style="{StaticResource TextBoxStyle1}" PlaceholderText="PlaceholderText here..." Margin="20" Foreground="Red" Height="30" Width="170"> <TextBox.Resources> <Style TargetType="ContentControl"> <Setter Property="Foreground" Value="{StaticResource ContentControlForeGround}"></Setter> </Style> </TextBox.Resources> </TextBox> <TextBox Style="{StaticResource TextBoxStyle1}" PlaceholderText="PlaceholderText here..." Margin="20" Foreground="Red" Height="30" Width="170"> <TextBox.Resources> <Style TargetType="ContentControl"> <Setter Property="Foreground" Value="{StaticResource ContentControlForeGround1}"></Setter> </Style> </TextBox.Resources> </TextBox> </StackPanel> 

enter image description here

+5
source

An old question that I know, but it seemed incredibly depressing that I had to create an entire copy of the TextBox style in order to edit the color of the placeholder for one or two TextBox elements.

So, I created this method, which can be used in separate text blocks as needed:

 public static void SetPlaceholderColor(TextBox textBox, Color color) { var textBoxContentGrid = VisualTreeHelper.GetChild(textBox, 0) as Grid; for (var i = 0; i < VisualTreeHelper.GetChildrenCount(textBoxContentGrid); i++) { var visualChild = VisualTreeHelper.GetChild(textBoxContentGrid, i); if ((string) visualChild.GetValue(FrameworkElement.NameProperty) != "PlaceholderTextContentPresenter") continue; var placeHolderContentControl = visualChild as ContentControl; if (placeHolderContentControl != null) placeHolderContentControl.Foreground = new SolidColorBrush(color); } } 

This should also work for PasswordBoxes, since the TextBox parameter should be easily replaced only using the "FrameworkElement"

0
source

Source: https://habr.com/ru/post/971376/


All Articles