简体   繁体   English

如何通过DataBinding为DataTemplate中的Buttons制作动画。

[英]How to do animation for Buttons inside DataTemplate through DataBinding.

I have one applications in Windows Phone 8.1 where at run time I generate multiple buttons from ViewModel and populate those into a Canvas, all the buttons are placed in the canvas at dynamic locations. 我在Windows Phone 8.1中有一个应用程序,在运行时,我从ViewModel生成多个按钮,并将这些按钮填充到Canvas中,所有按钮都放置在画布中的动态位置。 Now after some condition I regenerate different number of buttons and again populate in the Canvas UI. 现在,经过某种条件后,我重新生成了不同数量的按钮,并再次在Canvas UI中进行填充。 Every time I do it through ViewModel. 每次我通过ViewModel进行操作时。 Now I want some animations in the Canvas when the game turns from Label 1 to Label 2. 现在,当游戏从“标签1”变为“标签2”时,我需要“画布”中的一些动画。 如图片中所述

The GamePage.xaml contains a canvas control. GamePage.xaml包含一个画布控件。

<Canvas Grid.Row="2" x:Name="gameCanvas" >
   <ItemsControl ItemsSource="{Binding Path=ButtonItems}">
      <ItemsControl.ItemTemplate>
         <DataTemplate>
            <Button 
               Height="{Binding Height}"
               Width="{Binding Width}"  
               Content="{Binding Content}">
             </Button>
         </DataTemplate>
      </ItemsControl.ItemTemplate>
   <ItemsControl>
</Canvas>

Is it possible to trigger an animations for the Buttons which are placed inside a DataTemplate ? 是否可以触发放置在DataTemplate内部的Buttons的动画? If I want to have flip buttons style, say Label 1 Buttons will flip horizontally and disappear, and Label 2 buttons will appear flip vertically? 如果要使用翻转按钮样式,请说“标签1” Buttons将水平翻转并消失,而“标签2” buttons将显示为垂直翻转? Or any Opacity animations. 或任何不透明度动画。

I want to do this through DataBinding to some Property in ViewModel . 我想通过将数据DataBindingViewModel某些Property来做到这一点。 I know that in Windows Phone 8.1 <Style.Triggers> is not there. 我知道Windows Phone 8.1中没有<Style.Triggers> So how can I achieve this? 那么我该如何实现呢? Any help would be greatly appreciated. 任何帮助将不胜感激。

Thanks 谢谢

Note: This solution might not be work with a data-bound list; 注意:此解决方案可能不适用于数据绑定列表; I haven't tried that. 我没有尝试过。 But it works if you can name each item added to your UI (which must be done programmatically). 但是,如果您可以命名添加到UI中的每个项目(必须以编程方式完成),它就会起作用。 But if animation is more important to you than the data-bound-ness of the items, then this could work. 但是,如果动画对您来说比项目的数据绑定度更重要,那么这可能会起作用。

Assuming you have a fixed number of items to move around, you can almost (but not quite) do it with Visual States. 假设您要移动的项目数量固定,那么您可以(但不太完全)使用可视状态做到这一点。 Here is an example that shows you how you can do it trivially for a single Button that moves randomly whenever you click it. 这是一个示例,向您展示如何对单击时随机移动的单个Button简单处理。

XAML XAML

<Grid x:Name="LayoutRoot" Background="Transparent">
  <Grid.Resources>
    <PowerEase Power="2" x:Key="PowerEase"/>
  </Grid.Resources>
  <VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="VSG">
      <VisualState x:Name="Default">
        <Storyboard>
          <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" 
            Storyboard.TargetName="button" To="{Binding LeftOffset}" 
            Duration="0:0:0.5" EasingFunction="{StaticResource PowerEase}"/>
          <DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)" 
            Storyboard.TargetName="button" To="{Binding TopOffset}" 
            Duration="0:0:0.5" EasingFunction="{StaticResource PowerEase}"/>
        </Storyboard>
      </VisualState>
      <VisualState x:Name="Other">
        <Storyboard>
          <DoubleAnimation Storyboard.TargetProperty="(Canvas.Left)" 
            Storyboard.TargetName="button" To="{Binding LeftOffset}" 
            Duration="0:0:0.5" EasingFunction="{StaticResource PowerEase}"/>
          <DoubleAnimation Storyboard.TargetProperty="(Canvas.Top)" 
            Storyboard.TargetName="button" To="{Binding TopOffset}" 
            Duration="0:0:0.5" EasingFunction="{StaticResource PowerEase}"/>
        </Storyboard>
      </VisualState>
    </VisualStateGroup>
  </VisualStateManager.VisualStateGroups>
  <Canvas>
    <Button x:Name="button" Content="Button" Height="100" Width="150" Click="button_Click"/>
  </Canvas>
</Grid>

Code

public partial class VSM : PhoneApplicationPage, INotifyPropertyChanged
{
  public VSM()
  {
    this.InitializeComponent();
    DataContext = this;
    random_ = new Random();
  }

  double left_;
  double top_;
  bool inOtherState_ = false;
  Random random_;

  public double LeftOffset { get { return left_; } }
  public double TopOffset { get { return top_; } }

  private void button_Click(object sender, RoutedEventArgs e)
  {
    left_ = random_.NextDouble() * (ActualWidth - 150);
    top_ = random_.NextDouble() * (ActualHeight - 100);

    RaisePropertyChanged();

    if (inOtherState_)
      VisualStateManager.GoToState(this, "Default", false);
    else
      VisualStateManager.GoToState(this, "Other", false);

    inOtherState_ = !inOtherState_;
  }

  void RaisePropertyChanged()
  {
    var handler = PropertyChanged;
    if (handler != null)
      handler(this, new PropertyChangedEventArgs(""));
  }

  public event PropertyChangedEventHandler PropertyChanged;
}

You should be able to generalize this to multiple Buttons, and using whatever databinding technique you need. 您应该能够将其推广到多个Button,并使用所需的任何数据绑定技术。 The trick is that you must flip-flop between two visual states, and you can only do that in code. 诀窍是您必须在两种视觉状态之间切换,并且只能在代码中进行。 And if you don't have a fixed number of elements, you can generate the Visual States in code as well (but again, not by data binding). 如果没有固定数量的元素,则也可以用代码生成可视状态(但同样,不能通过数据绑定)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM