#はじめに
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(共有プロジェクト) の違い
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 のサンプル
一番ためになる。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="" FontFamily="{ThemeResource SymbolThemeFontFamily}"/>
こういう感じで、FontFamilyも追加しておく。
他にも、フリーのアイコン集
https://materialdesignicons.com/
##テキトウなカコイイデザインテンプレートってないの?
知りたい。https://github.com/ButchersBoy/MaterialDesignInXamlToolkit のUWP版ちゃん、息していない。
CSSのようなものは?
リソースディクショナリ。
Bootstrapのグリッドシステムのようなレイアウトはできないの?
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ができないのだけど(怒
- ビヘイビアで解決する。方向性は、昔書いた記事 http://qiita.com/kiichi54321/items/73c8a0ccf21ce990875d
- SelectedItemsをどうせ使うのは、ボタン押した時だから、コマンドの変数にする。変数の型は、「IList<object>」(超重要)
http://stackoverflow.com/questions/34822340/listview-selecteditems-binding-why-the-list-is-always-null
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変更
ツッコミ待ちです。では。