Windowsフォーム開発者のためのWindows 10 UWPアプリ開発入門(後編):特集:UWPとは何か(1/5 ページ)
本稿ではデータバインド/非同期処理/ファイル操作/クラウド型アーキテクチャという、Windowsフォームとは異なるUWPプログラミングの特徴を取り上げる。
powered by Insider.NET
PCだけでなく、さまざまなデバイスで動くUWPアプリ*1(次の画像)。Windows 10と同時に登場したこの新しいアプリ形式に興味をお持ちの読者はきっと多いことだろう。しかしながら、例えば仕事でWindowsフォームの業務アプリを作っているという開発者にとっては、大きなギャップがある。
![UWPアプリの例](https://image.itmedia.co.jp/ait/articles/1510/06/ap-01.gif)
UWPアプリの例
Windows 10のデスクトップ上で動作しているUWPアプリ(左)と、Windows 10 Mobileエミュレーターで動作しているUWPアプリ(右)。この二つは同一のバイナリが動いているのである。この他にも動作するデバイスの種類は多い(前編参照)。
そこで本稿では、Windowsフォーム開発者が遭遇するであろう大きなギャップに焦点を当てて、UWPアプリの開発方法を紹介している。なお、本稿のサンプルは「Windows Store app samples」からダウンロードできる。
前編では、UWPアプリの特徴を紹介した後、UI作成の初歩を丁寧に説明した。
【前編】
- UWPアプリの特徴
- 「Hello, UWP!」〜UIはXAMLで
この後編では、Windowsフォーム開発者にとって大きなギャップとなる課題を四つ選んで解説していく。
【後編】
3. 画面にデータを表示する〜データバインド
4. 非同期! 非同期! 非同期!〜async/await
5. ファイルの読み書き〜セキュリティ優先設計
6. Webサービスの利用〜「クラウド型」アーキテクチャ
*1 Windows 10のユニバーサルWindowsプラットフォーム用のアプリ。「アプリ」とはプログラムのこと。「UWPアプリ」は、マイクロソフトの文書でも用語そのものやその意味に揺らぎがあるが、本稿ではWindows 10のユニバーサルWindowsプラットフォームで動作するアプリに限定する。ただし、モバイルデバイス(スマートフォン)向けWindows 10のAndroidサブシステムで動作するもの(Project Astoria)、デスクトップPC/ノートPC/タブレット(モバイルデバイスを除く)向けWindows 10用のProject Centennial(2016年リリース予定)、および全Windows 10デバイス向けの「ホストされたWebアプリ」(Project Westminster)は、本稿では除外する。
事前準備
デスクトップ用とモバイル(=Windows 10を搭載したスマートフォンなど)用のUWPアプリを開発するには、Windows 10とVisual Studio 2015(および、Windows SDK for Windows 10)が必要だ。詳しくは前編を参照してもらいたい。本稿では、無償のVisual Studio Community 2015を使っている。
3. 画面にデータを表示する〜データバインド
画面にデータを表示する方法として、前編ではコードビハインドからUIコントロールのプロパティを変更した。しかし、UWPアプリではデータバインド(あるいは「データバインディング」ともいう)という方法を使うのが主流だ。本稿では説明していないが、複雑なUIの実現のためにUWPアプリではデータテンプレートという仕組みを使う。そのときの表示にはデータバインドが必須なのである。
Windowsフォームでのデータバインド
あまり活用されていないように思うのだが、実はWindowsフォームにもデータバインドの仕組みはあるのだ。実装する方法はUWPアプリとはずいぶん違うのだが、根本的な考え方は同じだ。ここでは、データバインドになじみのない読者のために、Windowsフォームで説明しよう。次の図をご覧いただきたい。データオブジェクト(ここでは「PersonData」クラスのオブジェクト)のプロパティに保持している値が変われば、データバインドによってフォーム上のUIコントロールのプロパティも自動的に変わる。逆に、UIコントロールのプロパティを変えれば、自動的にデータオブジェクトのプロパティへ反映される。このように、いったんデータバインドを確立してしまえば、後は自動的に値の変化を相互に反映させられるのである(相互ではなく一方向のみ、あるいは、一方向に1回のみというバインディングも可能)。
![Windowsフォームのデータバインドの例](https://image.itmedia.co.jp/ait/articles/1510/06/ap-02.gif)
Windowsフォームのデータバインドの例
上: Windowsフォームを開いたとき。PersonDataオブジェクトのプロパティ値が、データバインドによって自動的にUIコントロールのプロパティにセットされる。
中: エンドユーザーがテキストボックスにキー入力してからフォーカスを移すと、その値がデータバインドによって自動的にPersonDataオブジェクトの値に反映される。
下: ボタンのクリックイベントのハンドラー内でPersonDataオブジェクトの値を変更すると、その変更はデータバインドによって自動的にUIコントロールにも反映される。
なお、このようにデータとUIコントロールの間で相互に値が反映される場合を「双方向バインド」と呼ぶ(「双方向のデータバインディング」などとも)。また、データからUIコントロールに値の変化を反映させるには、データのクラスにINotifyPropertyChangedインターフェース(System.ComponentModel名前空間)を実装しておく。
上のようなWindowsフォームアプリを作ってみよう(別途公開のサンプルでは、「S2_DataBind」ディレクトリの下にある「S2_01_WinForm」プロジェクト)。Windowsフォームのプロジェクトを作ったら、次のコードのように「PersonData」クラスを追加する。
using System;
using System.ComponentModel;
using System.Runtime.CompilerServices;
namespace S2_01_WinForm
{
public class PersonData : INotifyPropertyChanged
{
private string _姓;
public string 姓
{
get { return _姓; }
set
{
if (_姓 == value) return;
SetProperty<string>(ref _姓, value);
}
}
// 「名」プロパティも同様(省略)
……省略……
// 以下、INotifyPropertyChangedインターフェースの実装
public event PropertyChangedEventHandler PropertyChanged;
protected bool SetProperty<T>(ref T storage, T value,
[CallerMemberName] String propertyName = null)
{
if (object.Equals(storage, value)) return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}
Windowsフォームのプロジェクトを作り、「PersonData.cs」ファイルを追加し、このように書き変える(名前空間の宣言は適宜修正してほしい)。
データの変更をデータバインドによって自動的にUIコントロールへ反映させるには、このようにINotifyPropertyChangedインターフェースを実装する必要がある(そうせずに、コードビハインドからデータバインドを更新する方法もある)。
なお、このコードではVisual Studio 2015から利用可能になったNull条件演算子を使っている。
次に、「Form1.cs」ファイルのビューデザイナー(デザイン画面)を開いて、UIを作る(具体的には別途公開のサンプルを見てほしい)。一通りUIコントロールを配置し終えたら、一度、プロジェクトをビルドしてから、データバインドの設定を行う(次の画像)。
メニューバーの[プロジェクト]−[新しいデータソースの追加]を選び、
[データ ソース構成ウィザード]を開く
(左端の[データソース]タブからでも開ける)
[データ ソースの種類の選択]で[オブジェクト]を選び、
[次へ]ボタンをクリック
ダイアログを閉じ、今度はツールボックスの[データ]セクションにある
[BindingSource]コントロールをダブルクリック
それをクリックし、プロパティウィンドウで[DataSource]欄を見つけ、
その右のドロップダウンを展開する
[プロジェクト データ ソース]内の[PersonData]を選択する。
次に、「姓」入力用のTextBoxコントロールをクリックし、
プロパティウィンドウを見る
出てきたポップアップで[姓]を選択する。
続けて他のコントロールにも、同様にしてデータバインドを設定する
データバインドを設定する手順(Windowsフォーム)
以上の作業が終わったら、ボタンのイベントハンドラーを作り、「Form1.cs」ファイルのコードビハインドに次のようなコードを追加する。これで完成である。
private PersonData _data;
private void Form1_Load(object sender, EventArgs e)
{
// 初期表示用のデータを作成
_data = new PersonData() { 姓 = "山本", 名 = "康彦", };
// BindingSourceコントロールにデータを設定
bindingSource1.DataSource = _data;
}
private void button1_Click(object sender, EventArgs e)
{
// ボタンがクリックされたらデータを変更する
_data.姓 = "かわさき";
_data.名 = "しんじ";
}
コードビハインドからは、BindingSourceコントロールにデータを設定しただけで、その他にはUIコントロールのプロパティは操作していない。しかし、データバインドにより、前掲の図のようなデータとUIコントロールの相互作用が実現されるのだ。
Copyright© Digital Advantage Corp. All Rights Reserved.