【Win10 Pre】 UWP アプリで Windows Phone 向けだけメニューを画面下部に表示したい - しっぽを追いかけてmatatabi-ux.hateblo.jp
に乗っかりネタです。その上、VS2015RTMを入れちゃったので29日までWin10SDK入れれないので妄想で書いてます(重要)
別画面アプローチ
電話とPCは画面大きく違うから別画面で作ればいいじゃん?っていうのは個人的に賛成です。1画面は苦しい。
でも…
同じ画面に押し込めたいときもあるというか、同じ画面に押し込むときはどうしたらいいの?というのを考えてみました。頭の体操ですね。
まず、7インチより小さい端末の場合電話であるとみなします。そうするとUWPのサンプルにある
Microsoft/Windows-universal-samplesgithub.com
を使うと出来ます。以下にあるコードのように、デバイスが何インチかをとることが出来ます。(それC++でできるよ!事案)
Microsoft/Windows-universal-samplesgithub.com
#include "pch.h"#include "DisplaySizeClass.h"#include "sysinfoapi.h"usingnamespace DisplaySizeHelper; usingnamespace Platform; DisplaySizeClass::DisplaySizeClass() { } double DisplaySizeHelper::DisplaySizeClass::GetDisplaySizeInInches() { double sizeInInches = 7; HRESULT result = GetIntegratedDisplaySize(&sizeInInches); if (result == S_OK) return sizeInInches; elsereturn -1; //This will happen for non-integrated displays like monitors, projection surfaces etc., }
これをC#から呼んでやることで、何インチか取得できるようになります。C#にAPI用意してくれてもいいのにって思いますけどこれが現実。こいつを使ってごりっと出来そうではあります。
DeviceFamilyの取得
何インチかという情報に頼るほかにデバイスファミリーを取得する方法があります。こちらは丁寧にVisualStateManagerのStateTriggerのサンプルを上げてくださってる方がいます。
dotMorten/WindowsStateTriggersgithub.com
この中の、DeviceFamilyAdaptiveTriggerを使うとモバイルの時だけVSMを切り替えるといったことが出来ます。
// Copyright (c) Morten Nielsen. All rights reserved.// Licensed under the MIT license. See LICENSE file in the project root for full license information.using System; using Windows.Foundation.Metadata; using Windows.UI.Xaml; namespace WindowsStateTriggers { /// <summary>/// Trigger for switching between Windows and Windows Phone/// </summary>publicclass DeviceFamilyAdaptiveTrigger : StateTriggerBase, ITriggerValue { privatestaticstring deviceFamily; static DeviceFamilyAdaptiveTrigger() { deviceFamily = Windows.System.Profile.AnalyticsInfo.VersionInfo.DeviceFamily; } /// <summary>/// Initializes a new instance of the <seecref="DeviceFamilyAdaptiveTrigger"/> class./// </summary>public DeviceFamilyAdaptiveTrigger() { } /// <summary>/// Gets or sets the device family to trigger on./// </summary>/// <value>The device family.</value>public DeviceFamily DeviceFamily { get { return (DeviceFamily)GetValue(DeviceFamilyProperty); } set { SetValue(DeviceFamilyProperty, value); } } /// <summary>/// Identifies the <seecref="DeviceFamily"/> DependencyProperty/// </summary>publicstaticreadonly DependencyProperty DeviceFamilyProperty = DependencyProperty.Register("DeviceFamily", typeof(DeviceFamily), typeof(DeviceFamilyAdaptiveTrigger), new PropertyMetadata(DeviceFamily.Unknown, OnDeviceTypePropertyChanged)); privatestaticvoid OnDeviceTypePropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var obj = (DeviceFamilyAdaptiveTrigger)d; var val = (DeviceFamily)e.NewValue; if (deviceFamily == "Windows.Mobile") obj.IsActive = (val == DeviceFamily.Mobile); elseif (deviceFamily == "Windows.Desktop") obj.IsActive = (val == DeviceFamily.Desktop); elseif (deviceFamily == "Windows.Team") obj.IsActive = (val == DeviceFamily.Team); elseif (deviceFamily == "Windows.Universal") obj.IsActive = (val == DeviceFamily.Universal); else obj.IsActive = (val == DeviceFamily.Unknown); } #region ITriggerValueprivatebool m_IsActive; /// <summary>/// Gets a value indicating whether this trigger is active./// </summary>/// <value><c>true</c> if this trigger is active; otherwise, <c>false</c>.</value>publicbool IsActive { get { return m_IsActive; } privateset { if (m_IsActive != value) { m_IsActive = value; base.SetActive(value); if (IsActiveChanged != null) IsActiveChanged(this, EventArgs.Empty); } } } /// <summary>/// Occurs when the <seecref="IsActive" /> property has changed./// </summary>publicevent EventHandler IsActiveChanged; #endregion ITriggerValue } /// <summary>/// Device Families/// </summary>publicenum DeviceFamily { /// <summary>/// Unknown/// </summary> Unknown = 0, /// <summary>/// Desktop/// </summary> Desktop = 1, /// <summary>/// Mobile/// </summary> Mobile = 2, /// <summary>/// Team/// </summary> Team = 3, /// <summary>/// Windows universal (for some reason this is returned by IoT/// </summary> Universal = 255 } }
こいつを使うと以下のように書けるはずです(未コンパイル)
<VisualState x:Name="MobileState"><VisualState.Triggers><l:DeviceFamilyAdaptiveTrigger DeviceFamily="Mobile" /></VisualState.Triggers><VisualState.Setter> ...ここにモバイルのときの状態... </VisualState.Setter></VisualState><VisualState x:Name="DesktopState"><VisualState.Setter> ...ここにモバイルじゃないときの状態... </VisualState.Setter></VisualState>
上記のSetterでAppBarの表示非表示を切り替えればOKっぽいです。
まとめ
早くRTM版で試したい。