【问题标题】:Is there a way to change Foreground of a TextBox ScrollViewer in xaml whithout change the local property?有没有办法在 xaml 中更改 TextBox ScrollViewer 的前景而不更改本地属性?
【发布时间】:2020-10-20 22:58:56
【问题描述】:

有没有办法在不更改本地主 Foreground 属性的情况下使用触发器或视觉状态更改 xaml 中自定义 TextBoxForeground

这是一个带有随机选择颜色的通用自定义 TextBox 的 xaml 样式:

<Style TargetType="{x:Type local:CustomTextBox}">
    <Setter Property="Background" Value="White"/>
    <Setter Property="BorderBrush" Value="Black"/>
    <Setter Property="Foreground" Value="Black"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CustomTextBox}">
                <Border x:Name="PART_Border"
                        Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="1">
                    <ScrollViewer x:Name="PART_ContentHost"
                                    HorizontalScrollBarVisibility="Hidden"
                                    VerticalScrollBarVisibility="Hidden"
                                    Focusable="False"/>
                </Border>
                <ControlTemplate.Triggers>
                    <!-- Can be IsMouseOver, IsFocused, etc... -->
                    <Trigger Property="IsMouseOver" Value="True"> 
                        <Setter TargetName="PART_Border" 
                                Property="Background" Value="Green"/>
                        <Setter TargetName="PART_Border" 
                                Property="BorderBrush" Value="DarkGreen"/>
                        <!-- The only method I know that works is this one
                             that changes the local property -->
                        <Setter Property="Foreground" Value="Yellow"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

我尝试在触发器中使用这些行,但每个人都失败了(什么都不做):

<Setter TargetName="PART_ContentHost" Property="Foreground" Value="Yellow"/>
<Setter TargetName="PART_ContentHost" Property="TextBlock.Foreground" Value="Yellow"/>
<Setter TargetName="PART_ContentHost" Property="TextElement.Foreground" Value="Yellow"/>
<Setter TargetName="PART_Border" Property="TextBlock.Foreground" Value="Yellow"/>
<Setter TargetName="PART_Border" Property="TextElement.Foreground" Value="Yellow"/>

在按钮中,可以通过更改父元素的TextBlock.Foreground(例如PART_BorderTextBlock.Foreground)来更改前景色,但这不适用于TextBox。

像此行一样更改本地属性...

<Setter Property="Foreground" Value="Yellow"/>

...有一个问题,如果我稍后更改主前景属性(例如从黑色到灰色),触发器不能再将其更改为黄色,例如:

<local:CustomTextBox ... Foreground="Gray"/>

VisualStates 甚至无法与主 Foreground 属性交互。

那么还有其他我不知道的方法可以在 xaml 中实现这一点,还是 wpf 的限制?

【问题讨论】:

    标签: wpf triggers textbox foreground visualstates


    【解决方案1】:

    如果您完全覆盖 ControlTemplate 会怎样?

        <TextBox Text="Hiho" Foreground="Red">
            <TextBox.Style>
                <Style TargetType="{x:Type TextBox}">
                    <Setter Property="Background" Value="White"/>
                    <Setter Property="BorderBrush" Value="Black"/>
                    <Setter Property="Foreground" Value="Black"/>
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type TextBox}">
                                <TextBox Name="TheContent" Text="{TemplateBinding Text}"/>
    
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter TargetName="TheContent" Property="Foreground" Value="Yellow"/>
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </TextBox.Style>
        </TextBox>
    

    【讨论】:

      【解决方案2】:

      您可以使用Storyboard 为属性设置动画。这将对本地值生效:

      <Window ...>
          <Window.Resources>
              <Style TargetType="{x:Type local:CustomTextBox}">
                  <Setter Property="Background" Value="White"/>
                  <Setter Property="BorderBrush" Value="Black"/>
                  <Setter Property="Foreground" Value="Black"/>
                  <Setter Property="Template">
                      <Setter.Value>
                          <ControlTemplate TargetType="{x:Type local:CustomTextBox}">
                              <Border x:Name="PART_Border"
                                  Background="{TemplateBinding Background}"
                                  BorderBrush="{TemplateBinding BorderBrush}"
                                  BorderThickness="1">
                                  <ScrollViewer x:Name="PART_ContentHost"
                                              HorizontalScrollBarVisibility="Hidden"
                                              VerticalScrollBarVisibility="Hidden"
                                              Focusable="False"/>
                              </Border>
                              <ControlTemplate.Triggers>
                                  <Trigger Property="IsMouseOver" Value="True">
                                      <Setter TargetName="PART_Border" Property="Background" Value="Green"/>
                                      <Setter TargetName="PART_Border" Property="BorderBrush" Value="DarkGreen"/>
                                      <Trigger.EnterActions>
                                          <BeginStoryboard x:Name="sb">
                                              <Storyboard>
                                                  <ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetProperty="Foreground">
                                                      <DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{x:Static Brushes.Yellow}"/>
                                                  </ObjectAnimationUsingKeyFrames>
                                              </Storyboard>
                                          </BeginStoryboard>
                                      </Trigger.EnterActions>
                                      <Trigger.ExitActions>
                                          <RemoveStoryboard BeginStoryboardName="sb" />
                                      </Trigger.ExitActions>
                                  </Trigger>
                              </ControlTemplate.Triggers>
                          </ControlTemplate>
                      </Setter.Value>
                  </Setter>
              </Style>
          </Window.Resources>
          <StackPanel>
              <local:CustomTextBox Margin="10" Text="sample text" Foreground="Red" />
          </StackPanel>
      </Window>
      

      【讨论】:

        猜你喜欢
        • 2021-02-25
        • 2020-04-09
        • 2020-02-29
        • 2018-11-29
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2018-08-08
        • 1970-01-01
        相关资源
        最近更新 更多