Search code examples
c#xamlwindows-store-appsuwp

Override ThemeResource for specific controls


I want to create a transparent TextBox, with no background color when focused (default is white, or SystemControlBackgroundChromeWhiteBrush). I understand that I can override the used color in the App.xaml like so:

<Application.Resources>
    <SolidColorBrush x:Key="SystemControlBackgroundChromeWhiteBrush">Transparent</SolidColorBrush>
</Application.Resources>

(or by using multiple ThemeDictionaries)

However I don't want to modify ALL TextBlocks but only specific ones. My first guess was to include the changed brush in the TextBlock's Resources, but this doesn't work.


Solution

  • You can modify default styles of control. HERE is the article how to find it.

    Get style of TextBox, insert it as a resource in XAML and modify, eg.:

       <!-- Default style for Windows.UI.Xaml.Controls.TextBox -->
     <Style TargetType="TextBox">
    <Setter Property="MinWidth" Value="{ThemeResource TextControlThemeMinWidth}" />
    <Setter Property="MinHeight" Value="{ThemeResource TextControlThemeMinHeight}" />
    <Setter Property="Foreground" Value="{ThemeResource TextBoxForegroundThemeBrush}" />
    <Setter Property="SelectionHighlightColor" Value="{ThemeResource TextSelectionHighlightColorThemeBrush}" />
    <Setter Property="Background" Value="{ThemeResource TextBoxBackgroundThemeBrush}" />
    <Setter Property="BorderBrush" Value="{ThemeResource TextBoxBorderThemeBrush}" />
    <Setter Property="BorderThickness" Value="{ThemeResource TextControlBorderThemeThickness}" />
    <Setter Property="FontFamily" Value="{ThemeResource PhoneFontFamilyNormal}" />
    <Setter Property="FontSize" Value="{ThemeResource ContentControlFontSize}" />
    <Setter Property="TextWrapping" Value="NoWrap" />
    <Setter Property="ScrollViewer.HorizontalScrollMode" Value="Auto" />
    <Setter Property="ScrollViewer.VerticalScrollMode" Value="Auto" />
    <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Hidden" />
    <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden" />
    <Setter Property="ScrollViewer.IsDeferredScrollingEnabled" Value="False" />
    <Setter Property="Padding" Value="{ThemeResource TextControlThemePadding}" />
    <Setter Property="Margin" Value="{ThemeResource TextControlMarginThemeThickness}" />
    <Setter Property="VerticalAlignment" Value="Top" />
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="TextBox">
          <Grid Background="Transparent">
            <VisualStateManager.VisualStateGroups>
              <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="Disabled">
                  <Storyboard>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="Background">
                      <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextBoxDisabledBackgroundThemeBrush}" />
                    </ObjectAnimationUsingKeyFrames>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
                      <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextBoxDisabledBorderThemeBrush}" />
                    </ObjectAnimationUsingKeyFrames>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentElement" Storyboard.TargetProperty="Foreground">
                      <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextBoxDisabledForegroundThemeBrush}" />
                    </ObjectAnimationUsingKeyFrames>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PlaceholderTextContentPresenter" Storyboard.TargetProperty="Foreground">
                      <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextBoxDisabledForegroundThemeBrush}" />
                    </ObjectAnimationUsingKeyFrames>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="HeaderContentPresenter" Storyboard.TargetProperty="Foreground">
                      <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextBoxDisabledHeaderForegroundThemeBrush}" />
                    </ObjectAnimationUsingKeyFrames>
                  </Storyboard>
                </VisualState>
                <VisualState x:Name="Normal">
                  <Storyboard>
                    <DoubleAnimation Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="Opacity" Duration="0"
                                     To="{ThemeResource TextControlBorderThemeOpacity}" />
                  </Storyboard>
                </VisualState>
                <VisualState x:Name="Focused">
                  <Storyboard>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="BorderBrush">
                      <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextSelectionHighlightColorThemeBrush}" />
                    </ObjectAnimationUsingKeyFrames>
                    <DoubleAnimation Storyboard.TargetName="PlaceholderTextContentPresenter" Storyboard.TargetProperty="Opacity" Duration="0" To="0" />
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="BorderElement" Storyboard.TargetProperty="Background">
                      <DiscreteObjectKeyFrame KeyTime="0" Value="{ThemeResource TextBoxFocusedBackgroundThemeBrush}" />
                    </ObjectAnimationUsingKeyFrames>
                  </Storyboard>
                </VisualState>
              </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            <Grid.RowDefinitions>
              <RowDefinition Height="Auto"/>
              <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Border x:Name="BorderElement" Grid.Row="1" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" />
            <ContentPresenter x:Name="HeaderContentPresenter" Grid.Row="0" Style="{StaticResource HeaderContentPresenterStyle}" Margin="{ThemeResource TextControlHeaderMarginThemeThickness}"
                              Content="{TemplateBinding Header}" ContentTemplate="{TemplateBinding HeaderTemplate}" />
            <ScrollViewer x:Name="ContentElement" Grid.Row="1" MinHeight="{ThemeResource TextControlThemeMinHeight}"
                          HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
                          HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
                          VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
                          VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
                          IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
                          IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
                          IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}" Margin="{TemplateBinding BorderThickness}"
                          Padding="{TemplateBinding Padding}" IsTabStop="False" ZoomMode="Disabled"
                          AutomationProperties.AccessibilityView="Raw"/>
            <ContentControl x:Name="PlaceholderTextContentPresenter" Grid.Row="1" Foreground="{ThemeResource TextBoxPlaceholderTextThemeBrush}"
                            FontSize="{ThemeResource ContentControlFontSize}" Margin="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}"
                            IsTabStop="False" Content="{TemplateBinding PlaceholderText}" />
          </Grid>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
    

    Next, add name to modified style:

    <Style  x:Name="CustomTextBlock" TargetType="TextBox">
    

    And apply it to your control, eg:

    <TextBlock Style="{StaticResource CustomTextBlock}"/>
    

    Here is the sample style for Transparent TextBox (WinRT/Universal Apps):

    <Style x:Key="TransparentTextBox"
               TargetType="TextBox">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="TextBox">
                        <Grid Background="Transparent">
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="*" />
                            </Grid.RowDefinitions>
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="CommonStates">
                                    <VisualState x:Name="Disabled">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush"
                                                                           Storyboard.TargetName="BorderElement">
                                                <DiscreteObjectKeyFrame KeyTime="0"
                                                                        Value="{ThemeResource TextBoxDisabledBorderThemeBrush}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground"
                                                                           Storyboard.TargetName="ContentElement">
                                                <DiscreteObjectKeyFrame KeyTime="0"
                                                                        Value="{ThemeResource TextBoxDisabledForegroundThemeBrush}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground"
                                                                           Storyboard.TargetName="PlaceholderTextContentPresenter">
                                                <DiscreteObjectKeyFrame KeyTime="0"
                                                                        Value="{ThemeResource TextBoxDisabledForegroundThemeBrush}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Foreground"
                                                                           Storyboard.TargetName="HeaderContentPresenter">
                                                <DiscreteObjectKeyFrame KeyTime="0"
                                                                        Value="{ThemeResource TextBoxDisabledHeaderForegroundThemeBrush}" />
                                            </ObjectAnimationUsingKeyFrames>
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Normal">
                                        <Storyboard>
                                            <DoubleAnimation Duration="0"
                                                             To="{ThemeResource TextControlBorderThemeOpacity}"
                                                             Storyboard.TargetProperty="Opacity"
                                                             Storyboard.TargetName="BorderElement" />
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Focused">
                                        <Storyboard>
                                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderBrush"
                                                                           Storyboard.TargetName="BorderElement">
                                                <DiscreteObjectKeyFrame KeyTime="0"
                                                                        Value="{ThemeResource TextSelectionHighlightColorThemeBrush}" />
                                            </ObjectAnimationUsingKeyFrames>
                                            <DoubleAnimation Duration="0"
                                                             To="0"
                                                             Storyboard.TargetProperty="Opacity"
                                                             Storyboard.TargetName="PlaceholderTextContentPresenter" />
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Border x:Name="BorderElement"
                                    BorderBrush="{TemplateBinding BorderBrush}"
                                    BorderThickness="{TemplateBinding BorderThickness}"
                                    Grid.Row="1" />
                            <ContentPresenter x:Name="HeaderContentPresenter"
                                              ContentTemplate="{TemplateBinding HeaderTemplate}"
                                              Content="{TemplateBinding Header}"
                                              Margin="{ThemeResource TextControlHeaderMarginThemeThickness}"
                                              Grid.Row="0"
                                              Style="{StaticResource HeaderContentPresenterStyle}" />
                            <ScrollViewer x:Name="ContentElement"
                                          AutomationProperties.AccessibilityView="Raw"
                                          HorizontalScrollMode="{TemplateBinding ScrollViewer.HorizontalScrollMode}"
                                          HorizontalScrollBarVisibility="{TemplateBinding ScrollViewer.HorizontalScrollBarVisibility}"
                                          IsTabStop="False"
                                          IsHorizontalRailEnabled="{TemplateBinding ScrollViewer.IsHorizontalRailEnabled}"
                                          IsVerticalRailEnabled="{TemplateBinding ScrollViewer.IsVerticalRailEnabled}"
                                          IsDeferredScrollingEnabled="{TemplateBinding ScrollViewer.IsDeferredScrollingEnabled}"
                                          Margin="{TemplateBinding BorderThickness}"
                                          MinHeight="{ThemeResource TextControlThemeMinHeight}"
                                          Padding="{TemplateBinding Padding}"
                                          Grid.Row="1"
                                          VerticalScrollBarVisibility="{TemplateBinding ScrollViewer.VerticalScrollBarVisibility}"
                                          VerticalScrollMode="{TemplateBinding ScrollViewer.VerticalScrollMode}"
                                          ZoomMode="Disabled" />
                            <ContentControl x:Name="PlaceholderTextContentPresenter"
                                            Content="{TemplateBinding PlaceholderText}"
                                            Foreground="{ThemeResource TextBoxPlaceholderTextThemeBrush}"
                                            FontSize="{ThemeResource ContentControlFontSize}"
                                            IsTabStop="False"
                                            Margin="{TemplateBinding BorderThickness}"
                                            Padding="{TemplateBinding Padding}"
                                            Grid.Row="1" />
                        </Grid>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    

    Furthermore, you can use Blend (tool installed with Visual Studio), to modify controls easier. HERE is the sample tutorial from Microsoft Virtual Academy how to use it with VS2013.