注意:此解决方案可能不适用于数据绑定列表;我没试过。但是,如果您可以命名添加到 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;
}
您应该能够将其推广到多个按钮,并使用您需要的任何数据绑定技术。诀窍是你必须在两种视觉状态之间切换,而且你只能在代码中做到这一点。如果您没有固定数量的元素,您也可以在代码中生成视觉状态(但同样,不是通过数据绑定)。