UWPのアプリを作っているうえで、早く知りたかったこと。

More than 1 year has passed since last update.


はじめに

MSがWindows10への切り替えをしつこく行っているため、

WindowsStoreから配布できるUWPの需要は大きくなっているはずです。

私自身、ある程度作れる感触も持てるようになったため、UWPのソフトを作っているうえで、早く知りたかったことをまとめてみました。基本的に自分の興味中心です。配布やテストまでの段階はまだです。

UWP関係は、ドキュメント自体はあるのは嬉しいのですが、バラバラでドキュメントがあるのが困ったところ。

Google検索では、一年以内の条件で検索するのもコツですかね(情弱っぽさあふれるコツ)

間違っていることとか、僕自身もあまりわかっていないので、コメントでの指摘よろしくお願いします。追加すべきものとかもありましたらどうぞ。

最強UWPのサンプル

https://github.com/Microsoft/Windows-universal-samples


インストールすべきNuget


  • Prism.Windows

  • Prism.Unity

  • Mvvmlight

  • ReactiveProperty

  • WinRTXamlToolkit.UWP

Prismは、MvvmまわりとDIまわりを行う。

Mvvmlightは、Prismと被るのだが、メッセージ機構が優れているので使う。 MVVMLightは必要なかった

ReactivePropertyは、反応させるプロパティを作ることができる。日本語ドキュメントはたくさんあるのでそちらでどうぞ。

WinRTXamlToolkit.UWPは、UIの部品や、Converterなどが多数ある。標準で用意しろよ・・と思うもの多数。


PCL と shared-project(共有プロジェクト) の違い

http://stackoverflow.com/questions/30634753/what-is-the-difference-between-a-shared-project-and-a-class-library-in-visual-st

PCLは制限多い。ストレス溜まる。shared-projectは、ストレス小さめ。

shared-projectは、本体にソースコードが挿入されるので、本体を参照でき、後述するMessengerパターンが必要なかったりもする。ただ、後で苦しみそうだし、#If がソースコードに満ちるのは辛そう。

shared-projectから別のshared-projectを見ることができないので、使い方は考えるべき。

そのため、複数のアプリで、共通する処理はPCL

そのUWPアプリの処理(モデル?)はshared-projectにして、

ViewとViewModelは、UWPプロジェクトが持つという風にしておくと、

後々のクロスプラットフォームとき、いいのじゃないかな?


MVVMフレームワーク

WPFの後継であるUWPは、データバディング機構を持ち、MVVMで開発でき、UIまわりは、XAMLで記述するようになっている。JSだと、Angularなどの考え方と同じ。

イベント起動で、コードビハインドの記述を行うサンプルを見かけるが、そのようなことを行うのは、非奨励で、緊急時のみ。UI的に仕方ない時はあるけどね。

Xamarinでの、クロスプラットフォームの開発まで見通すと、model viewmodelは、共有可能なようにして、プラットフォーム依存の実装を避けたい。

Mvvmフレームワークは、疎結合で、固有実装を避け、テストのしやすさを高めるような仕組みになっている。


Prism

