XamarinでMvvm Light
2017年3月19日
前回作ったXamarinアプリでMvvm Lightを使ってみた。
DBはREST APIでjsonを取得するので、Json.netも入れた。
Nugetで入れる
コアプロジェクトに入れる
①MvvmLight
②MvvmLightLibs
③Json.net
コード修正
①ViewModelLocator
App.xamlでリソースになっていなかったのでstaticメソッドにした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
public class ViewModelLocator { /// <summary> /// Initializes a new instance of the ViewModelLocator class. /// </summary> public ViewModelLocator() { //ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); ////if (ViewModelBase.IsInDesignModeStatic) ////{ //// // Create design time view services and models //// SimpleIoc.Default.Register<IDataService, DesignDataService>(); ////} ////else ////{ //// // Create run time view services and models //// SimpleIoc.Default.Register<IDataService, DataService>(); ////} //SimpleIoc.Default.Register<MainViewModel>(); } public static void Setup() { ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default); SimpleIoc.Default.Register<MainViewModel>(() => { return new MainViewModel(DBManager.GetInstance()); }); SimpleIoc.Default.Register<MainView>(); } public static MainViewModel Main { get { return ServiceLocator.Current.GetInstance<MainViewModel>(); } } |
②App.xaml.cs
アプリ起動時にViewModelLocatorを呼んで、MainPageにViewを設定する。
1 2 3 4 5 6 7 8 9 10 11 12 |
public partial class App : Application { public App() { //InitializeComponent(); //MainPage = new blood.MainPage(); ViewModelLocator.Setup(); MainPage = ServiceLocator.Current.GetInstance<MainView>(); } |
③DBアクセス
非同期メソッドしかないようなので、EventでWaitOneして同期にした
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 |
public IList<BloodModel> ReadSync(DateTime from, DateTime to) { var wait = new AutoResetEvent(false); // URL string url = string.Format("http://192.168.0.135/api/blood/{0}/{1}", from.ToString("yyyy-MM-dd"), to.ToString("yyyy-MM-dd")); IList<BloodModel> model = null; HttpWebRequest httpWebRequest = (HttpWebRequest)WebRequest.Create(url); httpWebRequest.Method = "GET"; httpWebRequest.ContentType = "application/json"; httpWebRequest.Headers["Authorization"] = "Basic " + Convert.ToBase64String(Encoding.UTF8.GetBytes("user@usr.usr:password")); //レスポンスを受け取る Task.Run(() => { var response = (IAsyncResult)httpWebRequest.BeginGetResponse((result) => { var request = (HttpWebRequest)result.AsyncState; var res = request.EndGetResponse(result); using (var stream = res.GetResponseStream()) using (var reader = new StreamReader(stream)) { string responseText = reader.ReadToEnd(); model = JsonConvert.DeserializeObject<IList<BloodModel>>(responseText); wait.Set(); } }, httpWebRequest); }); wait.WaitOne(); return model; } |
④XAML
BindingContextにViewModelLocatorのViewModelを指定して。
ContentRenderedが無いのでAppearingをEventToComanndする。
1 2 3 4 5 6 7 8 9 10 11 12 |
<?xml version="1.0" encoding="utf-8" ?> <ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:vm="clr-namespace:blood.ViewModel" xmlns:bhv="clr-namespace:blood.Behavior" BindingContext="{x:Static vm:ViewModelLocator.Main}" xmlns:cnv="clr-namespace:blood.Converter" x:Class="blood.View.MainView"> <ContentPage.Behaviors> <bhv:EventToCommandBehavior EventName="Appearing" Command="{Binding AppearingCommand}"/> </ContentPage.Behaviors> <ContentPage.Resources> |
※ WPFみたいにSystem.Windows.Interactivityのやつは使えないみたいなので、Behaviorは参考サイトより入れた。
⑤VM
Appearingイベントのコマンドで初回データを取得して表示するようにした。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
private RelayCommand<object> _AppearingCommand; /// <summary> /// ContentRenderedCommand /// </summary> public RelayCommand<object> AppearingCommand { get { if (_AppearingCommand == null) { _AppearingCommand = new RelayCommand<object>((e) => { var list = _DBManager.ReadSync(DateTime.Now.AddDays(-10), DateTime.Now); BloodList = new ObservableCollection<BloodModel>(list.OrderByDescending(x => x.Time).OrderByDescending(x => x.Date)); }); } return _AppearingCommand; } } |
⑥その他
converterとかBindingは普通に使えるので、適当に作る
実行
ショボい。(´・ω・`)
でもまあ、Mvvm Lightで作っていけそうだ。
—
参考サイト
http://www.nuits.jp/entry/2016/07/01/001312
https://rksoftware.wordpress.com/2016/07/18/001-42/