2

我在 Windows Phone 8.1 中有一个应用程序,在运行时我从 ViewModel 生成多个按钮并将它们填充到画布中,所有按钮都放置在画布中的动态位置。现在,在某些情况下,我重新生成了不同数量的按钮并再次填充到 Canvas UI 中。每次我都是通过 ViewModel 来做的。现在,当游戏从标签 1 变为标签 2 时,我想要画布中的一些动画。 如图片中所述

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>

是否可以触发Buttons放置在 a 中的动画DataTemplate?如果我想要翻转按钮样式,说标签 1Buttons会水平翻转并消失,标签 2buttons会出现垂直翻转?或任何不透明度动画。

我想DataBinding通过ViewModel. 我知道在 Windows Phone 8.1<Style.Triggers>中是不存在的。那么我该如何实现呢?任何帮助将不胜感激。

谢谢

4

1 回答 1

0

注意:此解决方案可能不适用于数据绑定列表;我没试过。但是,如果您可以命名添加到 UI 中的每个项目(必须以编程方式完成),它就可以工作。但是,如果动画对您来说比项目的数据绑定更重要,那么这可能会起作用。

假设您有固定数量的项目要四处移动,您几乎可以(但不完全)使用视觉状态来做到这一点。这是一个示例,它向您展示了如何轻松地为Button单击它时随机移动的单个对象执行此操作。

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>

代码

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

您应该能够将其推广到多个按钮,并使用您需要的任何数据绑定技术。诀窍是你必须在两种视觉状态之间切换,而且你只能在代码中做到这一点。如果您没有固定数量的元素,您也可以在代码中生成视觉状态(但同样,不是通过数据绑定)。

于 2015-05-28T04:32:56.357 回答