繁体   English   中英

我的TextBox控件模板有问题

[英]Having an issue with my TextBox control template

我正在研究一个简单的textBox模板,它只有两个边框,一个带有渐变背景。 现在,我的特定问题是我希望能够将textBox的前景色设置为我想要的任何颜色,并使它正确运行。 但是,我似乎无法同时使禁用的前景色和启用的前景色同时起作用。 例如,如果将前景设置为红色,则在禁用textBox时,前景不会更改为禁用的颜色。 我尝试在IsEnabled =“ true”触发器中绑定前景,但这似乎不起作用。 不管文本框是否启用,前景始终保持红色。

您能否看一下下面的模板,然后告诉我我做错了什么? 另外,请向我指出自创建模板以来我可能犯的其他任何错误。

非常感谢。

  <SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />
  <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE" />
  <SolidColorBrush x:Key="WindowBackgroundBrush" Color="#FFF" />
  <SolidColorBrush x:Key="SelectedBackgroundBrush" Color="#DDD" />


<Style x:Key="TextBoxControlTemplate1" TargetType="{x:Type TextBox}">
  <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
  <Setter Property="AllowDrop" Value="true"/>
  <Setter Property="Background" Value="#00000000"/>
  <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
  <Setter Property="VerticalContentAlignment" Value="Stretch"/>
  <Setter Property="FontFamily" Value="Segoe UI"/>
  <Setter Property="FontSize" Value="12"/>
  <Setter Property="Padding" Value="8,5,3,3"/>
  <Setter Property="BorderThickness" Value="0"/>
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="{x:Type TextBox}">
        <Grid>
          <Border BorderBrush="#FF000000" BorderThickness="2,2,2,2" CornerRadius="5,5,5,5" Padding="0,0,0,0" Width="Auto" Height="Auto" Background="#FF000000"/>
          <Border x:Name="Border" BorderBrush="#FFFFFFFF" BorderThickness="1,1,1,1" CornerRadius="5,5,5,5" Padding="0,0,0,0" Width="Auto" Height="Auto" Margin="2,2,2,2">
            <Border.Background>
              <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FF000000" Offset="0"/>
                <GradientStop Color="#FF4D4D4D" Offset="1"/>
              </LinearGradientBrush>
            </Border.Background>
          </Border>
          <ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
        </Grid>
        <ControlTemplate.Triggers>
          <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Background" Value="{DynamicResource DisabledBackgroundBrush}" TargetName="Border"/>
            <Setter Property="BorderBrush" Value="{DynamicResource DisabledBackgroundBrush}" TargetName="Border"/>
            <Setter Property="Foreground" Value="{DynamicResource DisabledForegroundBrush}"/>
          </Trigger>
          <Trigger Property="IsEnabled" Value="True">
            <Setter Property="Foreground" Value="{Binding Path=Foreground, RelativeSource={RelativeSource AncestorType={x:Type TextBox}}}"/>
          </Trigger>
        </ControlTemplate.Triggers>
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>


<TextBox Text="TEST" TextWrapping="Wrap" Canvas.Top="293.761" Canvas.Left="112" Style="{DynamicResource TextBoxControlTemplate1}" Height="28.724" Width="232.25" IsTabStop="False" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" IsEnabled="True" Foreground="#FFFF0000"/>

这里有一些不同的问题都对您不利。 首先是您要在控件实例上设置特定的前景值,该值比在StyleTrigger设置的控件本身属性的优先级更高。 这与在ControlTemplate 内部的元素(如“边框”)上设置的属性不同。 您使用Trigger设置Border属性的方式就说明了这一点。 通常,您还希望使用TemplateBinding来拉取控件实例上设置的值作为默认值,例如Background ,当前被忽略。

要在样式控件上的两个属性值之间切换,就像您要使用Foreground ,可以在Style使用SetterTrigger来提供默认值和备用值。 实例上设置的值仍然会覆盖它。 如果要禁止实例覆盖Trigger则可以像设置“ ControlTemplate元素的值的“边界” Trigger一样设置它。

