方向变化时保持相同的布局
我有一个Silverlight页面,我希望在纵向和横向模式下有下面的外观。基本上,有三个图像排列在一个网格中。大图像横跨两列。当手机旋转时,图像会旋转,但整体布局不会。小图像保持靠近后/窗/搜索按钮,大图像保持在手机的顶部。方向变化时保持相同的布局
我已经尝试了许多方法来达到这种效果,但他们都证明了这样或那样的不满意。我希望有人能指出我错过的东西,或者至少可以防止其他人浪费4或5天来得出与我所做的相同的结论。 问题粗体部分:
我试图在应用RotateTransform到LayoutRoot元素,其旋转-90度,每当手机旋转而改变为横向的第一件事。我必须将布局根的高度和宽度硬编码为800和400,而不是“自动”,否则它会被压扁。这个解决方案几乎可以工作,但是在绘制页面之后,RotateTransform会被应用。由于它在800x400屏幕上绘制为400x800图像,因此不会绘制顶部200像素和底部200像素。旋转后,(现在)左侧和右侧部分丢失后,这变得很明显。 有没有办法强制布局引擎绘制屏幕,以便在应用RotateTransform后所有像素都在那里?
我认为(但没有尝试),接下来的事情就是设置页面SupportedOrientations为“PortraitOnly”,然后使用加速度计来生成自己的“OnOrientationChanged”事件,然后有选择地在90度旋转图像手机倾斜景观。我确定这是一个糟糕的主意,因为我可能会以某种微妙的方式导致错误,导致旋转在我的应用中与其他应用中的旋转方式不同。 有没有办法让OnOrientationChanged事件触发,而不会自动更新包含我的元素的网格布局?或者,是否还有其他可用于检测电话方向的挂钩?
我试过的最后一件事与这里提供的建议类似:Windows Phone 7 applications - Orientation Change和here:http://blogs.msdn.com/b/ptorr/archive/2010/03/27/strategies-for-dealing-with-orientation-changes.aspx。这个解决方案对我来说似乎有些脆弱,因为它迫使我在OnOrientationChanged事件处理程序以及xaml代码中更改网格行和列的相对大小。在人像模式中,第一行设置为5 *,第二行设置为2 *。然后,当我切换到横向时,行需要被设置为1 *,并且列需要分别设置为5 *和2 *。另外,我可以对小图像的大小进行硬编码,并将行和列设置为自动,但是我仍然坚持对某些东西进行编码。 由于我已经耗尽了所有其他选项,我认为这是我坚持使用的解决方案。
我错过了什么,或者是这样做的吗?
你并不需要硬编码任何东西。你需要的是巧妙的设计。要开发具有多方位支持的良好应用程序,您应该创建一个巧妙的网格布局,使您可以按照自己想要的方式重新定位对象而不会造成混乱。
对于您的情况考虑布局:
<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>
而且你的方向改变的方法应该是这样的:
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);
}
}
结果:
我希望解决y我们的问题。请记住,总会有一个更好的设计让你的问题消失! :)
这非常聪明,但您还必须确保您密切关注边距,否则图像的高宽比会发生一些变化。注意左边的小笑脸是正方形的,右边是更多的矩形。 – 2012-07-09 22:09:54
是的,你是对的。我注意到,列纵横比也有一点问题。但足以传达我想说的话:) – naqvitalha 2012-07-10 04:36:01