在Windows 8.1 Store app中处理方向

时间:2014-03-25 09:18:20

标签: windows-store-apps windows-store visualstatemanager

我正在制作一个Win Store应用程序,并面临处理方向的问题。

有一个网格,我想在方向改变时修改它的设计。 两侧的堆叠面板(在横向视图中)应在纵向视图中转到顶部和底部。

目前,我已经使用所有控件创建了两个网格,并根据方向调整它们,并使用VisualStateManager切换可见性属性。

但我希望用一个网格实现这一目标,任何建议对我都有很大的帮助。

以下图片是该应用的概念设计: enter image description here

1 个答案:

答案 0 :(得分:6)

使用单个网格执行此操作很困难,但可能。

首先,您可能想要做的是减少对方向的担忧,而不是担心水平宽度。这样,如果用户以不会有很多水平空间(类似于纵向模式)的方式快照应用程序,您可以显示类似的体验。

现在,进入网格。

这里的关键是你从一个Grid移动,实际上是3列,一个是1列。因此,您需要修改单元格的ColumnSpan属性。

到目前为止您所绘制的内容有3 Columns,每个Width GridLength *。从那里开始。

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>    
</Grid>

接下来,我们要设置Rows。最好将行数设置为您需要的最大行数,这是我的计数6.如果您将它们全部设置为Auto,那么空Rows(在横向方向)将消失。

<Grid>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>    
    <Grid.RowDefinitions>
        <RowDefinition Width="Auto"/>
        <RowDefinition Width="Auto"/>
        <RowDefinition Width="Auto"/>
        <RowDefinition Width="Auto"/>
        <RowDefinition Width="Auto"/>
        <RowDefinition Width="Auto"/>
    </Grid.ColumnDefinitions>    
</Grid>

现在,创建一些基本内容。我只想创建一堆不同的StackPanel并将它们命名为它们。

我将默认Grid/Row值设置为Landscape的值。我也在第二行使用了两行&#39; (包含StackPanel s 1和2)。两个StackPanel的{​​{1}}都为2,以便进行补偿。

RowSpan

现在我们为您的<Grid> <Grid.ColumnDefinitions> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> <ColumnDefinition Width="*"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition Width="Auto"/> <RowDefinition Width="Auto"/> <RowDefinition Width="Auto"/> <RowDefinition Width="Auto"/> <RowDefinition Width="Auto"/> <RowDefinition Width="Auto"/> </Grid.ColumnDefinitions> <StackPanel Name="HeaderRow" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="3"/> <StackPanel Name="StackPanel1" Grid.Row="1" Grid.Column="0" Grid.RowSpan="2"/> <StackPanel Name="Content" Grid.Row="1" Grid.Column="1"/> <StackPanel Name="BlueSection" Grid.Row="2" Grid.Column="1"/> <StackPanel Name="StackPanel2" Grid.Row="1" Grid.Column="2" Grid.RowSpan="2"/> <StackPanel Name="FooterRow" Grid.Row="3" Grid.Column="0" Grid.ColumnSpan="3"/> </Grid> 方向提供了一个很好的定义。它会根据其中的内容自动垂直调整大小,但您可以随意执行任何最小尺寸调整。

既然我们已经完成了这项工作,我们只需要为不同的尺寸创建一些Landscape。在一个VisualStates中,我们将准确定义我们已经完成的工作。另一方面,我们将创建一个新的。我正在命名他们&#39; Landscape&#39;和&#39;肖像&#39;现在,但我建议做一些类似于&#39; Mid&#39;和&#39; Wide&#39;,然后根据给定的VisualState定义使用哪个。为了空间,我省略了以前的定义。

从技术上讲,我们不需要包含Bounds定义,但我将其作为附加示例包含在内。

注意:在第二张图片中,您有Landscape StackPanel2。我在下面反映了这一点。如果您需要更改,只需将Footer的行定义更改为StackPanel2,将4的行定义更改为Footer

5

