2009-07-13 18 views
6

这是经常出现的情况:限制值变化时启动动画的最佳方式是什么?

在视图中,你必须绑定到视图模型属性(由INotifyPropertyChanged的支持)的控制。例如:

<TextBlock Text="{Binding Path=Subtotal}"/> 

当属性的变化,你需要把用户注意一个事实,一些动漫创意。我如何利用视图已经连接到通知并避免创建大量额外代码(或者至少创建一次并重新使用)的事实。数据触发器可能是最好的选择,但我不知道如何让它们触发任何价值变化与某些特定价值。

下列选项浮现在脑海中:

  • 筹集视图模型额外的事件,在查看订阅代码隐藏。
  • 创建一个绑定到使用转换器提到的属性的数据触发器,如果​​值发生变化,将返回true。
  • 创建绑定到ViewModel上的新布尔属性的datatrigger,该属性用于“发信号”更改。
  • 创建附加到控件的行为,该控件将订阅控件的依赖项属性更改并启动动画。

你喜欢/使用哪一个?我错过任何选择吗?

P.S.如果解决方案能够首先启动动画,并在结束时反映价值变化,那将会很好(但并非关键)。

回答

3

好吧,这是我经过一番尝试后才发现的。

我已经创建了具有依赖项属性的Expression Blend 3触发器(我将其命名为Subscription)。我认购绑定到我的TextBlock绑定到相同的值,这触发附加到ControlStoryboardAction从Expression Blend中3

这里的触发:

public class DataTriggerPlus : TriggerBase<DependencyObject> 
{ 
    public static readonly DependencyProperty SubscriptionProperty = 
     DependencyProperty.Register("Subscription", 
      typeof(string), 
      typeof(DataTriggerPlus), 
      new FrameworkPropertyMetadata("", 
       new PropertyChangedCallback(OnSubscriptionChanged))); 

    public string Subscription 
    { 
     get { return (string)GetValue(SubscriptionProperty); } 
     set { SetValue(SubscriptionProperty, value); } 
    } 

    private static void OnSubscriptionChanged(DependencyObject d, 
     DependencyPropertyChangedEventArgs e) 
    { 
     ((DataTriggerPlus)d).InvokeActions(null); 
    } 
} 

下面是它是如何连接到故事板:

<TextBlock x:Name="textBlock" Text="{Binding TestProp}" Background="White"> 
    <i:Interaction.Triggers> 
     <local:DataTriggerPlus Subscription="{Binding TestProp}"> 
      <im:ControlStoryboardAction 
       Storyboard="{StaticResource Storyboard1}"/> 
     </local:DataTriggerPlus> 
    </i:Interaction.Triggers> 
</TextBlock> 

我喜欢这种方法很多,很棒的工作混合3名设计师!

编辑:回答Drew评论...

是的,它附带Blend。您可以将Microsoft.Expression.Interactions.dll和System.Windows.Interactivity包含到您的项目中。

是的,它是冗长的(我问过是否有人通过样式in this question找到了一种适用行为的好方法) - 但也有灵活性的好处。例如,您不仅可以启动故事板,还可以切换状态或从同一触发器执行其他操作。

2

您可以创建一个触发器来启动动画。

事情是这样的:

<Style> 
    <Style.Triggers> 
     <Trigger 
      Property="ViewModelProperty" 
      Value="True"> 
      <Trigger.EnterActions> 
       <BeginStoryboard Storyboard="YourStoryBoard" /> 
      </Trigger.EnterActions> 
     </Trigger> 
    </Style.Triggers> 
</Style> 

至于这一次的动画已经完成设定值问题的问题,这是一个有点疼痛。据我所知,您需要在故事板上使用完成的事件,这需要隐藏代码,这是您想要通过MVVM避免的。

我试过使用EventTriggers绑定到已完成的事件,但这也引入了一些复杂性。有关更多详细信息,请参见here

+0

同样,如果属性不是布尔值或一组选项,但是是一个任意的字符串或数字呢? – 2009-07-13 23:51:18

+0

然后你会使用一个ValueConverter。相同的解决方案,只需使用valueConverter – 2009-07-14 02:01:41

相关问题