307
322

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-04-07

#はじめに
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="&#xE894;" 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ができないのだけど(怒

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変更
    ツッコミ待ちです。では。
307
322
5

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
307
322

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?