Windowsストア アプリのコード(App.xaml/App.xaml.cs/App.g.i.cs)

前回に続けて、Windowsストアアプリのコードを見てみる。

WPFアプリケーションではプロジェクトのプロパティでスタートアップオブジェクトを指定できるが、WindowsStoreアプリでは選択できない。Windowsストアアプリではマニフェストファイル「Package.appxmanifest」に記述できる。(ただし、変更することは特に無いように思う。)


  <Applications>
    <Application Id="App"
        Executable="$targetnametoken$.exe"
        EntryPoint="AppSample.App">
        <VisualElements
            DisplayName="AppSample"
            Logo="Assets\Logo.png"
            SmallLogo="Assets\SmallLogo.png"
            Description="AppSample"
            ForegroundText="light"
            BackgroundColor="#464646">
            <DefaultTile ShowName="allLogos" />
            <SplashScreen Image="Assets\SplashScreen.png" />
        </VisualElements>
    </Application>

↑Package.appxmanifestのXML一部。EntryPointにクラス名を記載。

<Application
    x:Class="AppSample.App"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:AppSample">

    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="Common/StandardStyles.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

↑App.xaml。スタイル用のリソース読み込みを設定。


エントリポイントで指定した「App.xaml.cs」のAppクラスのコンストラクタは次の通り。

sealed partial class App : Application
{
    public App()
    {
        this.InitializeComponent();
        this.Suspending += OnSuspending;
    }

最初の一行目のInitializeComponentメソッドは、App.xaml.csには存在しない。「定義へ移動(F12)」を選択すると「\obj\Debug\App.g.i.cs」のInitializeComponentメソッドが表示される。これは自動的に生成されたコードとなる。(App.xamlのビルドアクションが「ApplicationDefinition」となっている)
InitializeComponentメソッドには、BindingFailedイベントとUnhandledExceptionイベント処理が記載されている。

partial class App : global::Windows.UI.Xaml.Application
{
    private bool _contentLoaded;

    public void InitializeComponent()
    {
        if (_contentLoaded)
            return;

        _contentLoaded = true;

        DebugSettings.BindingFailed += (sender, args) =>
        {
            global::System.Diagnostics.Debug.WriteLine(args.Message);
        };

        UnhandledException += (sender, e) =>
        {
            if (global::System.Diagnostics.Debugger.IsAttached) global::System.Diagnostics.Debugger.Break();
        };

    }
}

↑生成されたInitializeComponentメソッドアトリビュートプリプロセッサディレクティブは省略)

App.g.i.csのコードには、全般的に、GeneratedCodeAttribute(生成コード)とDebuggerNonUserCodeAttribute(ユーザーが書いたコード)のアトリビュートが付与されている。

public static class Program
{
    static void Main(string[] args)
    {
        global::Windows.UI.Xaml.Application.Start((p) => new App());
    }
}

「App.g.i.cs」ファイルにはProgramクラスのvoid Mainのコードも生成されている。Application.StartメソッドによってAppクラスを起動するコードが生成されている。

アプリケーションの起動時と再開時には、OnLaunchedメソッドが呼び出される。
この中からメインページであるMainPageを呼び出している。

protected override void OnLaunched(LaunchActivatedEventArgs args)
{
    Frame rootFrame = Window.Current.Content as Frame;

    if (rootFrame == null)
    {
        rootFrame = new Frame();

        if (args.PreviousExecutionState == ApplicationExecutionState.Terminated)
        {
            //TODO: 以前中断したアプリケーションから状態を読み込みます。
        }

        Window.Current.Content = rootFrame;
    }

    if (rootFrame.Content == null)
    {
        //メインページへ移動
        if (!rootFrame.Navigate(typeof(MainPage), args.Arguments))
        {
            throw new Exception("Failed to create initial page");
        }
    }

    Window.Current.Activate();
}

Windows Storeアプリでは、別のアプリに切り替えた場合に、OnSuspendingメソッドが呼び出される。サスペンド状態となった後、メモリが不足した場合、アプリは自動的に終了(Terminate)する。

private void OnSuspending(object sender, SuspendingEventArgs e)
{
    var deferral = e.SuspendingOperation.GetDeferral();
   //TODO: アプリケーションの状態を保存してバックグラウンドの動作があれば停止します
    deferral.Complete();
}