我建议的最后一个更改是,将要拉入Style Brush切换到StaticResource。 在这种情况下,它可能没有什么区别,但是在某些情况下,可以将默认样式拖入上下文中,该上下文没有从声明该文件的文件中引用周围的资源。使用静态将保证它无论在哪里使用,都将包括那些资源。 您可能不会遇到这种情况,但是在设置这样的样式/模板时,这是一个很好的习惯。

这些是经过改进的代码:

<SolidColorBrush x:Key="DisabledForegroundBrush" Color="#888" />
<SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE" />

<Style x:Key="TextBoxControlTemplate1" TargetType="{x:Type TextBox}">
    <Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
    <Setter Property="AllowDrop" Value="true"/>
    <Setter Property="Background">
        <Setter.Value>
            <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FF000000" Offset="0"/>
                <GradientStop Color="#FF4D4D4D" Offset="1"/>
            </LinearGradientBrush>
        </Setter.Value>
    </Setter>
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="VerticalContentAlignment" Value="Stretch"/>
    <Setter Property="FontFamily" Value="Segoe UI"/>
    <Setter Property="FontSize" Value="12"/>
    <Setter Property="Padding" Value="8,5,3,3"/>
    <Setter Property="BorderThickness" Value="2"/>
    <Setter Property="BorderBrush" Value="#FF000000"/>
    <Setter Property="Foreground" Value="Red" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type TextBox}">
                <Grid>
                    <!--Take advantage of containment when possible to let the layout engine help you!-->
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="5" Padding="0" Background="#FF000000"/>
                    <Border x:Name="Border" BorderBrush="#FFFFFFFF" BorderThickness="1" CornerRadius="5" Padding="0" Margin="{TemplateBinding BorderThickness}"
                            Background="{TemplateBinding Background}"/>
                    <ScrollViewer Margin="0" x:Name="PART_ContentHost"/>
                </Grid>
                <ControlTemplate.Triggers>
                    <Trigger Property="IsEnabled" Value="False">
                        <Setter Property="Background" Value="{StaticResource DisabledBackgroundBrush}" TargetName="Border"/>
                        <Setter Property="BorderBrush" Value="{StaticResource DisabledBackgroundBrush}" TargetName="Border"/>
                    </Trigger>
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <Trigger Property="IsEnabled" Value="False">
            <Setter Property="Foreground" Value="{StaticResource DisabledForegroundBrush}"/>
        </Trigger>
    </Style.Triggers>
</Style>

和仅使用Style设置的TextBox

<TextBox Text="TEST" TextWrapping="Wrap" Canvas.Top="293.761" Canvas.Left="112" Style="{DynamicResource TextBoxControlTemplate1}" 
         Height="28.724" Width="232.25" IsTabStop="False" HorizontalContentAlignment="Right" VerticalContentAlignment="Center" />

可以尝试以下几种方法:

  1. 摆脱您的触发器之一。 有两个相反的触发器可能不是一个好主意。 我将直接在Border声明中设置默认的BackgroundBorderBrushForeground ,并删除Enabled="True"触发器。 然后,调试仅是正确设置Enabled="False"触发器的问题。

  2. 为您的Enabled="False"触发器将TargetName属性添加到setter中。

  3. 这是一个长镜头,但请使用UIElement.IsEnabled而不是IsEnabled ,如下所示: <Trigger Property="UIElement.IsEnabled">

希望我在这里说过的话对您有所帮助!

可能的原因是在使用样式时看不到DisabledBackgroundBrush 请尝试将样式添加到ControlTemplate的资源中:

<ControlTemplate TargetType="{x:Type TextBox}">
    <ControlTemplate.Resources>
        <SolidColorBrush x:Key="DisabledBackgroundBrush" Color="#EEE" />
        ...
    </ControlTemplate.Resources>
    ...

顺便说一句,您的控件模板不支持您的属性的值。 例如,您也许应该使用类似

<ScrollViewer Margin="{TemplateBinding Padding}" x:Name="PART_ContentHost"/>

在您的控制模板中。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM