【问题标题】:Changing Expander template based on properties根据属性更改扩展器模板
【发布时间】:2010-11-09 21:41:23
【问题描述】:

以下是我定制的扩展器模板的一部分:

<Grid 
    x:Name="ExpandSiteContainer" 
    Visibility="Visible" 
    HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" 
    Margin="{TemplateBinding Padding}" 
    VerticalAlignment="{TemplateBinding VerticalContentAlignment}" 
    DockPanel.Dock="Bottom">
        <!--<Grid.Height>
            <MultiBinding Converter="{StaticResource multiplyConverter}">
                <Binding Path="ActualHeight" ElementName="ExpandSite"/>
                <Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
            </MultiBinding>
        </Grid.Height>-->
        <Grid.Width>
            <MultiBinding Converter="{StaticResource multiplyConverter}">
                <Binding Path="ActualWidth" ElementName="ExpandSite"/>
                <Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
            </MultiBinding>
        </Grid.Width>
        <Grid.Tag>
            <sys:Double>0.0</sys:Double>
        </Grid.Tag>
        <ScrollViewer VerticalScrollBarVisibility="Hidden" HorizontalScrollBarVisibility="Hidden">
            <ContentPresenter x:Name="ExpandSite" Focusable="false" VerticalAlignment="Top"/>
        </ScrollViewer>
</Grid>

我还定义了以下触发器:

<Trigger Property="IsExpanded" Value="true">
    <Trigger.EnterActions>
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimation Storyboard.TargetName ="ExpandSiteContainer" Storyboard.TargetProperty = "Tag" To="1.0" Duration ="0:0:0.25" />
            </Storyboard>
        </BeginStoryboard>
    </Trigger.EnterActions>
    <Trigger.ExitActions>
        <BeginStoryboard>
            <Storyboard>
                <DoubleAnimation Storyboard.TargetName ="ExpandSiteContainer" Storyboard.TargetProperty ="Tag" To="0" Duration ="0:0:0.25"/>
            </Storyboard>
        </BeginStoryboard>
    </Trigger.ExitActions>
</Trigger>

当 IsExpanded 属性发生变化时,扩展器将使用上述定义的情节提要滑动打开/关闭。

我想做的是以某种方式“传入”会修改其行为的值:

  1. 请注意,模板中的 Grid.Height 部分已被注释掉。它被注释掉了,因为现在我的扩展器向右展开,我只想修改网格的宽度。有什么我可以做的,以便根据扩展器的 ExpandDirection,我可以更改模板的行为方式(如果 ExpandDirection 向上或向下,则更改高度,如果 ExpandDirection 向左或向右,则更改宽度)?

  2. 有没有一种方法可以更改模板中为不同扩展器定义的动画的持续时间,还是需要创建单独的模板?

谢谢。

【问题讨论】:

  • 如果触发器没有做你想做的事,你有没有看过模板选择器?您可以使用一些属性对 DataTemplateSelector 进行子类化,并根据这些属性设置值。

标签: wpf wpf-controls binding


【解决方案1】:

在问题 1 中,您可以使用触发器来选择基于 ExpandDirection 的扩展行为。从Grid 中删除Grid.WidthGrid.Height,然后将其添加到模板的触发器中:

<Trigger Property="ExpandDirection" Value="Down">
    <Setter TargetName="ExpandSiteContainer" Property="Height">
        <Setter.Value>
            <MultiBinding Converter="{StaticResource multiplyConverter}">
                <Binding Path="ActualHeight" ElementName="ExpandSite"/>
                <Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
            </MultiBinding>
        </Setter.Value>
    </Setter>
</Trigger>
<Trigger Property="ExpandDirection" Value="Right">
    <Setter TargetName="ExpandSiteContainer" Property="Width">
        <Setter.Value>
            <MultiBinding Converter="{StaticResource multiplyConverter}">
                <Binding Path="ActualWidth" ElementName="ExpandSite"/>
                <Binding Path="Tag" RelativeSource="{RelativeSource Self}" />
            </MultiBinding>
        </Setter.Value>
    </Setter>
</Trigger>

对于问题 2,我认为答案可能是:不。问题是,WPF 最终会尝试冻结动画,因为它是 Style 的一部分,这使得很难做任何修改持续时间的事情。 (例如,如果您尝试对动画的 Duration 进行数据绑定,则在初始化期间会出现错误,因为 WPF 会尝试冻结 Storyboard,这会立即引发异常以说明它不能被冻结。)

据我了解,样式冻结其资源的原因是因为这使资源能够在样式的多个实例之间更有效地共享。正如http://msdn.microsoft.com/library/ms742868中所说的那样

您不能使用动态资源引用或数据绑定表达式来设置 Storyboard 或动画属性值。这是因为 Style 中的所有内容都必须是线程安全的,并且计时系统必须冻结 Storyboard 对象以使其成为线程安全的。如果 Storyboard 或其子时间线包含动态资源引用或数据绑定表达式,则无法冻结 Storyboard。

我不太清楚为什么“样式中的所有内容都必须是线程安全的”。我可以看到跨多个线程使用的样式(例如控件的默认样式)是必需的。也许他们只是强制要求所有样式的一致性。但无论如何,样式内的动画似乎不包含任何类型的动态值,这表明您将无法执行您要求的第二件事。

【讨论】:

    【解决方案2】:

    关于你的第二个问题,

    为什么不在你的自定义扩展器中添加一个依赖属性(例如“时间”),然后在其上绑定 doubleAnimation 的 Duration 属性?

    以后你就可以通过这种方式使用了

    <local:MyCustomExpander Time="2"/>
    

    您的默认模板将获得此值。 (我自己没试过,所以不能保证效果)

    【讨论】:

      猜你喜欢
      • 2014-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-11-11
      • 1970-01-01
      • 2011-06-15
      • 1970-01-01
      相关资源
      最近更新 更多