2010-02-19 22 views
2

我正在研究一個簡單的文本框模板,它只是兩個邊框,一個帶有漸變背景。現在,我的具體問題是,我希望能夠將textBox的前景色設置爲我想要的任何顏色並使其正確工作。但是,我似乎無法同時獲得禁用前景和啓用前景色的功能。例如,如果我將前景設置爲紅色,當禁用文本框時,前景不會更改爲禁用的顏色。我嘗試在IsEnabled =「true」觸發器中綁定前景,但似乎不起作用。無論文本框是否啓用,前景總是保持紅色。對我的TextBox控件模板有問題

你可以看看下面的模板,告訴我我做錯了什麼嗎?另外,請指出我自從創建模板以來可能犯的任何其他錯誤。

非常感謝。

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

回答

3

這裏有幾個不同的問題都對你有效。首先,您要爲控件實例設置一個特定的前景值,該值的優先級高於StyleTriggers中爲控件本身的屬性設置的值。這與在,ControlTemplate內部的元件上設置的屬性不同,如「邊框」。您使用Trigger來設置Border屬性的方式說明了這一點。通常情況下,您還希望使用TemplateBinding s來將您的控件實例中設置的值作爲默認值,如Background,這些值當前被忽略。

要將屬性的兩個值之間你的風格的控制,切換像你想與Foreground做,你可以使用一個SetterTriggerStyle提供了默認和替代值。這仍然受到實例上設置的值的覆蓋。如果您想禁止覆蓋Trigger的實例將其設置爲像「邊框」Trigger那樣設置ControlTemplate內部元素的值。

我建議的最後更改是切換到您要拉入Style的筆刷的StaticResource。在這種情況下,它可能沒有什麼區別,但是在某些情況下,默認的Style可以被拉入到一個上下文中,該上下文不會從它聲明的文件中引用周圍的Resources。使用Static將保證它將包括這些資源,無論它在哪裏使用。您可能不會遇到這種情況,但在設置樣式/模板時,這是一個很好的習慣。

這裏是你的代碼的改進:

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

而且TextBox僅使用Style設置:

<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

一對夫婦的想法嘗試:

  1. 擺脫你的觸發器之一。有兩個相反的觸發器可能不是一個好主意。我會直接在您的Border聲明上設置默認的Background,BorderBrushForeground,並刪除Enabled="True"觸發器。然後,調試只是獲得Enabled="False"觸發器的權利。

  2. TargetName屬性添加到您的Enabled="False"觸發器的設置器。

  3. 這是一個遠射,但使用UIElement.IsEnabled,而不是僅僅IsEnabled,就像這樣:<Trigger Property="UIElement.IsEnabled">

希望我在這裏說的東西有所幫助!

1

可能的原因是您的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"/> 
在你的控制模板