Window.Current.Bounds.Height の罠
Mobileで実行しているUWPで画面いっぱいにポップアップを出す際の注意点です。
最初に結論から言うと、
- ポップアップを開く前にcs上でポップアップのサイズを動的に指定して画面いっぱいにする
- Window.Current.Bounds は危険
- Mobileは通知領域やOSボタンを考慮しましょう(GetForCurrentView().VisibleBoundsを使えば大丈夫!)
です。
今回使用したサンプルアプリは一番下にまるまる載せているので、ご参考までに。
サンプルアプリの概要
- 画面上にデバイスファミリー、Window.Current.Bounds(画面サイズ)、ApplicationView.GetForCurrentView().VisibleBoundsのサイズを表示
- アプリをフルスクリーンモードへの切り替え
- Window.Current.Boundsのサイズと同じサイズのポップアップを表示する
- ページの一番上の階層のGridのサイズと同じサイズのポップアップを表示する
では実際に見てみましょう。
PCでサイズの確認
サンプルアプリを動かすと以下のようになります。
タイトルバーやツールバーの有無が変わるので、それぞれのモードで数字は違いますが、
Window.Current.BoundsとVisibleBoundsは両方同じ数字になってますね。
Windowモード時
フルスクリーンモード時
PCでPopup表示
Window.Current.Boundsを設定する方法
ポップアップを開く前にWindow.Current.Boundsをポップアップに設定して表示します。
ポップアップにはテキストを並べてスクロールするようになっています。
「1」を並べて、一番下だけ「2」になっています。
grdPop.Height = Window.Current.Bounds.Height;
grdPop.Width = Window.Current.Bounds.Width;
popTest.IsOpen = true;
当然ながら一番下までスクロールできますね。
VisibleBoundsを設定する方法
最初に確認した通り、数字が一緒なので、同じ結果になります。
同じなので、画像は割愛します。
var view = ApplicationView.GetForCurrentView();
grdPop.Height = view.VisibleBounds.Height;
grdPop.Width = view.VisibleBounds.Width;
popTest.IsOpen = true;
それでは問題のMobileです。
Mobileで確認
同じアプリをNuAns NEOで表示してみます。
フルスクリーンモードでは同じですが、Windowモードの場合、
Window.Current.Bounds.HeightとVisibleBounds.Heightの数字が異なっています。
そうです。
こいつが諸悪の根源です。
Windowモード時
フルスクリーンモード時
Window.Current.Boundsだと、Mobileの通知領域やOS標準のボタン領域も含めた単純な画面サイズが取得されてしまいます。
ApplicationView.GetForCurrentView().VisibleBounds だと、現在のビューに表示されている領域のサイズが取得されます。
そのため、このような差が生まれてしまうのですね。
では続いてポップアップを表示してみましょう。
MobileでPopup表示
Window.Current.Boundsを設定する方法
最終行である「2」がボタン領域の下に隠れてしまっています。
VisibleBoundsを設定する方法
正常にすべて表示されます。
まとめ
PCでは同じだけど、Mobileだと異なるっていうのがいやらしいですね。
ウチのアプリの場合、PC版を作って後からMobileに対応ってパターンがあるので、ハマりがちです。
全部見直さないと。。。。。
ソース
MainPage.xaml.cs
using Windows.System.Profile; using Windows.UI.ViewManagement; using Windows.UI.Xaml; using Windows.UI.Xaml.Controls; using Windows.UI.Xaml.Input; namespace WindowSizeTest { public sealed partial class MainPage : Page { public MainPage() { this.InitializeComponent(); } private void grdMain_SizeChanged(object sender, SizeChangedEventArgs e) { //Page_SizeChangeはなぜかMobileのFullスクリーンモードの切り替えだと動いてくれないため、 //GridのSizeChangeでTextの再設定を行う setText(); } private void ToggleButton_Checked(object sender, RoutedEventArgs e) { changeViewMode(true); } private void ToggleButton_Unchecked(object sender, RoutedEventArgs e) { changeViewMode(false); } private void btnShowPopupWindowBounds_Click(object sender, RoutedEventArgs e) { grdPop.Height = Window.Current.Bounds.Height; grdPop.Width = Window.Current.Bounds.Width; popTest.IsOpen = true; } private void btnShowPopupVisibleBounds_Click(object sender, RoutedEventArgs e) { var view = ApplicationView.GetForCurrentView(); grdPop.Height = view.VisibleBounds.Height; grdPop.Width = view.VisibleBounds.Width; popTest.IsOpen = true; } private void grdPop_Tapped(object sender, TappedRoutedEventArgs e) { popTest.IsOpen = false; } private void changeViewMode(bool isFull) { var view = ApplicationView.GetForCurrentView(); if (isFull) { view.TryEnterFullScreenMode(); } else { view.ExitFullScreenMode(); } } private void setText() { txtDevice.Text = AnalyticsInfo.VersionInfo.DeviceFamily; txtWindowHeight.Text = Window.Current.Bounds.Height.ToString(); txtWindowWidth.Text = Window.Current.Bounds.Width.ToString(); var view = ApplicationView.GetForCurrentView(); txtVisibleBoundsHeight.Text = view.VisibleBounds.Height.ToString(); txtVisibleBoundsWidth.Text = view.VisibleBounds.Width.ToString(); } } }
MainPage.xaml
<Page x:Class="WindowSizeTest.MainPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="using:WindowSize" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d"> <Page.Resources> <Style TargetType="TextBlock"> <Setter Property="FontSize" Value="28" /> </Style> <Style x:Key="txtValueStyle" TargetType="TextBlock"> <Setter Property="FontSize" Value="28" /> <Setter Property="Foreground" Value="Red" /> </Style> <Style TargetType="Button"> <Setter Property="Margin" Value="10" /> <Setter Property="FontSize" Value="28" /> </Style> <Style TargetType="ToggleButton"> <Setter Property="FontSize" Value="28" /> </Style> </Page.Resources> <Grid x:Name="grdMain" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" SizeChanged="grdMain_SizeChanged"> <Viewbox VerticalAlignment="Top"> <Grid x:Name="grdContent"> <Grid.ColumnDefinitions> <ColumnDefinition Width="Auto" /> <ColumnDefinition Width="Auto" /> </Grid.ColumnDefinitions> <StackPanel Margin="10,0"> <TextBlock Text="AnalyticsInfo.VersionInfo.DeviceFamily" /> <TextBlock Text="Window.Current.Bounds.Height" /> <TextBlock Text="Window.Current.Bounds.Width" /> <TextBlock Text="GetForCurrentView().VisibleBounds.Height" /> <TextBlock Text="GetForCurrentView().VisibleBounds.Width" /> <ToggleButton Margin="10" Checked="ToggleButton_Checked" Content="FullScreen" Unchecked="ToggleButton_Unchecked" /> <Button x:Name="btnShowPopupWindowBounds" Click="btnShowPopupWindowBounds_Click" Content="ShowPopupWindowBounds" /> <Button x:Name="btnShowPopupVisibleBounds" Click="btnShowPopupVisibleBounds_Click" Content="ShowPopupVisibleBounds" /> </StackPanel> <StackPanel Grid.Column="1"> <TextBlock x:Name="txtDevice" Style="{StaticResource txtValueStyle}" /> <TextBlock x:Name="txtWindowHeight" Style="{StaticResource txtValueStyle}" /> <TextBlock x:Name="txtWindowWidth" Style="{StaticResource txtValueStyle}" /> <TextBlock x:Name="txtVisibleBoundsHeight" Style="{StaticResource txtValueStyle}" /> <TextBlock x:Name="txtVisibleBoundsWidth" Style="{StaticResource txtValueStyle}" /> </StackPanel> </Grid> </Viewbox> <Popup x:Name="popTest"> <Grid x:Name="grdPop" Background="AliceBlue" Tapped="grdPop_Tapped"> <ScrollViewer> <StackPanel> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="1" /> <TextBlock Text="2" /> </StackPanel> </ScrollViewer> </Grid> </Popup> </Grid> </Page>