【问题标题】:Puzzle - Dynamically change data template control from another data template拼图 - 从另一个数据模板动态更改数据模板控件
【发布时间】:2010-05-25 23:33:41
【问题描述】:

我有一个 DataTemplate,其中包含一个在标题中带有边框的 Expander。我希望标题边框在折叠时具有圆角,在展开时具有直的底角。实现这一目标的最佳实践是什么(代码示例的奖励积分,因为我是 XAML 的新手)?

这是包含扩展器的模板:

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

这是扩展数据模板:

    <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>

【问题讨论】:

    标签: wpf silverlight xaml


    【解决方案1】:

    CornerRadius 属性绑定到Expander.IsExpanded 属性并附加一个IValueConverter,该IValueConverter 在为false 时返回圆角,在true 时返回直底角。它不是最优雅的,但它可以完成工作。

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

    【讨论】:

      【解决方案2】:

      另一种方法是编辑控件模板。可以说这是最佳实践,但我不确定我是否已准备好做出承诺。

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

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

      现在找到在按下ToggleButton 时使ExpandSite 可见的触发器。将此设置器添加到其中:

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

      就是这样。现在每次使用ExpanderRoundedCorners 样式创建Expander 时,标题内容将包含在Border 中,当Expander 展开时,其角会变圆。

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-08-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-09-20
        相关资源
        最近更新 更多