2011-10-19 21 views
3

我正在嘗試使用並瞭解樣式的XAML層次結構...在簡單,簡單的文本框中...遍及各處看到如何設置「禁用「基於」IsEnabled「標誌的背景顏色。太好了,明白了。嘗試繼承主題/樣式並應用其他觸發器

現在,我想有另一個派生自TextBox的類... MyTextBox。對於這個類,我有一個屬性(不依賴於屬性,所以我使用DataTrigger)。所以,我想保留正在工作的所有正常的TextBox動作,但是現在獲得新的觸發器來正確地將背景色更新爲其他顏色。所以,這就是我所擁有的。只是爲了澄清,我所有的顏色靜態資源是固體刷...

<Style TargetType="TextBox" > 
    <Setter Property="FontFamily" Value="Courier New" /> 
    <Setter Property="FontSize" Value="12" /> 
    <Setter Property="Foreground" Value="{StaticResource MyForeground}" /> 
    <Setter Property="Background" Value="{StaticResource MyBackground}" /> 
    <Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="TextBox"> 
     <Border Name="Bd" BorderThickness="{TemplateBinding BorderThickness}" 
      BorderBrush="{TemplateBinding BorderBrush}" 
      Background="{TemplateBinding Background}" 
      SnapsToDevicePixels="true"> 

      <ScrollViewer Name="PART_ContentHost" 
       Background="{TemplateBinding Background}" 
       SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> 
     </Border> 

     <ControlTemplate.Triggers> 
      <Trigger Property="IsEnabled" Value="False"> 
      <Setter Property="Background" Value="{StaticResource MyDisBackground}" /> 
      <Setter TargetName="PART_ContentHost" Property="Background" 
       Value="MyDisBackground"/> 
      </Trigger> 
     </ControlTemplate.Triggers> 
     </ControlTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

<!-- Now, my derived (or so I was hoping) style that just adds additional trigger --> 
<Style TargetType="local:MyTextBox" BasedOn="{StaticResource {x:Type TextBox}}" > 
    <Style.Triggers> 
    <DataTrigger Binding="{Binding Path=IsRequired}" Value="True"> 
     <Setter Property="Background" Value="{StaticResource RequiredBackground}" /> 
    </DataTrigger> 
    </Style.Triggers> 
</Style> 

我缺少一些簡單的東西?

回答

1

首先,您的DataTrigger正在查看您的MyTextBox(不是控制器本身)的DataContext。所以看的控制,你需要做這樣的事情:

<DataTrigger Binding="{Binding Path=IsRequired, RelativeSource={RelativeSource Self}}" Value="True"> 
    <Setter Property="Background" Value="{StaticResource RequiredBackground}" /> 
</DataTrigger> 

現在將設置MyTextBox.Background屬性時MyTextBox.IsRequired是真實的。但依賴項屬性值有一個precedence order。因此,上述在視覺上就會發生變化一樣使用背景:

<local:MyTextBox /> 

在下列情況下,您RequiredBackground刷將不會被使用。相反,你會看到MyDisBackground刷:

<local:MyTextBox IsEnabled="False" /> 

在這種情況下,ScrollViewer.Background改爲MyDisBackground,不再綁定到MyTextBox.Background財產。 MyTextBox.Background仍然是RequiredBackground,但它不再在任何地方使用。

最後,在下列情況下,您的RequiredBackground畫筆將不會使用。

<local:MyTextBox Background="Yellow" /> 

這裏,本地值(黃色)在優先列表中爲#3,而樣式設置者在#8。

如果你把你的財產的依賴屬性,默認爲false,那麼你可以這樣做:

<Style TargetType="TextBox" > 
    <Setter Property="FontFamily" Value="Courier New" /> 
    <Setter Property="FontSize" Value="12" /> 
    <Setter Property="Foreground" Value="{StaticResource MyForeground}" /> 
    <Setter Property="Background" Value="{StaticResource MyBackground}" /> 
    <Setter Property="Template"> 
    <Setter.Value> 
     <ControlTemplate TargetType="TextBox"> 
     <Border Name="Bd" BorderThickness="{TemplateBinding BorderThickness}" 
      BorderBrush="{TemplateBinding BorderBrush}" 
      Background="{TemplateBinding Background}" 
      SnapsToDevicePixels="true"> 

      <ScrollViewer Name="PART_ContentHost" 
       Background="{TemplateBinding Background}" 
       SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> 
     </Border> 

     <ControlTemplate.Triggers> 
      <Trigger Property="local:MyTextBox.IsRequired" Value="False"> 
      <Setter Property="Background" Value="{StaticResource RequiredBackground}" /> 
      <Setter TargetName="PART_ContentHost" Property="Background" 
       Value="RequiredBackground"/> 
      </Trigger> 
      <Trigger Property="IsEnabled" Value="False"> 
      <Setter Property="Background" Value="{StaticResource MyDisBackground}" /> 
      <Setter TargetName="PART_ContentHost" Property="Background" 
       Value="MyDisBackground"/> 
      </Trigger> 
     </ControlTemplate.Triggers> 
     </ControlTemplate> 
    </Setter.Value> 
    </Setter> 
</Style> 

<Style TargetType="local:MyTextBox" BasedOn="{StaticResource {x:Type TextBox}}" /> 

Eventhough的屬性不存在的文本框,它仍然可以得到的默認值的依賴屬性並觸發它。但由於它將被設置爲一個文本框,該觸發器將永遠不會被使用。

+0

好吧,我複製了你的代碼,並提出了CodeNaked列出的第一個建議修改** Binding =「{Binding Path = IsRequired,RelativeSource = {RelativeSource Self}}」**這種改變似乎是行得通的(假設你的' MyTextBox類實現了INotifyPropertyChanged和你的IsRequired屬性,我會發布我的代碼來告訴你我做了什麼......但是我不想發佈一個相互競爭的答案,因爲我不是那個真正想出它的人。 – Scott

+0

@Scott,感謝您的輸入,他們似乎正在按照我所希望的方式工作,並且看到在兩種情況下......一個是DependencyProperty,另一個是通過INotifyPropertyChanged(我已經擁有) – DRapp

+0

@DRapp,很高興看到你的解決方案能夠正常工作!在這兩種解決方案中,我確實更喜歡依賴屬性解決方案,因爲您可以直接在XAML中設置值。我只注意到你在你的問題中特別提到你沒有使用DependencyProperty,因此認爲你更願意避免它。 – Scott