拼图 - 从另一个数据模板动态更改数据模板控件

时间:2010-05-25 23:33:41

标签: wpf silverlight xaml

我有一个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>

2 个答案:

答案 0 :(得分:1)

CornerRadius属性绑定到Expander.IsExpanded属性,并附加IValueConverter,如果为true,则返回圆角,如果为真,则返回直角。它不是最优雅的,但它可以完成工作。

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

答案 1 :(得分:1)

另一种方法是编辑控件模板。可以说这是最好的做法,虽然我不确定我是否愿意承诺。

如果你有Expression Blend,这很容易做到这一点。编辑控件模板的一个优点是它将Expander的行为与数据模板分开,以便您可以在不同类型的数据中重用它。缺点是您最终在控件模板中嵌入了标头Border的属性,因此您无法为控件的任何单个实例更改它们。 (其他缺点:你必须使用Expression Blend,它会产生大量的XAML,你必须把它放在你的资源字典中。)

在Expression Blend中,创建一个空页面并在其上放置一个Expander。右键单击Expander并选择“Edit Template / Edit a Copy ...”。给它一个像“ExpanderRoundedCorners”这样的名字。

这将向Page.Resources添加约200行XAML,但大部分用于在展开按钮上创建图形。切换到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>

现在找到按下ExpandSiteToggleButton可见的触发器。将此setter添加到其中:

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

就是这样。现在,每当您使用Expander样式创建ExpanderRoundedCorners时,标题内容都会被Border括起来,Expander在展开Border时会被舍入。

当你让它工作时,你可能想要更多地玩这个。至少,您需要从样式中的标题模板中删除{{1}},因为它现在是控件模板的一部分。