5

多年来我一直在编写 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 布局,还是我走对了,但很难走?

谢谢!

4

3 回答 3

2

处理不同方向的一种方法是创建两个 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";
    }

}

希望这可以帮助!

于 2013-05-10T20:20:10.723 回答
1

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

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

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

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

于 2013-05-11T14:41:48.790 回答
0

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

[在 Windows 8 应用上处理方向][1]在 Windows 8.1 应用商店应用中处理方向

发给我,如果你有更多的问题。

谢谢, 安布吉

于 2014-05-17T19:52:37.867 回答