はじめに
第1回、第2回ではWindowsストアアプリケーションのデフォルトのプロジェクトを、第3回では画面を構成する部品「コントロール」について紹介しました。
第4回からは、Windowsストアアプリケーションを開発するうえで避けて通れない概念、「コントラクト」についての紹介を開始しました。引き続き今回紹介するのは、そのうちの「ファイルピッカーコントラクト」「キャッシュファイルアップデーターコントラクト」「連絡先ピッカー拡張機能」「自動再生拡張機能」の4つです。また、「バックグラウンドタスク拡張機能」については、バックグランド処理として別途紹介します。
なお、本記事はXAML+C#での開発を想定しています。
ファイルピッカーコントラクト
ファイルピッカーコントラクトは、ストアアプリ間のファイルの受け渡しを可能にするコントラクトです。
ストアアプリにファイルを渡す「ファイルオープンピッカーコントラクト」と、ストアアプリからファイルを受け取って保存する「ファイル保存ピッカー」があります。以下ではファイルオープンピッカーコントラクトの実装を紹介します。
ファイルオープンピッカーコントラクト
ファイルオープンピッカーコントラクトは、別のストアアプリがFileOpenPickerを用いてファイルを開こうとした際にファイルを提供可能にする機能です。
ストアアプリがFileOpenPickerを用いてファイルを取得しようとすると、ファイル取得のダイアログが起動されます。ファイルオープンピッカーコントラクトに対応するとそのダイアログにファイルの取得先候補として対応したストアアプリが表示されます。
ファイル取得先として選択されたストアアプリは以下に説明するように適切なファイルを返す必要があります。
ファイルオープンピッカーコントラクトの実装
ファイルオープンピッカーコントラクトの利用は、「新しい項目の追加」から「ファイルオープンピッカーコントラクト」を追加する方法が簡単です。
起動処理
ソリューションエクスプローラー上で右クリックし、[追加]-[新しい項目]で「新しい項目の追加」ポップアップを起動します。
「ファイルオープンピッカーコントラクト」を選択し、ポップアップ下部の「名前」項目はデフォルトのまま「FileOpenPickerPage1.xaml」として「追加」ボタンをクリックします。
「追加」することで以下の処理が行われます。
- Package.appxmanifestの宣言タブに「ファイルオープンピッカー」が追加される
- App.xaml.csにOnFileOpenPickerActivatedイベントハンドラーが追加される
- ファイルFileOpenPickerPage1.xamlとFileOpenPickerPage1.xaml.csが追加される
デフォルトでは「すべてのファイルの種類をサポートする」にチェックが入っているので、特定のファイルを扱う場合は、サポートするファイルの拡張子に合わせて修正してください。
OnFileOpenPickerActivatedイベントハンドラーで、以下のようにFileOpenPickerPage1ページクラスを生成、Activateメソッドを呼び出しています。
/// <summary> /// ファイル オープン ピッカーを表示するためにアプリケーションがアクティブにされたときに呼び出されます。 /// </summary> /// <param name="args">アクティベーション要求の詳細。</param> protected override void OnFileOpenPickerActivated(Windows.ApplicationModel.Activation.FileOpenPickerActivatedEventArgs args) { var fileOpenPickerPage = new FileOpenPickerSample_CodeZine.FileOpenPickerPage1(); fileOpenPickerPage.Activate(args); }
Package.appxmanifestの宣言タブの追加によって、ストアアプリがファイルピッカーのファイル取得先の対象として表示されるようになります。ファイルピッカーの対象としてストアアプリが選択された場合、App.xaml.csのOnFileOpenPickerActivatedが呼び出されます。
これでファイルオープンピッカーコントラクトの起動処理ができました。
ファイル呼び出しと元に返す処理
このストアアプリはまだ、何もファイルを返すことができないため、次にファイルを呼び出し元に返す処理を記載します。
FileOpenPickerPage1.xamlには、すでにリスト形式のファイルを表示するためのGridView(Name属性がfileGridView)が記載されていますので、そこに表示するためのファイル候補を追加します。
FileOpenPickerPage1クラスのActivateメソッドに、以下のように候補を追加する方法がコメントで記載されています。
// TODO: this.DefaultViewModel["Files"] を設定して、アイテムのコレクションを表示します。 // 各アイテムには、バインド可能な Image、Title、および Description が含まれている必要があります
コメントに沿うようにActivateメソッドを修正します。
/// <summary> /// 別のアプリケーションがこのアプリケーションのファイルを開く必要がある場合に呼び出されます。 /// </summary> /// <param name="args">Windows と連携して処理するために使用されるアクティベーション データ。</param> public void Activate(FileOpenPickerActivatedEventArgs args) { this._fileOpenPickerUI = args.FileOpenPickerUI; _fileOpenPickerUI.FileRemoved += this.FilePickerUI_FileRemoved; // TODO: this.DefaultViewModel["Files"] を設定して、アイテムのコレクションを表示します。 // 各アイテムには、バインド可能な Image、Title、および Description が含まれている必要があります BitmapImage img = new BitmapImage(); img.UriSource = new Uri("ms-appx:///Assets/Logo.png", UriKind.RelativeOrAbsolute); var items = new [] { new { FileName = "Logo.png", Title = "タイトル", Description = "Description", Image = img } }; this.DefaultViewModel["Files"] = items; this.DefaultViewModel["CanGoUp"] = false; Window.Current.Content = this; Window.Current.Activate(); }
DefaultViewModel["Files"]に、アイテムのリストを渡しています。
これで画像のように、ファイルオープンピッカーコントラクト呼び出し時にファイルを表示できました。
ファイルオープンピッカーコントラクト利用時に、エラーが発生することがあります。その場合StandardStyles.xamlファイルのスタイル定義の「x:Key="StandardFileWithTooltip190x130ItemTemplate"」の記述を確認してください。
ToolTipService.Placement属性がカタカナのマウスと記載されている場合は、Mouseに変更します。
これは日本語化にあたり、余分に翻訳しすぎた結果のようです。
アイテム選択時の処理
リストからアイテムを選択した際の処理について記述します。
FileGridView_SelectionChangedイベントの中で、this._fileOpenPickerUI.AddFileメソッドを用いてファイルを追加することで、呼び出し側にファイルを返すことができます。
/// <summary> /// ファイルの選択したコレクションが変更されたときに呼び出されます。 /// </summary> /// <param name="sender">使用可能なファイルを表示するために使用される GridView インスタンス。</param> /// <param name="e">選択内容を変更した方法を説明するイベント データ。</param> private async void FileGridView_SelectionChanged(object sender, SelectionChangedEventArgs e) { // TODO: this._fileOpenPickerUI.AddFile および this._fileOpenPickerUI.RemoveFile を使用して、 // Windows UI を更新します // 本来アイテムとして選択されたファイルを返す必要がありますが、今回はサンプルとしてLogo.pngを返します var packageLocation = Windows.ApplicationModel.Package.Current.InstalledLocation; var assetsFolder = await packageLocation.GetFolderAsync("Assets"); StorageFile file = await assetsFolder.GetFileAsync("Logo.png"); this._fileOpenPickerUI.AddFile(file.FolderRelativeId, file); }