Prismは、元々Microsoft社が作っていたライブラリ。今は、オープンソースで、gitにコードがある。mvvmの基本機能に加え、自動的にviewとviewmodelを紐づけたり、DI(依存性の注入)ができるのがつおい。大規模ソフトウェア開発にも対応できる仕組みになっている。そのため、やや大げさで複雑な機構を持つ。UWP的には、ナビゲーションまわりの便利機構を勝手に自動搭載してくれている。さあ、app.xaml.cs のApplicationクラスを PrismUnityApplicationに差し替えよう。(https://github.com/runceel/PrismEdu/blob/master/UWP/02.HelloWorld/README.md)


Prismのドキュメント


githubの英語版

https://github.com/PrismLibrary/Prism/tree/master/docs

WPFのところを読むいい。


Prismのコンセプトの日本語訳

やや古いけど(2011年)コンセプトは変わらないはず。読んでいて勉強になる。

https://msdn.microsoft.com/ja-jp/library/gg592959.aspx

デメリットに「ソース コードの複雑さが増し、理解が困難になる。」を繰り返しており、涙なしには読めない。


Prismの日本語解説

https://github.com/runceel/PrismEdu

WPFのところも関係している。


Prism のサンプル

https://github.com/PrismLibrary/Prism-Samples-Windows

一番ためになる。AdventureWorks.ShopperはPrismを使った本格的なソフトウェアのサンプルですごくいい。細切れの解説ブログでは、どのように全体像をつくるの??というのがちんぷんかんぷんだったので、非常にためになった。神。


複数のVM間で共有するオブジェクトはどうやるの?

DIを使う。App.xaml.csで、登録して、ViewModelのコンストラクタに入れる。View側に、魔法の言葉「 prismMvvm:ViewModelLocator.AutoWireViewModel="True"」を入れる。

共有するオブジェクト自体を差し替えることがある場合は、オブジェクトを挟む。


Prismの名前規則

名前によって、ViewとViewModelが紐づく。

基本的に、Viewsフォルダ、ViewModelsフォルダを作って、そこに入れていく。

このルールを変えるサンプルは、AdventureWorks.Shopperにある。

inavigationService を使うと、Page遷移を行うことができる。この時の名前には注意。

UserContorlなどのPage以外のものでもViewModelLocator.AutoWireViewModel="True"で紐づき、DIされる。

        
名前    
コメント

View
名前
Views名前空間に配置

ViewModel
名前ViewModel
ViewModels名前空間に配置

Page
名前Page
Views名前空間に配置。Pageをつける

ViewModel
名前PageViewModel
ViewModels名前空間に配置

Navigete
名前
Pageがない!


Messengerパターンはどうやるの?

ダイアログを出すなどの、Viewに対する命令は、古いMVVMの解説では、Messengerパターンを使うことを奨励している。しかし、これは過去の方法であり、DIを使ってXXXXServiceを介してを行うのが、今時のやり方。そもそも、NavigeteもViewに対する処理であり、iNavigationServiceも同様な仕組み。

MVVMな設計のTips~サービスを作ってVMの依存性を排除~

↑良記事


ContentDialogは非常に強力

Dialog自体を自分で記述できるContentDialogはとてもつよい。呼び出し方は、Messengerパターンで。


UWPのPopup/Flyout/Dialog系のコントロール

http://sourcechord.hatenablog.com/entry/2015/09/19/233538


ContentDialogのサイズが指定したものと一致しない

http://mag.autumn.org/Content.modf?id=20150819134833

でもこういう困ったことがある。WindowsPhoneにも対応しているためですかね。


XAMLまわり


横にメニューが出るのを作りたいのだけど。

https://github.com/PrismLibrary/Prism-Samples-Windows/tree/master/SplitViewSample/SplitViewSample

パーフェクトサンプル


TabControlがないのだけど?

Pivotコントロールを使う。


あのコントロールがないのだけど。

WinRTXamlToolkit(https://github.com/xyzzer/WinRTXamlToolkit )から探す。

SliverlightToolkitの後継みたいなもの。

標準でほしいよ、と思う、ControlやConverterなどが多数ある。

なければ、自分で作る。(まて)


DataBindingに String formatがないのだけど・・・

コンバーター作れ。

http://stackoverflow.com/questions/34026332/string-format-using-uwp-and-xbind

MVVM的に完結するためにも、その他、コンバータをたくさん作る模様。


よくあるアイコン画像一覧はどこ??? 

アイコンのフォント一覧

http://modernicons.io/segoe-mdl2/cheatsheet/

<Button Content="&#xE894;" FontFamily="{ThemeResource SymbolThemeFontFamily}"/>

こういう感じで、FontFamilyも追加しておく。

他にも、フリーのアイコン集

https://materialdesignicons.com/


テキトウなカコイイデザインテンプレートってないの?

知りたい。https://github.com/ButchersBoy/MaterialDesignInXamlToolkit のUWP版ちゃん、息していない。


CSSのようなものは?

リソースディクショナリ。


Bootstrapのグリッドシステムのようなレイアウトはできないの?

http://sourcechord.hatenablog.com/entry/2016/07/02/011702


Binding とx:Bindの違いは何?

実行時実行か、コンパイルするか、の違い。動的型付け言語がいいのか、静的型付け言語がいいのか、みたいな話。

Bindingは実行してみないとわからない。エラーはデバッグログに出る。

x:Bindの方が新しいだけあって、Bindingでは無理だったことがx:Bindであっさりできるようになっている。イベントのBindが強力。ICommandとはなんだったのか。Bind先の型を変えると、静的なだけあって、やや大変なことになる。


XAMLデザイナーがエラーで開けなくなった

警告を潰そう。リビルドしてみる。Visual Studioの再起動。OSの再起動。ゾンビのプロセスがある模様?全体的に謎い。


デザインで入力補助が効かなくて、Bindingがとてもつらいのだけど。

d:DataContext で、対象のViewModelを指定しよう。

d:DataContext="{d:DesignInstance Type=vm:XXViewModel}"  

PrismでDIを使っているViewModelの場合、そのままだと、コンストラクタが動かないと言われてエラーが頻発する。そのため、このようにして、変数なしのコンストラクタを作り、[InjectionConstructor]をつけた、DIして本番で使いたいものを指定する。

        public MenuViewModel()

{ }

[InjectionConstructor]
public MenuViewModel(INavigationService navigationService)
{
this.navigationService = navigationService;
}

X:Bind関係も入力補助が機能しないのだけど??(わからない)

生産性上げる方法教えてください。


複雑なXAMLを書いていられるか。

Blendを使おう。Visual Studioについています。

テンプレートコントロールを作るといいみたい。


文字列のデータバディング

<TextBlock >(<Run Text="{Binding Count,Mode=OneWay}"/>)</TextBlock>

長いなぁ・・


Modelでの色の扱い方は?

uintで扱うといい。書いた http://qiita.com/kiichi54321/items/56140dba6a58fdbb8f58


Bindingが機能しないプロパティがあるのだけど

Behaviorを使おう。X:Bindによって解決する場面もある。

対象のコントロールを継承して、DependencyPropertyを作るという方法もある。


値更新が反映されないのですけど?

Mode=OneWayにしよう。入力を反映させるには、Mode=TwoWay


Bindingがうまく行っていないところがある??

デバッグログを見よう。


ListBoxのアイテムの間隔が大きすぎる。

タッチパネル対応だから・・・・

    <ListBox.ItemContainerStyle>

<Style TargetType="ListBoxItem">
<Setter Property="Padding" Value="0"/>
</Style>
</ListBox.ItemContainerStyle>


ListBoxのSelectedItemsにBindingができないのだけど(怒


taskから値を更新しようとすると怒られるんですけど。

UIスレッド以外では、UIの更新はできない。

非同期構文を使おう。

または、



  GalaSoft.MvvmLight.Threading.DispatcherHelper.CheckBeginInvokeOnUI(() => { });



を使うと、UIスレッドで実行される。DispatcherHelperは、app.xaml.csで初期化しよう。結局はこれが楽。


よくある検索ボックスを作りたい

Auto-suggest box を使う。

https://msdn.microsoft.com/en-us/windows/uwp/controls-and-patterns/auto-suggest-box

   <AutoSuggestBox Text="{x:Bind ViewModel.SearchText,Mode=TwoWay}" 

   ItemsSource="{x:Bind ViewModel.SuggestList,Mode=OneWay}"
   QueryIcon="Find" QuerySubmitted="{x:Bind ViewModel.SearchQuery}" ></AutoSuggestBox>
<ListBox ItemsSource="{x:Bind ViewModel.ResultList,Mode=OneWay}" ></ListBox>

SearchTextが変更されたときに、SuggestListを書き換えて、SearchQueryでSearchTextをもとに検索を行いResultListを書き換えるという感じでやる。


オブジェクトの内容でデータテンプレートを切り替える

DataTemplateSelectorを使う。


その他


ViewModelで同じようなものをひたすら書かないといけないのが辛い

CodeSnippetを作る。作るのは簡単。

http://yutawatanabe.hatenablog.com/entry/mvvm-cross-code-snippet-add-to-visual-studio


FilePickerで取ってきたStreamの使い方がわからん

方法: .NET Framework ストリームと Windows ランタイム ストリームの間で変換を行う

https://msdn.microsoft.com/ja-jp/library/dn531021(v=vs.110).aspx

System.IOに拡張メソッドがある。


バックグランド処理はTaskでテキトウにやるんでしょ?

ちがう。バックグランド用の機構がある。Windows.ApplicationModel.Background名前空間

バックグラウンド タスクの作成と登録


テンプレート &MVVMライブラリ

https://github.com/Windows-XAML/Template10

ビヘイビア回りは、参考になる。そこそこ使われている模様。


UWPアプリにおける正しいnetworking APIの使い方

https://docs.com/akira-hatsune/5609/uwp-networking-api


サンプルをコンパイルして動かそうとしたら、WidowsPhoneがないとか怒れれる。持っていないよ。

デバッグの構成をx86あたりにする。


修正箇所


  • MVVMLightは必要なかった

  • メッセージパターンまわりの記述修正

  • [InjectionConstructor]の使い方追加。

  • Windows.ApplicationModel.Backgroundの使い方

  • ListBoxのSelectedItemsの扱い

  • PrismのドキュメントのURL変更
    ツッコミ待ちです。では。