【问题标题】:Handling different orientations while developing Windows 8 Store applications在开发 Windows 8 应用商店应用程序时处理不同的方向
【发布时间】:2013-05-10 19:42:17
【问题描述】:

多年来我一直在编写 Android 应用程序,现在我正在开发 Windows Store/Windows 8 应用程序。

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

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

我一直在用谷歌搜索在我的 Windows 8 应用程序中执行相同操作的解决方案,我发现的只是使用 Visual State Groups 和 Visual States 的解决方案,在相同的 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 布局,还是我走对了,但很难走?

谢谢!

【问题讨论】:

    标签: xaml windows-store-apps winrt-xaml


    【解决方案1】:

    处理不同方向的一种方法是创建两个 Grid 元素及其子元素,并根据方向更改 Grid 的可见性。

    要检测方向变化,您还可以使用 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";
        }
    
    }
    

    希望这会有所帮助!

    【讨论】:

    • 嗯。这听起来不错,但在我的代码中,我必须处理某些网格视图的选定内容,我应该执行类似if (portrait) { handle_my_gridview_portrait(); } else { handle_my_gridview_landscape(); } 的操作。无论如何,它比我目前的解决方案要好。谢谢!
    • 上面的示例只是展示了如何以不同的方式检测方向变化。但是,您可以更改 DataContext 中的值并使用 Binding 来避免代码隐藏。
    • 这个问题的两个答案都很好,但你的答案更适合我的问题。感谢和抱歉耽搁了!
    【解决方案2】:

    Esdras - 你没看错,应该有更简单的方法,但唯一的其他选择是 Expression Blend 软件。而且我承认有一个学习曲线来启动和运行。

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

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

    如果您能亲身体验 Expression Blend 程序,它就是为此目的而制作的。

    【讨论】:

    • 这里快速添加:由于这里的上下文是 Windows 8,Blend 已经在 Visual Studio 2012 的“盒子里”
    【解决方案3】:

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

    [Windows 8 应用的处理方向][1]Handling Orientation in Windows 8.1 Store app

    如果您有更多问题,请发帖给我。

    谢谢, 安布吉

    【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-12-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-07
    相关资源
    最近更新 更多