如何进行屏幕尺寸感知布局?

时间:2013-03-06 04:36:45

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

我正在制作棋盘游戏。要构建电路板,我会执行以下操作:

    // adapted from http://code.msdn.microsoft.com/windowsapps/Reversi-XAMLC-sample-board-816140fa/sourcecode?fileId=69011&pathId=706708707
    // This is shit code.
    async void PlayGame_Loaded(object sender, RoutedEventArgs e)
    {
        foreach (var row in Game.ALL_ROWS)
        {
            boardGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(BOARD_GRID_SIDE_LENGTH) });
        }
        var maxColIndex = Game.ALL_ROWS.Max();
        foreach (var col in Enumerable.Range(0, maxColIndex))
        {
            boardGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(BOARD_GRID_SIDE_LENGTH) });
        }

        // ...
     }

(随意建议替代方法。)

基本上,我根据预先设定的高度和宽度创建了一堆行和列,并用板空间填充这些行和列。当我设置行和列长度以适合我的笔记本电脑时,这很好用,但显然它不适用于具有不同分辨率的设备。 (例如,它在Surface RT上被截断了。)我如何解决这个问题?我可以指定边长是父容器的一部分吗?这里最好的做法是什么?

3 个答案:

答案 0 :(得分:1)

您最好的选择可能是使用ViewBox,假设您要绘制的棋盘具有恒定的行/列数。

答案 1 :(得分:1)

我用这个:

var bounds = Window.Current.Bounds;

double height = bounds.Height;    
double width = bounds.Width;

找出我的应用所依据的屏幕分辨率,然后根据屏幕尺寸重新调整网格项目的大小。

编辑: 所以对于你的代码,我会这样做:

 async void PlayGame_Loaded(object sender, RoutedEventArgs e)
        {
             var bounds = Window.Current.Bounds;

             double BOARD_GRID_SIDE_LENGTH = bounds.Height;    
             double BOARD_GRID_SIDE_WIDTH = bounds.Width;

            foreach (var row in Game.ALL_ROWS)
            {
            boardGrid.RowDefinitions.Add(new RowDefinition() { Height = new GridLength(BOARD_GRID_SIDE_LENGTH) });
        }
        var maxColIndex = Game.ALL_ROWS.Max();
        foreach (var col in Enumerable.Range(0, maxColIndex))
        {
            boardGrid.ColumnDefinitions.Add(new ColumnDefinition() { Width = new GridLength(BOARD_GRID_SIDE_WIDTH) });
        }

        // ...
     }

答案 2 :(得分:0)

声音解决方案是划分页面,使boardGrid占据屏幕的2/3,其余内容(按钮,计时器,记分板...)占据另一半。
其次,将其封装在Viewbox元素内,以便在进入不同的视图模式(完整,纵向,捕捉,填充)时重新计算电路板尺寸
最后,确保页面继承LayoutAwarePage而不是Page,以便它优雅地处理视图模式的更改

这是一个粗略的模型:

<common:LayoutAwarePage
xmlns:UI="using:Microsoft.Advertising.WinRT.UI"
x:Class="ApexKT.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:MyApp"
xmlns:common="using:MyApp.Common"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:snaps="http://schemas.microsoft.com/netfx/2007/xaml/presentation"
mc:Ignorable="d" >    
<Grid x:Name="bigGrid">
    <StackPanel Orientation="Horizontal">
        <StackPanel x:Name="OneThird">
            <TextBlock x:Name="ScoreBoard" Text="Score:" />
            <Button x:Name="Button1" Content="Button 1" Click="" />
        </StackPanel>
        <Viewbox x:Name="TwoThirds">
            <Viewbox.Transitions>
                <TransitionCollection>
                    <ContentThemeTransition />
                </TransitionCollection>
            </Viewbox.Transitions>
            <Grid x:Name="boardGrid"><!-- insert row and column definitions here, or hard code them --></Grid>
        </Viewbox>
    </StackPanel>
    <VisualStateManager.VisualStateGroups>
        <VisualStateGroup x:Name="ApplicationViewStates">
            <VisualState x:Name="FullScreenLandscape"/>
            <VisualState x:Name="Filled"/>
            <VisualState x:Name="Snapped" />
            <VisualState x:Name="FullScreenPortrait" />
        </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
</Grid>

`