方向更改时保持相同的布局

时间:2012-07-07 05:33:39

标签: silverlight windows-phone-7 layout auto-rotation

我有一个Silverlight页面,我希望在纵向和横向模式下具有以下外观。基本上,有三个图像排列在网格中。大图像跨越两列。手机旋转时,图像会旋转,但整体布局不会。小图像保持靠近后窗/窗口/搜索按钮,大图像保持在手机顶部。

enter image description here

我已经尝试了许多方法来实现这种效果,但是它们都以这种或那种方式被证明是不令人满意的。我希望有人可以指出我缺少的东西,或者至少阻止别人不得不浪费4或5天来得出与我相同的结论。 大胆的问题:

  • 我尝试的第一件事是将RotateTransform应用于LayoutRoot元素,并在手机旋转更改为横向时将其旋转-90度。我不得不将布局根的高度和宽度硬编码为800和400而不是“自动”,否则它会被拉伸。此解决方案几乎可以工作,但在绘制页面后应用RotateTransform。因为它在800x400屏幕上绘制为400x800图像,所以不绘制前200和后200像素。旋转后(现在)左右部分缺失,这一点变得很明显。 有没有办法强制布局引擎绘制屏幕,​​以便在应用RotateTransform后所有像素都在那里?

  • 我考虑的下一件事(但没试过)是将页面SupportedOrientations设置为“PortraitOnly”,然后使用加速度计生成我自己的“OnOrientationChanged”事件,然后选择性地将图像旋转90度。手机倾斜到风景。我确定这是一个坏主意,因为我可能会以某种微妙的方式弄错,导致混乱时旋转在我的应用程序中的工作方式与其他应用程序完全相同。 是否有办法在不自动更新包含我的元素的网格布局的情况下触发OnOrientationChanged事件?或者,是否有其他一些可用于检测手机方向的挂钩?

  • 我尝试的最后一件事与此处提供的建议相似:Windows Phone 7 applications - Orientation Change和此处:http://blogs.msdn.com/b/ptorr/archive/2010/03/27/strategies-for-dealing-with-orientation-changes.aspx。这个解决方案对我来说似乎有点脆弱,因为它迫使我在OnOrientationChanged事件处理程序和xaml代码中更改网格行和列的相对大小。在纵向模式中,第一行设置为5 *,第二行设置为2 *。然后当我切换到横向时,每行需要设置为1 *,并且列需要分别设置为5 *和2 *。或者,我可以硬编码小图像的大小,并将行和列设置为自动,但后来我仍然坚持硬编码的东西。 由于我已经用尽所有其他选项,我认为这是我坚持的解决方案。

我错过了什么,或者这是这样做的方法吗?

1 个答案:

答案 0 :(得分:4)

你真的不需要硬编码任何东西。你需要的是聪明的设计。要开发具有多个方向支持的优秀应用程序,您应该想出一个聪明的网格布局,它允许您按照自己想要的方式重新定位对象,而不会造成混乱。

根据您的情况考虑布局:

 <Grid x:Name="LayoutRoot" Background="Transparent">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="3.5*" />
            <ColumnDefinition Width="1.5*" />
            <ColumnDefinition Width="2*" />
        </Grid.ColumnDefinitions>
        <Grid.RowDefinitions>
            <RowDefinition Height="2.5*"/>
            <RowDefinition Height="1.5*" />
            <RowDefinition Height="1.5*" />
            <RowDefinition Height="2*"/>
        </Grid.RowDefinitions>

        <!--TitlePanel contains the name of the application and page title-->
        <StackPanel x:Name="TitlePanel" Margin="12,17,0,28" Grid.ColumnSpan="3" Grid.RowSpan="3"></StackPanel>
        <Image Name="bigSmiley" Margin="8" Grid.RowSpan="3" Grid.ColumnSpan="3" Source="big.jpg"
               Stretch="Fill"/>
        <Image Name="smallSmiley1" Grid.Row="3" Source="smiley.jpg" Stretch="Fill" Margin="8"/>
        <Image Name="smallSmiley2" Grid.Row="3" Grid.Column="1"
               Source="smiley.jpg" Stretch="Fill" Margin="8"
               Grid.ColumnSpan="2" />
        <!--ContentPanel - place additional content here-->
    </Grid>

Layout

你的方向改变方法应该是:

private void PhoneApplicationPage_OrientationChanged(object sender, OrientationChangedEventArgs e)
        {
            if ((e.Orientation & PageOrientation.Portrait) == PageOrientation.Portrait)
            {
                Grid.SetRow(bigSmiley, 0);
                Grid.SetColumn(bigSmiley, 0);
                Grid.SetColumnSpan(bigSmiley, 3);
                Grid.SetRowSpan(bigSmiley, 3);
                Grid.SetRow(smallSmiley1, 3);
                Grid.SetColumn(smallSmiley1, 0);
                Grid.SetColumnSpan(smallSmiley1, 1);
                Grid.SetRowSpan(smallSmiley1, 1);
                Grid.SetRow(smallSmiley2, 3);
                Grid.SetColumn(smallSmiley2, 1);
                Grid.SetColumnSpan(smallSmiley2, 2);
                Grid.SetRowSpan(smallSmiley2, 1);
            }
            else
            {
                Grid.SetRow(bigSmiley, 0);
                Grid.SetColumn(bigSmiley, 0);
                Grid.SetColumnSpan(bigSmiley, 2);
                Grid.SetRowSpan(bigSmiley, 4);
                Grid.SetRow(smallSmiley1, 0);
                Grid.SetColumn(smallSmiley1, 2);
                Grid.SetColumnSpan(smallSmiley1, 1);
                Grid.SetRowSpan(smallSmiley1, 2);
                Grid.SetRow(smallSmiley2, 2);
                Grid.SetColumn(smallSmiley2, 2);
                Grid.SetColumnSpan(smallSmiley2, 1);
                Grid.SetRowSpan(smallSmiley2, 2);
            }
        }

结果: Result

我希望能解决你的问题。请记住,总会有一个更好的设计让你的问题消失! :)