2011-06-08 75 views
2

我想將DataTrigger添加到我的基本TextBox樣式中,以便它將前景色設置爲不同的值(如果它位於所選DataGridCell的內部)。這裏是我的觸發器是什麼樣子:如果RelativeSource不存在,則隱藏DataTrigger

<Style.Triggers> 
    <DataTrigger Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridCell}}, Path=IsSelected}" 
       Value="True"> 
     <Setter Property="Foreground" 
       Value="White" /> 
    </DataTrigger> 
</Style.Triggers> 

這個偉大的工程一樣,除了在我的文本框是不是在一個DataGrid綁定失敗,並寫入一個例外輸出窗口。我怎樣才能防止這一點。

我基本上想說如果Parent是一個DataGridCell然後應用這個觸發器,否則忽略它。

回答

5

一般來說,只適用於適用的風格。如果你想隱式應用程序中使用嵌套樣式:

<Style TargetType="{x:Type DataGrid}"> 
    <Style.Resources> 
     <Style TargetType="{x:Type TextBox}"> 
      <Style.Triggers> 
       <DataTrigger 
         Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridCell}}, Path=IsSelected}" 
         Value="True"> 
        <Setter Property="Foreground" Value="White" /> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 
    </Style.Resources> 
</Style> 

如果要適用於所有的文本框等部位取出這些部件在serarate建築風格,在它適用於內部的文本框的樣式使用BasedOn數據網格。


編輯: MultiDataTrigger似乎立即如果條件不滿足返回這樣就可以避免綁定錯誤:

<Style TargetType="{x:Type TextBox}"> 
    <Style.Resources> 
     <vc:HasAncestorOfTypeConverter x:Key="HasAncestorOfTypeConverter" AncestorType="{x:Type DataGridCell}" /> 
    </Style.Resources> 
    <Style.Triggers> 
     <MultiDataTrigger> 
      <MultiDataTrigger.Conditions> 
       <Condition 
         Binding="{Binding RelativeSource={RelativeSource Self}, Converter={StaticResource HasAncestorOfTypeConverter}}" 
         Value="True" /> 
       <Condition 
         Binding="{Binding RelativeSource={RelativeSource AncestorType={x:Type DataGridCell}}, Path=IsSelected}" 
         Value="True" /> 
      </MultiDataTrigger.Conditions> 
      <Setter Property="Foreground" Value="Red" /> 
     </MultiDataTrigger> 
    </Style.Triggers> 
</Style> 
public class HasAncestorOfTypeConverter : IValueConverter 
{ 
    public Type AncestorType { get; set; } 

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     if (value == null) return false; 
     DependencyObject current = value as DependencyObject; 
     while (true) 
     { 
      current = VisualTreeHelper.GetParent(current); 
      if (current == null) 
      { 
       return false; 
      } 
      if (current.GetType() == AncestorType) 
      { 
       return true; 
      } 
     } 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotSupportedException(); 
    } 
} 

這當然會導致相當索姆開銷等等它可能不是一個好的解決方案,然後再次如果RelativeSource綁定失敗,它也必須首先上去樹。

+0

謝謝H.但是這是設置在我們自定義外觀中的文件中。因爲會有多個皮膚覆蓋這個,所以我希望把所有的TextBox風格觸發器放在同一個文件中,而不是讓它們分離出來 - 你知道有什麼方法可以解決我特別提出的問題(也許通過使用MultiTrigger和編寫我自己的DataTrigger類或其他)? – 2011-06-08 20:34:40

+0

@MattWest:一個MultiDataTrigger可能會工作,但只有當下面的條件不被評估,如果第一個是否定的,不知道是否是這種情況。 (問題是輸出消息還是僅僅是綁定失敗?消息可能被敲除) – 2011-06-09 01:20:49

+0

輸出消息是主要問題 - 我該如何敲出來? – 2011-06-09 16:26:08