2

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. Now after some condition I regenerate different number of buttons and again populate in the Canvas UI. Every time I do it through ViewModel. Now I want some animations in the Canvas when the game turns from Label 1 to Label 2. As described in the Image

The GamePage.xaml contains a canvas control.

<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? 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? Or any Opacity animations.

I want to do this through DataBinding to some Property in ViewModel. I know that in Windows Phone 8.1 <Style.Triggers> is not there. So how can I achieve this? Any help would be greatly appreciated.

Thanks

Community
  • 1
  • 1
Debhere
  • 1,055
  • 2
  • 19
  • 41

1 Answers1

0

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). 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.

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. 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).

Peter Torr - MSFT
  • 11,824
  • 3
  • 18
  • 51
  • I don't have any `button_click`, its command binding, added to that `` is having a `` inside the `` I have a `Button` control. So Button's animation I need to perform on certain properties from viewmodel – Debhere May 28 '15 at 11:32