2013-04-10 61 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); 
     } 
    } 
} 

改进建议,欢迎。

相关问题