2013-04-10 60 views
1

我正在爲基本屬性網格創建一些樣式。例如,XAML將是是否有一種乾淨的方式來實現XAML中的祖先樣式觸發器WPF

<StackPanel Style="{StaticResource propertyGrid}" Orientation="Vertical" > 

    <ItemsControl Tag="property"> 
     <Label>Nodes</Label> 
     <TextBox Text="{Binding Nodes}"/> 
    </ItemsControl> 

    <ItemsControl Tag="property"> 
     <Label >Major Diameter</Label> 
     <TextBox Text="{Binding MajorDiameter}"/> 
    </ItemsControl> 

    <ItemsControl Tag="property"> 
     <Label>Minor Diameter</Label> 
     <TextBox Text="{Binding MinorDiameter}"/> 
    </ItemsControl> 

    <ItemsControl Tag="property"> 
     <Label>Excenter</Label> 
     <TextBox Text="{Binding Excenter}"> </TextBox> 
    </ItemsControl> 

</StackPanel> 

並且我的樣式遵循此邏輯。 中的標籤或文本框帶標籤property的ItemsControl會獲得特殊樣式。如果我 在做這爲僞CSS我更牙齒咬牙切齒我想通了,要做到這一點的一種方式後寫

ItemsControl.property Label { 
    Grid.Row: 0; 
    FontWeight: bold; 
    Padding:0,4,0,0; 
} 

ItemsControl.property TextBox { 
    Grid.Row: 1; 
    FontWeight: bold; 
} 

,這 是使用DataTriggers回顧了樹,而不是 CSS心態俯視樹。不過,我相當震驚地說,它的詳細程度是 。見下文。

<Style TargetType="StackPanel" x:Key="propertyGrid"> 
    <Style.Resources> 

     <Style TargetType="Label"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=Tag}" Value="property"> 
        <Setter Property="Grid.Row" Value="0"/> 
        <Setter Property="FontWeight" Value="Bold"/> 
        <Setter Property="Padding" Value="0,4,0,0"/> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 

     <Style TargetType="TextBox"> 
      <Style.Triggers> 
       <DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=Tag}" Value="property"> 
        <Setter Property="FontWeight" Value="Bold"/> 
        <Setter Property="Grid.Row" Value="1"/> 
       </DataTrigger> 
      </Style.Triggers> 
     </Style> 

     <Style TargetType="ItemsControl" x:Key="property"> 
      <Style.Triggers> 
       <Trigger Property="Tag" Value="property"> 
        <Setter Property="Focusable" Value="False"/> 
        <Setter Property="ItemsPanel"> 
         <Setter.Value> 
          <ItemsPanelTemplate> 
           <Grid Width="Auto"> 
            <Grid.ColumnDefinitions> 
             <ColumnDefinition Width="40*" /> 
            </Grid.ColumnDefinitions> 
            <Grid.RowDefinitions> 
             <RowDefinition /> 
             <RowDefinition /> 
            </Grid.RowDefinitions> 
           </Grid> 
          </ItemsPanelTemplate> 
         </Setter.Value> 
        </Setter> 
       </Trigger> 
      </Style.Triggers> 
     </Style> 
    </Style.Resources> 
</Style> 

我的問題是。這樣做有沒有捷徑或更好的符號?我很想 試圖編寫一個WPFCSS編譯器來處理這個;)我可以 寫一個MarkupExtension來清理它。如果可能的話,我寧願在設計時使用任何解決方案來工作 。

例如將有可能寫爲

<AncestorTrigger TargetType="ItemsControl" Path="Tag" Value="property"> 
    <Setter Property="Grid.Row" Value="0"/> 
    <Setter Property="FontWeight" Value="Bold"/> 
    <Setter Property="Padding" Value="0,4,0,0"/> 
</AncestorTrigger> 

這樣的延伸?這將比記得如何寫更容易

<DataTrigger Binding="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ItemsControl}}, Path=Tag}" Value="property"> 

回答

0

我寫了一個自定義行爲來解決這個問題,也可以在設計時使用。標記將

<DataTrigger 
    WPF:WhenParentTag.TargetType="{x:Type ItemsControl}" Value="property"> 

    <Setter Property="Grid.Row" Value="0"/> 
    <Setter Property="FontWeight" Value="Bold"/> 
    <Setter Property="Padding" Value="0,4,0,0"/> 

</DataTrigger> 

這是一個多一點理智。該擴展的代碼是

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 
using System.Threading.Tasks; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Markup; 

namespace My.WPF 
{ 
    public static class WhenParentTag 
    { 

     static WhenParentTag() 
     {} 

     public static readonly DependencyProperty 
      TargetTypeProperty = 
      DependencyProperty.RegisterAttached 
      ("TargetType" 
      , typeof(Type) 
      , typeof(WhenParentTag) 
      , new PropertyMetadata(null, TargetTypeChanged)); 

     public static void 
      TargetTypeChanged 
      (DependencyObject dob 
      , DependencyPropertyChangedEventArgs e) 
     { 
      var trigger = dob as DataTrigger; 
      if(trigger==null){ 
       return; 
      } 

      var type = e.NewValue as Type; 
      if (type == null) 
       return; 

      var binding = new Binding(); 
      var rel = new RelativeSource(RelativeSourceMode.FindAncestor) { AncestorType = type }; 
      binding.RelativeSource = rel; 
      binding.Path = new PropertyPath("Tag"); 
      trigger.Binding = binding; 
     } 

     public static Type 
      GetTargetType 
      (DataTrigger dp) 
     { 
      return (Type)dp.GetValue(TargetTypeProperty); 
     } 

     public static void 
      SetTargetType 
      (DataTrigger dp, 
      Type value) 
     { 
      dp.SetValue(TargetTypeProperty, value); 
     } 
    } 
} 

改進建議,歡迎。

相關問題