在WPF中使用带有Rectangle的DataTrigger时遇到问题

时间:2012-05-17 15:33:07

标签: wpf xaml animation storyboard

我是WPF的新手,我正在尝试将更改设置为Rectangle的大小和位置。我通过将其绑定到INotifyPropertyChanged属性来设置矩形。这工作正常,但变化可能是极端的,我希望它在视觉上不那么刺耳。

这很好用:

<Rectangle Fill="{x:Static SystemColors.ControlBrush}" 
        Stroke="black">
<Rectangle.Style>
    <Style TargetType="{x:Type Rectangle}">
        <Setter Property="Canvas.Left" Value="{Binding Path=Coil.Left, Mode=OneWay}"/>
        <Setter Property="Canvas.Top" Value="{Binding Path=Coil.Top, Mode=OneWay}"/>
        <Setter Property="Width" Value="{Binding Path=Coil.Width, Mode=OneWay}"/>
        <Setter Property="Height" Value="{Binding Path=Coil.Height, Mode=OneWay}"/>
    </Style>
</Rectangle.Style>

Coil.Left是我的INotifyPropertyChanged对象中的RectangleF结构,包含矩形的画布的DataContext属性在创建对象后在我的代码中设置。

我也可以使用EventTrigger设置动画:

<Rectangle Fill="{x:Static SystemColors.ControlBrush}" 
        Stroke="black">
<Rectangle.Style>
    <Style TargetType="{x:Type Rectangle}">
        <Setter Property="Canvas.Left" Value="{Binding Path=Coil.Left, Mode=OneTime}"/>
        <Setter Property="Canvas.Top" Value="{Binding Path=Coil.Top, Mode=OneTime}"/>
        <Setter Property="Width" Value="{Binding Path=Coil.Width, Mode=OneTime}"/>
        <Setter Property="Height" Value="{Binding Path=Coil.Height, Mode=OneTime}"/>
    </Style>
</Rectangle.Style>
<Rectangle.Triggers>
    <EventTrigger RoutedEvent="Rectangle.MouseEnter">
        <EventTrigger.Actions>
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetProperty="Width" 
                                        To="{Binding Path=Coil.Width, Mode=OneWay}"
                                        Duration="0:0:5"/>
                    <DoubleAnimation Storyboard.TargetProperty="Height" 
                                        To="{Binding Path=Coil.Height, Mode=OneWay}"
                                        Duration="0:0:0.5"/>
                    <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" 
                                        To="{Binding Path=Coil.Left, Mode=OneWay}"
                                        Duration="0:0:5"/>
                    <DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)" 
                                        To="{Binding Path=Coil.Top, Mode=OneWay}"
                                        Duration="0:0:5"/>
                </Storyboard>
            </BeginStoryboard>
        </EventTrigger.Actions>
    </EventTrigger>
</Rectangle.Triggers>

当我将鼠标移到Rectangle上时,它会通过动画更改为Coil.Left,Top,Width和Height的当前属性值。

但是,我想要完成的是将Coil属性值的任何更改作为动画更改。所以我的计划是设置一个DataTrigger并使用转换器始终返回true,这样任何更改都会导致通过动画播放更改。

但是无论我做什么,我在使用DataTrigger打开窗口之前都会遇到异常错误而我不知道为什么会这样。为了简单起见,我取出了转换器并使用了直接值:

<Rectangle Fill="{x:Static SystemColors.ControlBrush}" 
        Stroke="black">
<Rectangle.Style>
    <Style TargetType="{x:Type Rectangle}">
        <Setter Property="Canvas.Left" Value="{Binding Path=Coil.Left, Mode=OneTime}"/>
        <Setter Property="Canvas.Top" Value="{Binding Path=Coil.Top, Mode=OneTime}"/>
        <Setter Property="Width" Value="{Binding Path=Coil.Width, Mode=OneTime}"/>
        <Setter Property="Height" Value="{Binding Path=Coil.Height, Mode=OneTime}"/>
    </Style>
</Rectangle.Style>
<Rectangle.Triggers>
    <DataTrigger Binding="{Binding Path=Coil.Height}" Value="60">
        <DataTrigger.EnterActions>
            <BeginStoryboard>
                <Storyboard>
                    <DoubleAnimation Storyboard.TargetProperty="Width" 
                                        To="{Binding Path=Coil.Width, Mode=OneWay}"
                                        Duration="0:0:5"/>
                    <DoubleAnimation Storyboard.TargetProperty="Height" 
                                        To="{Binding Path=Coil.Height, Mode=OneWay}"
                                        Duration="0:0:0.5"/>
                    <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" 
                                        To="{Binding Path=Coil.Left, Mode=OneWay}"
                                        Duration="0:0:5"/>
                    <DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)" 
                                        To="{Binding Path=Coil.Top, Mode=OneWay}"
                                        Duration="0:0:5"/>
                </Storyboard>
            </BeginStoryboard>
        </DataTrigger.EnterActions>
    </DataTrigger>
</Rectangle.Triggers>

有关为什么会出现异常错误的任何想法?我确定这只是我对WPF缺乏经验的问题。这是我的第一个项目。

提前谢谢。

- 约翰

2 个答案:

答案 0 :(得分:0)

对于像FrameworkElement这样的Rectangle,您只能使用EventTrigger。在StyleControlTemplateDataTemplate中,您也可以使用Trigger / MultiTriggerDataTrigger / MultiDataTrigger

这意味着将您的DataTrigger移到Rectangle样式,它应该有效:

<Rectangle Fill="{x:Static SystemColors.ControlBrush}" Stroke="Black">
    <Rectangle.Style>
        <Style TargetType="{x:Type Rectangle}">
            ... 
            <Style.Triggers>
                <DataTrigger Binding="{Binding Path=Coil.Height}" Value="60">
                    ...
                </DataTrigger>
            </Style.Triggers>
        </Style>
    </Rectangle.Style>
</Rectangle>

答案 1 :(得分:0)

最近正在阅读这篇文章。尽管EventTriggersDataTriggers具有相似性,但您可以在BindingStoryboard使用EventTrigger而不是DataTrigger

如果您尝试在Storyboard条件中使用绑定(例如下面的

),那么您将收到 System.Windows.Markup.XamlParseException 错误
<Style.Triggers>
  <DataTrigger Binding="{Binding Path=IsBarVisible, 
    Converter={StaticResource myBooleanToVisibiltyConverter}}" Value="Visible">
    <DataTrigger.EnterActions>
      <BeginStoryboard>
        <Storyboard>
          <DoubleAnimation
            Storyboard.TargetProperty="Value"
            From="{Binding Path=ProgressedAmout}"
            To="100"
            Duration="0:0:50"
          ></DoubleAnimation>
        </Storyboard>
      </BeginStoryboard>
    </DataTrigger.EnterActions>
  </DataTrigger>
</Style.Triggers>

您可以使用EventTrigger作为回报或删除Storyborad ToFrom绑定。