2013-05-10 31 views
5

我一直在编写Android应用程序几年,现在我正在开发Windows应用商店/ Windows 8应用程序。开发Windows 8商店应用程序时处理不同的方向

我很困惑如何编写横向和纵向的不同屏幕布局。

在Android中,我们所要做的只是编写2个布局,一个用于纵向,另一个用于横向,遵循文件名的一些名称约定,当我们旋转设备时,平台会自动更改屏幕布局。

我一直在搜索一些解决方案,在Windows 8应用程序中做同样的事情,我发现的所有解决方案都是使用视觉状态组和视觉状态的解决方案,将相同的XAML进行一些修改,发生在我们的我们旋转设备时的小部件。

例如,为了使文本块改变其位置,当我旋转设备为纵向:

<VisualState x:Name="FullScreenPortrait" > 
    <Storyboard> 
     <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Grid.ColumnSpan)" Storyboard.TargetName="GridViewTitle"> 
      <DiscreteObjectKeyFrame KeyTime="0"> 
       <DiscreteObjectKeyFrame.Value> 
        <x:Int32>3</x:Int32> 
       </DiscreteObjectKeyFrame.Value> 
      </DiscreteObjectKeyFrame> 
     </ObjectAnimationUsingKeyFrames> 
     <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Margin)" Storyboard.TargetName="GridViewTitle"> 
      <DiscreteObjectKeyFrame KeyTime="0"> 
       <DiscreteObjectKeyFrame.Value> 
        <Thickness>0,10,10,807</Thickness> 
       </DiscreteObjectKeyFrame.Value> 
      </DiscreteObjectKeyFrame> 
     </ObjectAnimationUsingKeyFrames> 
    </Storyboard> 
</VisualState> 

它看起来并不很干净,简单的我,即使这样做,使用Visual Studio的拖放小部件以生成代码的方法我有一种印象,即必须有一些比我所做的更简单,更清洁的解决方案。

所以我的问题是:是否有任何更容易的解决方案为每个方向编写XAML布局,还是我正确,但艰难的方式?

谢谢!

回答

2

处理不同方向的一种方法是在其内部创建两个带有子元素的Grid元素,并根据方向改变Grids的可见性。

要检测方向的变化,你也可以使用SimpleOrientation传感器像下面的代码:

public sealed partial class MainPage : Page 
    { 
     private SimpleOrientationSensor _oSensor; 

     public MainPage() 
     { 
      this.InitializeComponent(); 

      _oSensor = SimpleOrientationSensor.GetDefault(); 

     } 

     protected override void OnNavigatedTo(NavigationEventArgs e) 
     { 
      if (_oSensor != null) 
       _oSensor.OrientationChanged += (s, a) => 
       { 
        Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.Normal,() => 
        { 
         switch (a.Orientation) 
         { 
          case SimpleOrientation.NotRotated: 
          case SimpleOrientation.Rotated180DegreesCounterclockwise: 
           currentOrientation.Text = "Landscape"; 
           break; 
          case SimpleOrientation.Rotated270DegreesCounterclockwise: 
          case SimpleOrientation.Rotated90DegreesCounterclockwise: 
           currentOrientation.Text = "Portrait"; 
           break; 
          default: 
           currentOrientation.Text = "N/A"; 
           break; 
         } 
        }); 
       }; 
     } 

    } 

或者最简单的方法是处理SizeChanged事件如下面的代码:

public sealed partial class MainPage : Page 
{ 
    public MainPage() 
    { 
     this.InitializeComponent(); 

     mainGrid.SizeChanged += mainGrid_SizeChanged; 
    } 

    void mainGrid_SizeChanged(object sender, SizeChangedEventArgs e) 
    { 
     if (mainGrid.ActualHeight > mainGrid.ActualWidth) 
      currentOrientation.Text = "Portrait"; 
     else 
      currentOrientation.Text = "Landscape"; 
    } 

} 

希望这帮助!

+0

嗯。这听起来不错,但在我的代码中,我必须处理一些gridviews的选定内容,我应该做一些像'if(portrait){handle_my_gridview_portrait(); } else {handle_my_gridview_landscape(); }'。无论如何,这比我目前的解决方案要好。谢谢! – 2013-05-10 20:38:15

+0

以上示例仅显示如何以不同方式检测方向更改。但是,您可以更改DataContext中的值并使用Binding来避免代码隐藏。 – kimsk 2013-05-10 21:45:25

+0

这两个问题的答案都很好,但你的问题更适合我的问题。谢谢,并为延迟感到抱歉! – 2013-06-06 14:13:22

1

Esdras - 你没有错,应该有一个更简单的方法,但唯一的其他选择是软件Expression Blend。我会承认有一条学习曲线可以起步和跑步。

对于用Xaml编写的方向更改,父控件必须从可以扩展的控件驱动(不是内部密封的),并且必须能够识别布局。因此,例如,如果将文本框放在布局感知页面上,其方向将会改变,但是如果将网格放在布局感知页面上并且网格中有文本框......默认行为是网格将响应,但是文本框不会。

您可能还会注意到,虽然它很混乱,并且每个控件都需要一个控件修饰符,就像您为每个响应方向更改的元素所提供的那样...它的好处是它不需要本地代码来定义状态或转换因此设计人员可以使用xml外观类似于xaml来描述视图中的变化,无论它是方向还是其他控件的状态。

如果您可以亲自操作程序Expression Blend,它就是为此目的而制作的。

+2

快速Add(添加):由于这里的环境是Windows 8中,混合已经是“盒子”与Visual Studio 2012 – 2013-05-13 05:15:39

0

我已经在一段时间后在stackoverflow上写了一篇文章,可能对您有用。 一些示例和代码提供:

[操纵定向上的Windows 8应用程序] [1] Handling Orientation in Windows 8.1 Store app

帖子我,如果你有更多的问题。

谢谢, Ambuj

+0

也可参考这篇文章: [快速入门:Windows屏幕方向(http://msdn.microsoft .COM/EN-US /库/ WindowsPhone的/开发/ jj207002(v = vs.105)的.aspx) – Ambuj 2014-05-19 06:46:56

相关问题