简体   繁体   English

我的TextBox控件模板有问题

[英]Having an issue with my TextBox control template

I am working on a simple textBox template, which is just two borders, one with a gradient background. 我正在研究一个简单的textBox模板,它只有两个边框,一个带有渐变背景。 Now, my specific issue is that I want to be able to set the foreground color of the textBox to whatever color I want and have it work correctly. 现在,我的特定问题是我希望能够将textBox的前景色设置为我想要的任何颜色,并使它正确运行。 However, I can't seem to get both the disabled foreground and enabled foreground colors to work together. 但是,我似乎无法同时使禁用的前景色和启用的前景色同时起作用。 If I set the foreground to red for example, when I disable the textBox, the foreground doesn't get changed to my disabled color. 例如,如果将前景设置为红色,则在禁用textBox时,前景不会更改为禁用的颜色。 I tried binding the foreground in the IsEnabled="true" trigger but that doesn't seem to work. 我尝试在IsEnabled =“ true”触发器中绑定前景,但这似乎不起作用。 The foreground always stays red, no matter if the textBox is enabled or not. 不管文本框是否启用,前景始终保持红色。

Can you please take a look at the below template and tell me what I am doing wrong? 您能否看一下下面的模板,然后告诉我我做错了什么? Also, please point out to me any other mistakes I may have made since I am new at creating templates. 另外,请向我指出自创建模板以来我可能犯的其他任何错误。

Thanks a lot. 非常感谢。

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

There are a few different issues here all working against you. 这里有一些不同的问题都对您不利。 The first is that you're setting a specific Foreground value on your control instance, which has a higher priority than values set from Trigger s in your Style for properties of the control itself. 首先是您要在控件实例上设置特定的前景值,该值比在StyleTrigger设置的控件本身属性的优先级更高。 This is different than properties set on elements inside the ControlTemplate , like "Border". 这与在ControlTemplate 内部的元素(如“边框”)上设置的属性不同。 The way you're using Trigger s to set the Border properties is illustrating that. 您使用Trigger设置Border属性的方式就说明了这一点。 Normally you would also want to use TemplateBinding s to pull in values set on your control instance as defaults, like Background , which are currently being ignored. 通常,您还希望使用TemplateBinding来拉取控件实例上设置的值作为默认值,例如Background ,当前被忽略。

To switch between two values of a property on your styled control, like you want to do with Foreground , you can use a Setter and a Trigger in your Style to provide a default and alternate value. 要在样式控件上的两个属性值之间切换,就像您要使用Foreground ,可以在Style使用SetterTrigger来提供默认值和备用值。 This is still subject to being overridden by a value set on an instance. 实例上设置的值仍然会覆盖它。 If you want to disallow instances overriding a Trigger set it up like the "Border" Trigger where you're setting values on elements inside the ControlTemplate . 如果要禁止实例覆盖Trigger则可以像设置“ ControlTemplate元素的值的“边界” Trigger一样设置它。

The last change I'd recommend is switching to StaticResource for the Brushes you're pulling into your Style . 我建议的最后一个更改是,将要拉入Style Brush切换到StaticResource。 In this case it probably won't make a difference, but in some cases a default Style can get pulled into a context that doesn't have any reference to the surrounding Resources from the file it was declared in. Using Static will guarantee that it will include those Resources no matter where it gets used. 在这种情况下,它可能没有什么区别,但是在某些情况下,可以将默认样式拖入上下文中,该上下文没有从声明该文件的文件中引用周围的资源。使用静态将保证它无论在哪里使用,都将包括那些资源。 You may not run into this but it's a good habit to get into when setting up Styles/Templates like this. 您可能不会遇到这种情况,但是在设置这样的样式/模板时,这是一个很好的习惯。

Here's your code with those improvements: 这些是经过改进的代码:

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

And the TextBox using only the Style settings: 和仅使用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" />

A couple ideas to try: 可以尝试以下几种方法:

  1. Get rid of one of your triggers. 摆脱您的触发器之一。 Having two opposing triggers may not be a good idea. 有两个相反的触发器可能不是一个好主意。 I would set the default Background , BorderBrush , and Foreground directly on your Border declaration, and remove the Enabled="True" trigger. 我将直接在Border声明中设置默认的BackgroundBorderBrushForeground ,并删除Enabled="True"触发器。 Then, debugging is only a matter of getting the Enabled="False" trigger right. 然后,调试仅是正确设置Enabled="False"触发器的问题。

  2. Add the TargetName property to setter for your Enabled="False" trigger. 为您的Enabled="False"触发器将TargetName属性添加到setter中。

  3. This is a longshot, but use UIElement.IsEnabled instead of just IsEnabled , like this: <Trigger Property="UIElement.IsEnabled"> . 这是一个长镜头,但请使用UIElement.IsEnabled而不是IsEnabled ,如下所示: <Trigger Property="UIElement.IsEnabled">

Hope something I've said here helps! 希望我在这里说过的话对您有所帮助!

The possible reason is that your DisabledBackgroundBrush is not visible at the point where you use your style. 可能的原因是在使用样式时看不到DisabledBackgroundBrush Please try to add the styles into the ControlTemplate 's resources: 请尝试将样式添加到ControlTemplate的资源中:

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

By the way, your control template doesn't honour the values of your properties. 顺便说一句,您的控件模板不支持您的属性的值。 For example, you should perhaps use something like 例如,您也许应该使用类似

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

in your control template. 在您的控制模板中。

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

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