VisualStateManager 无法在 UserControl 上启动动画
我尝试在 Windows Phone 7 Silverlight 项目中使用 VisualStateManager 在 UserControl 上启动动画,但它不起作用。 GoToState 只是不断返回 false。
该代码包含一个 VisualState 行为,当数据上下文上的 State 属性发生更改时,该行为会运行 GoToState,这在单击 UI 中的按钮时会发生:
我做错了什么?
XAML:
<Grid>
<UserControl x:Name="_testSubject" l:VisualStates.CurrentState="{Binding State}" />
<Button VerticalAlignment="Bottom" Content="Change state" Click="Button_Click" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="State2">
<Storyboard>
<ColorAnimation From="Red" To="Green" Duration="0:0:10" Storyboard.TargetProperty="Background" Storyboard.TargetName="_testSubject" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
C#:
public class Test : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string name) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name)); }
string _state;
public string State { get { return _state; } set { _state = value; OnPropertyChanged("State"); } }
}
public static class VisualStates
{
public static readonly DependencyProperty CurrentStateProperty =
DependencyProperty.RegisterAttached("CurrentState", typeof(String), typeof(VisualStates), new PropertyMetadata(TransitionToState));
public static string GetCurrentState(DependencyObject obj)
{
return (string)obj.GetValue(CurrentStateProperty);
}
public static void SetCurrentState(DependencyObject obj, string value)
{
obj.SetValue(CurrentStateProperty, value);
}
private static void TransitionToState(object sender, DependencyPropertyChangedEventArgs args)
{
Control c = sender as Control;
if (c != null)
{
bool b = VisualStateManager.GoToState(c, (string)args.NewValue, false);
}
else
{
throw new ArgumentException("CurrentState is only supported on the Control type");
}
}
public partial class MainPage : PhoneApplicationPage
{
public MainPage() { InitializeComponent(); }
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
_testSubject.DataContext = new Test();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
((Test)_testSubject.DataContext).State = "State2";
}
}
I'm trying to start a animation on a UserControl using the VisualStateManager in a Windows Phone 7 Silverlight project but it won't work. GoToState just keep returning false.
The code consists of a VisualState-behaviour which is running the GoToState when a State-property on the datacontext is changed, which happens when the button in the UI is clicked:
What am I doing wrong?
XAML:
<Grid>
<UserControl x:Name="_testSubject" l:VisualStates.CurrentState="{Binding State}" />
<Button VerticalAlignment="Bottom" Content="Change state" Click="Button_Click" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup>
<VisualState x:Name="State2">
<Storyboard>
<ColorAnimation From="Red" To="Green" Duration="0:0:10" Storyboard.TargetProperty="Background" Storyboard.TargetName="_testSubject" />
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
C#:
public class Test : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
void OnPropertyChanged(string name) { if (PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs(name)); }
string _state;
public string State { get { return _state; } set { _state = value; OnPropertyChanged("State"); } }
}
public static class VisualStates
{
public static readonly DependencyProperty CurrentStateProperty =
DependencyProperty.RegisterAttached("CurrentState", typeof(String), typeof(VisualStates), new PropertyMetadata(TransitionToState));
public static string GetCurrentState(DependencyObject obj)
{
return (string)obj.GetValue(CurrentStateProperty);
}
public static void SetCurrentState(DependencyObject obj, string value)
{
obj.SetValue(CurrentStateProperty, value);
}
private static void TransitionToState(object sender, DependencyPropertyChangedEventArgs args)
{
Control c = sender as Control;
if (c != null)
{
bool b = VisualStateManager.GoToState(c, (string)args.NewValue, false);
}
else
{
throw new ArgumentException("CurrentState is only supported on the Control type");
}
}
public partial class MainPage : PhoneApplicationPage
{
public MainPage() { InitializeComponent(); }
private void PhoneApplicationPage_Loaded(object sender, RoutedEventArgs e)
{
_testSubject.DataContext = new Test();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
((Test)_testSubject.DataContext).State = "State2";
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
只是一个疯狂的猜测,但它可能是在错误的线程中执行的吗?您可能希望使用调度程序在正确的 (UI) 线程上执行它。
GoToState 在 Button_Click 函数中工作吗?
当您执行代码时是否会调用 TransitionToState?
这将排除任何其他问题。
更新
以下内容对我有用。我在设置背景时遇到了一些问题。首先,这对 UserControl 没有任何影响,其次不可能使用颜色动画更改背景,这就是我更改不透明度的原因。
MainPage.xaml
TestControl.xaml
Test.cs / TransitionToState 方法
MainPage.cs
我还建议使用 ControlTemplates 来分配 VisualStates,而不是直接在控件上定义它们。这将为您提供更大的灵活性、更好的维护等。
希望这会有所帮助。
just a wild guess, but could it be that it is being executed in the wrong thread? You might want to use the dispatcher to execute it on the correct (UI) thread.
Does the GoToState work in the Button_Click function ?
And is TransitionToState being called when you execute your code.
This would rule out any other problems.
UPDATE
The following works for me. I came accross some problems with setting the Background. First of all this doesn't have any effect on a UserControl and second it is not possible to change the background using a Color animation that's why I change the opacity.
MainPage.xaml
TestControl.xaml
Test.cs / TransitionToState method
MainPage.cs
I would also recommend using ControlTemplates to assign VisualStates instead of defining them directly on the control. This will give you more flexibility, better maintenance, etc..
Hope this helps.
我遇到了类似的问题,我找到了一个对我有帮助的解决方案,可能有人觉得它有用
如果用户控件托管在layoutawarepage中,
否则您必须执行以下操作(示例可以在布局感知页面中找到)
在sizechanged上制作事件处理程序
使用 VisualStateManager.GoToState 移动到该状态
编辑:抱歉误会我以为是winRT App
I had a similar issue I found a solution that helped me and may be someone find it useful
if the usercontrol is hosted in layoutawarepage
otherwise you will have to de the follow (example can be found in the layout aware page)
make event handler on sizechanged
in the event handler check the viewstate with ApplicationView.Value
move to that state with VisualStateManager.GoToState
Edit: Sorry for misunderstanding I thought that it is winRT App