你差不多完成了。您只需要<Grid> ... <VisualStateManager.VisualStateGroups> <VisualStateGroup x:Name="OrientationStates"> <!-- What we've already defined --> <VisualState x:Name="Landscape"> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.RowSpan)" Storyboard.TargetName="StackPanel1"> <DiscreteObjectKeyFrame KeyTime="0" Value="2"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.ColumnSpan)" Storyboard.TargetName="StackPanel1"> <DiscreteObjectKeyFrame KeyTime="0" Value="1"/> </ObjectAnimationUsingKeyFrames> <!-- Stack Panel 2 --> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.RowSpan)" Storyboard.TargetName="StackPanel2"> <DiscreteObjectKeyFrame KeyTime="0" Value="2"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.ColumnSpan)" Storyboard.TargetName="StackPanel2"> <DiscreteObjectKeyFrame KeyTime="0" Value="1"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Row)" Storyboard.TargetName="StackPanel2"> <DiscreteObjectKeyFrame KeyTime="0" Value="1"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Column)" Storyboard.TargetName="StackPanel2"> <DiscreteObjectKeyFrame KeyTime="0" Value="2"/> </ObjectAnimationUsingKeyFrames> <!-- Content --> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Row)" Storyboard.TargetName="Content"> <DiscreteObjectKeyFrame KeyTime="0" Value="1"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Column)" Storyboard.TargetName="Content"> <DiscreteObjectKeyFrame KeyTime="0" Value="1"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.ColumnSpan)" Storyboard.TargetName="Content"> <DiscreteObjectKeyFrame KeyTime="0" Value="1"/> </ObjectAnimationUsingKeyFrames> <! -- Blue Section --> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Row)" Storyboard.TargetName="BlueSection"> <DiscreteObjectKeyFrame KeyTime="0" Value="2"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Column)" Storyboard.TargetName="BlueSection"> <DiscreteObjectKeyFrame KeyTime="0" Value="1"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.ColumnSpan)" Storyboard.TargetName="BlueSection"> <DiscreteObjectKeyFrame KeyTime="0" Value="1"/> </ObjectAnimationUsingKeyFrames> <!-- Footer --> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Row)" Storyboard.TargetName="Footer"> <DiscreteObjectKeyFrame KeyTime="0" Value="3"/> </ObjectAnimationUsingKeyFrames> </VisualState> <!-- The New Section --> <VisualState x:Name="Portrait"> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.RowSpan)" Storyboard.TargetName="StackPanel1"> <DiscreteObjectKeyFrame KeyTime="0" Value="1"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.ColumnSpan)" Storyboard.TargetName="StackPanel1"> <DiscreteObjectKeyFrame KeyTime="0" Value="3"/> </ObjectAnimationUsingKeyFrames> <!-- Stack Panel 2 --> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.RowSpan)" Storyboard.TargetName="StackPanel2"> <DiscreteObjectKeyFrame KeyTime="0" Value="1"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.ColumnSpan)" Storyboard.TargetName="StackPanel2"> <DiscreteObjectKeyFrame KeyTime="0" Value="3"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Row)" Storyboard.TargetName="StackPanel2"> <DiscreteObjectKeyFrame KeyTime="0" Value="5"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Column)" Storyboard.TargetName="StackPanel2"> <DiscreteObjectKeyFrame KeyTime="0" Value="0"/> </ObjectAnimationUsingKeyFrames> <!-- Content --> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Row)" Storyboard.TargetName="Content"> <DiscreteObjectKeyFrame KeyTime="0" Value="2"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Column)" Storyboard.TargetName="Content"> <DiscreteObjectKeyFrame KeyTime="0" Value="0"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.ColumnSpan)" Storyboard.TargetName="Content"> <DiscreteObjectKeyFrame KeyTime="0" Value="3"/> </ObjectAnimationUsingKeyFrames> <! -- Blue Section --> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Row)" Storyboard.TargetName="BlueSection"> <DiscreteObjectKeyFrame KeyTime="0" Value="3"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Column)" Storyboard.TargetName="BlueSection"> <DiscreteObjectKeyFrame KeyTime="0" Value="0"/> </ObjectAnimationUsingKeyFrames> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.ColumnSpan)" Storyboard.TargetName="BlueSection"> <DiscreteObjectKeyFrame KeyTime="0" Value="3"/> </ObjectAnimationUsingKeyFrames> <!-- Footer --> <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.Row)" Storyboard.TargetName="Footer"> <DiscreteObjectKeyFrame KeyTime="0" Value="4"/> </ObjectAnimationUsingKeyFrames> </VisualState> </VisualStateGroup> <VisualStateManager.VisualStateGroups> </Grid> 收听Page并回复即可!它需要引用您的WindowSizeChanged。因此,我建议添加Grid或类似于基本x:Name="ContentGrid"定义的内容。如:

Grid

<Grid x:Name="ContentGrid"> 的示例将假设您已完成此操作。

WindowSizeChanged

然后,在private void WindowSizeChanged(object sender, WindowSizeChangedEventArgs windowSizeChangedEventArgs) { if (windowSizeChangedEventArgs.Size.Width < 800) { VisualStateManager.GoToState(ContentGrid, "Portrait", true); } else { VisualStateManager.GoToState(ContentGrid, "Landscape", true); } } PageOnNavigatedTo ...

OnNavigatedFrom

请务必在从页面导航时删除protected override void OnNavigatedTo(NavigationEventArgs e) { Window.Current.SizeChanged += WindowSizeChanged; } protected override void OnNavigatedFrom(NavigationEventArgs e) { Window.Current.SizeChanged -= WindowSizeChanged; } SizeChanged处理程序,否则您的应用会无限期地在内存中保留您的页面副本。这是如何创建一个有趣的内存泄漏。

那就是它!在更改大小时,您的主页面将通知您的网格它需要重新配置自己,它将以所述方式执行此操作。显然你不能直接粘贴它,但你应该能够使用它。请务必将event更改为您指定的控件。

希望这有助于编码!

相关问题