【飞秋】使用C++语言创建Silverlight中的VisualState
2010-08-05 14:39
423 查看
Silverlight中的VisualState(可视状态)是一个非常重要的概念,使用VisualState,可以将界面的各个状态进行有效的区隔开,并进行单独的设计,并且可以在状态切换时实现动画效果,一般来说,可以通过blend2(微软提供的可视化编程工具)进行设计,但是如果需要动态读取数值并进行设置的话,就需要使用本地的C++代码来编写各个VisualState,下面通过示例展示如何通过编写C++代码来实现与xaml代码同样的功能。
如下所示,xaml文件创建了一个状态,并在该状态下,将矩形旋转了75度。
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SilverlightApplication30.Page"
Width="640" Height="480" xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows" x:Name="Root">
<Grid x:Name="LayoutRoot" Background="White">
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="VisualStateGroup">
<vsm:VisualStateGroup.Transitions>
<vsm:VisualTransition GeneratedDuration="00:00:01"/>
</vsm:VisualStateGroup.Transitions>
<vsm:VisualState x:Name="State1">
<Storyboard>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000"
Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="75"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
<Rectangle Margin="168,168,208,192" x:Name="rectangle" RenderTransformOrigin="0.5,0.5" Fill="#FF8E1919" Stroke="#FF000000">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
</UserControl>
下面,一层层分析,使用本地代码来实现等效的功能:
首先,创建一个IXRVisualStateGroupCollection(即状态组的集合),并与Grid进行绑定
IXRVisualStateGroupCollection* pVisualStateGroups;
app->CreateObject(IID_IXRVisualStateGroupCollection, &pVisualStateGroups);
LayoutRoot->SetAttachedProperty(L"VisualStateManager.VisualStateGroups", pVisualStateGroups);
创建一个状态组,并将其添加到状态组集合中
IXRVisualStateGroupPtr pGroup;
app->CreateObject(IID_IXRVisualStateGroup,&pGroup);
pGroup->SetName(L"VisualStateGroup");
pVisualStateGroups->Add(pGroup,NULL);
通过状态组下的IXRVisualTransitionCollection来设置通用的切换时间,现在暂定为1秒
IXRVisualTransitionCollectionPtr transitions;
app->CreateObject(IID_IXRVisualTransitionCollection,&transitions);
pGroup->SetTransitions(transitions);
IXRVisualTransitionPtr transtion;
app->CreateObject(IID_IXRVisualTransition,&transtion);
XRDuration duration;
duration.DurationType = duration.DurationType_TimeSpan;
duration.TimeSpan.Ticks = duration.TimeSpan.TicksPerSecond;
transtion->SetGeneratedDuration(&duration);
transitions->Add(transtion,NULL);
创建状态集合,并将新建的状态添加进去
IXRVisualStateCollectionPtr StateCollection;
pGroup->GetStates(&StateCollection);
IXRVisualStatePtr state;
app->CreateObject(IID_IXRVisualState,&state);
state->SetName(L"State1");
StateCollection->Add(state,NULL);
创建一个新的故事板,并将其设置到刚创建的状态中
IXRStoryboardPtr Storyboard;
app->CreateObject(IID_IXRStoryboard,&Storyboard);
state->SetStoryboard(Storyboard);
创建一个IXRDoubleAnimationUsingKeyFrames对象,将它添加到故事板中,
[注:IXRDoubleAnimationUsingKeyFrames派生自IXRTimeline,通过在不同帧时对同一属性设置不同的数值来实现动画效果]
IXRTimelineCollectionPtr children;
Storyboard->GetChildren(&children);
IXRDoubleAnimationUsingKeyFramesPtr animation;
app->CreateObject(IID_IXRDoubleAnimationUsingKeyFrames,&animation);
children->Add(animation,NULL);
设置animation对象的通用属性
XRTimeSpan span;
memset(&span,0,sizeof(XRTimeSpan));
animation->SetBeginTime(&span);
animation->SetBeginTime(&span);
animation->SetDuration(&duration);
animation->SetAttachedProperty(L"Storyboard.TargetName",L"rectangle");
animation->SetAttachedProperty(L"Storyboard.TargetProperty",L"(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)");
创建新的一帧,并将其添加到animation的帧集合中
IXRDoubleKeyFrameCollectionPtr frameCollection;
animation->GetKeyFrames(&frameCollection);
IXRSplineDoubleKeyFramePtr keyFrame;
app->CreateObject(IID_IXRSplineDoubleKeyFrame,&keyFrame);
XRKeyTime time;
time.Ticks = time.TicksPerSecond;
keyFrame->SetKeyTime(&time);
keyFrame->SetValue(75);
frameCollection->Add(keyFrame,NULL);
OK,大功告成,转换状态,看到了矩形的变化过程
Root->GoToVisualState(L"State1",true);
关注技术文章飞秋:http://www.freeeim.com/,24小时专业转载。
如下所示,xaml文件创建了一个状态,并在该状态下,将矩形旋转了75度。
<UserControl
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="SilverlightApplication30.Page"
Width="640" Height="480" xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows" x:Name="Root">
<Grid x:Name="LayoutRoot" Background="White">
<vsm:VisualStateManager.VisualStateGroups>
<vsm:VisualStateGroup x:Name="VisualStateGroup">
<vsm:VisualStateGroup.Transitions>
<vsm:VisualTransition GeneratedDuration="00:00:01"/>
</vsm:VisualStateGroup.Transitions>
<vsm:VisualState x:Name="State1">
<Storyboard>
<DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000"
Storyboard.TargetName="rectangle" Storyboard.TargetProperty="(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)">
<SplineDoubleKeyFrame KeyTime="00:00:00" Value="75"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</vsm:VisualState>
</vsm:VisualStateGroup>
</vsm:VisualStateManager.VisualStateGroups>
<Rectangle Margin="168,168,208,192" x:Name="rectangle" RenderTransformOrigin="0.5,0.5" Fill="#FF8E1919" Stroke="#FF000000">
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform/>
<SkewTransform/>
<RotateTransform/>
<TranslateTransform/>
</TransformGroup>
</Rectangle.RenderTransform>
</Rectangle>
</Grid>
</UserControl>
下面,一层层分析,使用本地代码来实现等效的功能:
首先,创建一个IXRVisualStateGroupCollection(即状态组的集合),并与Grid进行绑定
IXRVisualStateGroupCollection* pVisualStateGroups;
app->CreateObject(IID_IXRVisualStateGroupCollection, &pVisualStateGroups);
LayoutRoot->SetAttachedProperty(L"VisualStateManager.VisualStateGroups", pVisualStateGroups);
创建一个状态组,并将其添加到状态组集合中
IXRVisualStateGroupPtr pGroup;
app->CreateObject(IID_IXRVisualStateGroup,&pGroup);
pGroup->SetName(L"VisualStateGroup");
pVisualStateGroups->Add(pGroup,NULL);
通过状态组下的IXRVisualTransitionCollection来设置通用的切换时间,现在暂定为1秒
IXRVisualTransitionCollectionPtr transitions;
app->CreateObject(IID_IXRVisualTransitionCollection,&transitions);
pGroup->SetTransitions(transitions);
IXRVisualTransitionPtr transtion;
app->CreateObject(IID_IXRVisualTransition,&transtion);
XRDuration duration;
duration.DurationType = duration.DurationType_TimeSpan;
duration.TimeSpan.Ticks = duration.TimeSpan.TicksPerSecond;
transtion->SetGeneratedDuration(&duration);
transitions->Add(transtion,NULL);
创建状态集合,并将新建的状态添加进去
IXRVisualStateCollectionPtr StateCollection;
pGroup->GetStates(&StateCollection);
IXRVisualStatePtr state;
app->CreateObject(IID_IXRVisualState,&state);
state->SetName(L"State1");
StateCollection->Add(state,NULL);
创建一个新的故事板,并将其设置到刚创建的状态中
IXRStoryboardPtr Storyboard;
app->CreateObject(IID_IXRStoryboard,&Storyboard);
state->SetStoryboard(Storyboard);
创建一个IXRDoubleAnimationUsingKeyFrames对象,将它添加到故事板中,
[注:IXRDoubleAnimationUsingKeyFrames派生自IXRTimeline,通过在不同帧时对同一属性设置不同的数值来实现动画效果]
IXRTimelineCollectionPtr children;
Storyboard->GetChildren(&children);
IXRDoubleAnimationUsingKeyFramesPtr animation;
app->CreateObject(IID_IXRDoubleAnimationUsingKeyFrames,&animation);
children->Add(animation,NULL);
设置animation对象的通用属性
XRTimeSpan span;
memset(&span,0,sizeof(XRTimeSpan));
animation->SetBeginTime(&span);
animation->SetBeginTime(&span);
animation->SetDuration(&duration);
animation->SetAttachedProperty(L"Storyboard.TargetName",L"rectangle");
animation->SetAttachedProperty(L"Storyboard.TargetProperty",L"(UIElement.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)");
创建新的一帧,并将其添加到animation的帧集合中
IXRDoubleKeyFrameCollectionPtr frameCollection;
animation->GetKeyFrames(&frameCollection);
IXRSplineDoubleKeyFramePtr keyFrame;
app->CreateObject(IID_IXRSplineDoubleKeyFrame,&keyFrame);
XRKeyTime time;
time.Ticks = time.TicksPerSecond;
keyFrame->SetKeyTime(&time);
keyFrame->SetValue(75);
frameCollection->Add(keyFrame,NULL);
OK,大功告成,转换状态,看到了矩形的变化过程
Root->GoToVisualState(L"State1",true);
关注技术文章飞秋:http://www.freeeim.com/,24小时专业转载。
相关文章推荐
- 在wince中使用C++语言创建Silverlight的VisualState
- 在WINCE中使用C++语言创建SILVERLIGHT的VISUALSTATE
- 在wince中使用C++语言创建Silverlight的VisualState
- 使用C++语言创建VisualState
- Silverlight 中文教程第八部分:使用WPF创建一个Digg桌面应用
- 演练:使用 Expression Blend 或代码创建 Silverlight 时钟
- 技巧/诀窍: 创建和使用Silverlight和WPF 用户控件
- 使用Visual Studio 2010 创建简单的Silverlight应用程序
- 创建自定义行为并在Silverlight项目中使用
- Silverlight教程第八部分:使用WPF创建一个Digg桌面应用
- Silverlight教程第八部分:使用WPF创建一个Digg桌面应用
- Silverlight教程第八部分:使用WPF创建一个Digg桌面应用
- 使用blend2 september preview 来为Silverlight程序创建动画资源
- Silverlight 教程第一部分: 使用Silverlight 2 和 VS 2008创建“Hello World”程序
- Silverlight中无法使用Delegate.CreateDelegate()来创建对无法访问的方法的委托
- Silverlight教程第一部分: 使用Silverlight 2 和 VS 2008创建“Hello World”程序
- [演练]使用Expression Blend或代码创建Silverlight时钟
- Silverlight学习笔记(一)-----Silverlight入门之创建项目与使用渐变填充色
- 技巧/诀窍: 创建和使用Silverlight和WPF 用户控件
- 使用Visual Studio 2010 创建简单的Silverlight应用程序