2010-05-25 92 views
0

我有一个DataTemplate,其中包含一个带有边框的扩展器。我希望标题边框在折叠时具有圆角并在展开时具有平直的底角。最好的做法是实现这一目标(代码示例的奖励点,因为我是XAML的新手)?拼图 - 从另一个数据模板动态更改数据模板控制

这是存放扩展模板:

<DataTemplate x:Key="A"> 
     <StackPanel> 
      <Expander Name="ProjectExpander" Header="{Binding .}" HeaderTemplate="{StaticResource B}" > 
       <StackPanel> 
        <Border CornerRadius="0,0,2,2"> 

这是扩展的DataTemplate:

<DataTemplate x:Key="B"> 
     <Border x:Name="ProjectExpanderHeader" 
       CornerRadius="{Binding local:ItemUserControl.ProjectHeaderBorderRadius, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentPresenter}}}" 
       Background="{StaticResource ItemGradient}" 
       HorizontalAlignment="{Binding HorizontalAlignment, 
               RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ContentPresenter}}, 
               Mode=OneWayToSource}"> 
      <local:ItemContentsUserControl Height="30"/> 
     </Border> 
    </DataTemplate> 

回答

1

绑定CornerRadius属性将Expander.IsExpanded财产并附加IValueConverter返回圆角时虚假和直的底角,如果是真的。这不是最优雅的,但它会完成工作。

如果使用MVVM,另一种方法是公开布尔属性并将其绑定到Expander.IsExpanded属性。然后公开CornerRadius的另一个属性,它检查布尔属性并返回适当的值。这绝对是“最佳实践”方式。

1

另一种方法是编辑控件模板。可以说这是最好的做法,尽管我不确定我是否准备好承诺。

如果您有Expression Blend,可以直接执行此操作。编辑控件模板的一个优点是它将Expander的行为与数据模板分开,以便您可以在不同类型的数据中重复使用它。一个缺点是你最终将头文件Border的属性嵌入到控件模板中,所以你不能真正改变它们的控件的任何单个实例。 (其他缺点:必须具有Expression Blend,并且它会产生大量XAML,必须将其放入资源字典中。)

在Expression Blend中,创建一个空白页并在其上放置一个Expander。右键单击扩展器并选择“编辑模板/编辑副本...”。给它起一个名字,如“ExpanderRoundedCorners”。

这会将约200行XAML添加到Page.Resources,但其中大部分用于在展开按钮上创建图形。切换到XAML视图并搜索名为“HeaderSite”的ToggleButton。这是展开按钮。请注意,它的Content属性设置为{TemplateBinding Header}。我们将要解决这个问题。

删除Content属性,一个子元素添加到ToggleButton这样的:

<ToggleButton.Content> 
    <Border x:Name="HeaderBorder" BorderBrush="Red" BorderThickness="2"> 
    <ContentPresenter Content="{TemplateBinding Header}"/> 
</Border> 
</ToggleButton.Content> 

现在发现当按下ToggleButton使ExpandSite可见触发。添加这个setter:

<Setter TargetName="HeaderBorder" Property="CornerRadius" Value="4"/> 

就是这样。现在,每次创建ExpanderRoundedCorners样式的Expander时,标题内容将被包含在Border中,当Expander展开时,其角将被舍入。

你可能会想在这个工作的时候稍微多一些。至少,您需要从样式中的标题模板中删除Border,因为它现在是控件模板的一部分。