导航可以分为两种:通过visual tree上控件状态变化的导航(例如,变化展现形式)称为State-based导航,通过在visual tree上增加或移除元素的导航被称为view-based导航,Prism对两种导航都提供了支持。
一、State-based导航
用不同的格式或者Style展现数据
情景:
上面的例子中,同样的数据被通过两种方式展现出来,列表形式和图标形式。因为不涉及到数据的变化,因此这种navigation完全在view层次上。
解决方案:使用Expression Blend的DataStateBehavior。
- <ei:DataStateBehavior Binding="{Binding IsChecked, ElementName=ShowAsListButton}"
- Value="True"
- TrueState="ShowAsList" FalseState="ShowAsIcons"/>
<ei:DataStateBehavior Binding="{Binding IsChecked, ElementName=ShowAsListButton}"
Value="True"
TrueState="ShowAsList" FalseState="ShowAsIcons"/>
通过控制view中不同control的visible和Collapsed来实现。
- <VisualTransition From="ShowAsIcons" To="ShowAsList">
- <Storyboard SpeedRatio="2">
- <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="ContainerPane">
- <EasingDoubleKeyFrame KeyTime="0:0:0" Value="360"/>
- <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="270"/>
- <EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="90"/>
- <EasingDoubleKeyFrame KeyTime="0:0:1" Value="0"/>
- </DoubleAnimationUsingKeyFrames>
- <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Visibility)" Storyboard.TargetName="Contacts">
- <DiscreteObjectKeyFrame KeyTime="0:0:0.5" Value="Visible"/>
- </ObjectAnimationUsingKeyFrames>
- <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Visibility)" Storyboard.TargetName="Avatars">
- <DiscreteObjectKeyFrame KeyTime="0:0:0.5" Value="Collapsed"/>
- </ObjectAnimationUsingKeyFrames>
- </Storyboard>
- </VisualTransition>
<VisualTransition From="ShowAsIcons" To="ShowAsList">
<Storyboard SpeedRatio="2">
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationY)" Storyboard.TargetName="ContainerPane">
<EasingDoubleKeyFrame KeyTime="0:0:0" Value="360"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="270"/>
<EasingDoubleKeyFrame KeyTime="0:0:0.5" Value="90"/>
<EasingDoubleKeyFrame KeyTime="0:0:1" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Visibility)" Storyboard.TargetName="Contacts">
<DiscreteObjectKeyFrame KeyTime="0:0:0.5" Value="Visible"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Visibility)" Storyboard.TargetName="Avatars">
<DiscreteObjectKeyFrame KeyTime="0:0:0.5" Value="Collapsed"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualTransition>
反应应用程序状态
情景:
UI会根据view model中的属性(是否可用属性)呈现出不同的状态。
解决方案:
- <ei:DataStateBehavior Binding="{Binding ConnectionStatus}"
- Value="Available"
- TrueState="Available" FalseState="Unavailable"/>
<ei:DataStateBehavior Binding="{Binding ConnectionStatus}"
Value="Available"
TrueState="Available" FalseState="Unavailable"/>
- <VisualStateGroup x:Name="StatusStates">
- <VisualState x:Name="Available"/>
- <VisualState x:Name="Unavailable">
- <Storyboard>
- <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Control.IsEnabled)" Storyboard.TargetName="MainPane">
- <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="False"/>
- </ObjectAnimationUsingKeyFrames>
- <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="OfflineMask">
- <DiscreteObjectKeyFrame KeyTime="0">
- <DiscreteObjectKeyFrame.Value>
- <Visibility>Visible</Visibility>
- </DiscreteObjectKeyFrame.Value>
- </DiscreteObjectKeyFrame>
- </ObjectAnimationUsingKeyFrames>
- </Storyboard>
- </VisualState>
- </VisualStateGroup>
<VisualStateGroup x:Name="StatusStates">
<VisualState x:Name="Available"/>
<VisualState x:Name="Unavailable">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Control.IsEnabled)" Storyboard.TargetName="MainPane">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="False"/>
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)" Storyboard.TargetName="OfflineMask">
<DiscreteObjectKeyFrame KeyTime="0">
<DiscreteObjectKeyFrame.Value>
<Visibility>Visible</Visibility>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
与用户交互
情景:
这一情景与前一节讲述的差不多,通过对话框和用户交互。
解决方案:
- <prism:InteractionRequestTrigger SourceObject="{Binding SendMessageRequest}">
- <prism:PopupChildWindowAction>
- <prism:PopupChildWindowAction.ChildWindow>
- <vs:SendMessageChildWindow/>
- </prism:PopupChildWindowAction.ChildWindow>
- </prism:PopupChildWindowAction>
- </prism:InteractionRequestTrigger>
<prism:InteractionRequestTrigger SourceObject="{Binding SendMessageRequest}">
<prism:PopupChildWindowAction>
<prism:PopupChildWindowAction.ChildWindow>
<vs:SendMessageChildWindow/>
</prism:PopupChildWindowAction.ChildWindow>
</prism:PopupChildWindowAction>
</prism:InteractionRequestTrigger>
二、View-based导航
Prism实现View-based导航的基本原理如图:
下图是View-based导航原理的流程图: