如何更改特定元素的TextBox占位符文本颜色,而不是全局

时间:2014-06-26 11:37:41

标签: xaml windows-runtime windows-store-apps windows-8.1

MSDN列出了TextBoxhere的样式和模板。我可以通过在ResourceDictionary中创建App.xaml来覆盖这些主题资源:

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

但这会影响我的应用中的每个TextBox如何仅为特定元素设置此主题?

我已尝试将此词典放在Page.Resources甚至TextBox.Resources中,用于我想要应用它的TextBox,但它不起作用。< / p>

真的不想重新定义Template只是为了更改此属性。


编辑 Heena的答案很接近,但我还想为浅色和深色主题设置不同的颜色,因为我的文本框具有透明的背景色。

我设法通过将Foreground="{ThemeResource TextBoxPlaceholderTextThemeBrush}"作为Template的一部分来实现这一目标(换句话说,模板完全是MSDN的默认模板),然后在页面资源中指定:< / p>

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

但是现在这意味着我必须在我的页面资源中为文本框添加一个巨大的ControlTemplate样式设置器,这只是默认的完全重复!

这是否与TextBoxPlaceholderTextThemeBrush中解决ControlTemplate的方式有关?即它发现我的自定义主题词典的原因是因为ControlTemplate是在同一资源词典中定义的?

这应该如何完成?我应该只是对文本框进行子类化,以便将所有XAML移动到另一个文件中(即使它仅用于一个文本框)?

2 个答案:

答案 0 :(得分:6)

假设您使用的是MSDN文本框Style

<强>资源 从模板<ContentControl Foreground="{ThemeResource TextBoxPlaceholderTextThemeBrush}"/>

中的Contencontrol中删除前景属性
<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

<强>更新

资源

从模板<ContentControl Foreground="{ThemeResource TextBoxPlaceholderTextThemeBrush}"/>

中的Contencontrol中删除前景属性
<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

答案 1 :(得分:0)

老问题我知道,但我发现我必须创建一个TextBox样式的完整副本才能编辑一个或两个TextBox元素的占位符颜色,这令人难以置信。

所以我创建了这个方法,可以根据需要在单个TextBox上使用:

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);
    }
}

这也适用于PasswordBoxes,因为TextBox参数应该可以轻松替换为“FrameworkElement”