【问题标题】:Override ThemeResource for specific controls覆盖特定控件的 ThemeResource
【发布时间】:2015-10-26 17:54:53
【问题描述】:

我想创建一个透明的文本框,焦点时没有背景颜色(默认为白色,或SystemControlBackgroundChromeWhiteBrush)。 我知道我可以像这样覆盖 App.xaml 中使用的颜色:

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

(或通过使用多个主题词典)

但是,我不想修改所有 TextBlock,而只修改特定的。我的第一个猜测是在 TextBlock 的资源中包含更改后的画笔,但这不起作用。

【问题讨论】:

    标签: c# xaml windows-store-apps uwp


    【解决方案1】:

    您可以修改控件的默认样式。 HERE是如何找到它的文章。

    获取TextBox的样式,作为XAML中的资源插入并修改,例如:

       <!-- 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>
    

    接下来,为修改后的样式添加名称:

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

    并将其应用于您的控件,例如:

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

    这是透明文本框(WinRT/通用应用程序)的示例样式:

    <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>
    

    此外,您可以使用 Blend(随 Visual Studio 安装的工具),更轻松地修改控件。 HERE 是来自 Microsoft Virtual Academy 如何使用的示例教程它与 VS2013.

    【讨论】:

    • 感谢您的回复,我希望不必为了更改这样一个次要属性而复制整个默认样式:/
    • 恐怕无法通过单个属性更改焦点控件的背景,因为 TextBox 有很多状态(如您所见)。在 Focused 状态下设置透明度的最简单方法是修改默认样式。您可以将其放入不同的文件 Resource Dictionary 并随时使用。我通过添加具有透明度的文本框来编辑我的答案,您可以将其应用于所需的文本框。
    【解决方案2】:

    您可以使用类似于 CSS 的样式并将它们仅应用于特定控件:

    <Style x:Key="TransparentTextBox" TargetType="{x:Type TextBox}">
            <Setter Property="Background" Value="Transparent" />
    </Style>
    

    然后在控件上引用你要使用的样式:

    <TextBox Style="{StaticResource TransparentTextBox}"  />
    

    希望这会有所帮助。

    【讨论】:

    • 我想,仅在控制焦点时才需要更改背景是不够的。可能有必要修改特定的控制状态(如下面的较长答案所述)。
    • 这不起作用。当控件获得焦点时,我用于 Background 的任何值都会被白色覆盖。
    • 详细说明。这在 UWP 环境中不起作用,而仅在 WPF 中起作用。
    猜你喜欢
    • 2015-07-29
    • 1970-01-01
    • 2021-07-19
    • 1970-01-01
    • 2013-07-15
    • 2011-12-26
    • 2016-07-22
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多