やりたいこと
サーバよりJsonでデータを取得してMVVMで画面に表示したい。
Jsonデータは以下の通りです。
- Code(データ取得状態コード) ※アプリ内共通
- Message(エラーメッセージ) ※アプリ内共通
- Data(詳細データ)※アプリ内各所個別
そのため、以下のようにクラスを作成
C#
1 public class JsonData<T> 2 { 3 public int Code 4 { 5 get; set; 6 } 7 public string Message 8 { 9 get; set; 10 } 11 public T Data 12 { 13 get; set; 14 } 15 } 16 public class OrgData: BindableBase 17 { 18 int _ID; 19 public int ID 20 { 21 get 22 { 23 return _ID; 24 } 25 set 26 { 27 SetProperty(ref _ID, value); 28 } 29 } 30 string _Text; 31 public string Text 32 { 33 get 34 { 35 return _Text; 36 } 37 set 38 { 39 SetProperty(ref _Text, value); 40 } 41 } 42 } 43 public abstract class BindableBase :INotifyPropertyChanged 44 { 45 public event PropertyChangedEventHandler PropertyChanged; 46 protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] String propertyName = null) 47 { 48 if(object.Equals(storage, value)) 49 return false; 50 51 storage = value; 52 this.OnPropertyChanged(propertyName); 53 return true; 54 } 55 protected void OnPropertyChanged([CallerMemberName] string propertyName = null) 56 { 57 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 58 } 59 }
作った環境
画面側は以下の通りです。
今回はテストのためEntryに入力したJson文字列をMVVMで画面するものを作成しています。
XAML
1<?xml version="1.0" encoding="utf-8" ?> 2<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" 3 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 4 x:Class="App1.Page1"> 5 <StackLayout x:Name="stackMain"> 6 <Entry x:Name="txtData" /> 7 <Label Text="{Binding ID}" /> 8 <Label Text="{Binding Text}" /> 9 <Button x:Name="btn1" 10 Text="GetData" /> 11 </StackLayout> 12</ContentPage>
C#
1using System; 2using Xamarin.Forms; 3using Newtonsoft.Json; 4 5namespace App1 6{ 7 public partial class Page1 :ContentPage 8 { 9 public Page1() 10 { 11 InitializeComponent(); 12 var _vm = new JsonData<OrgData> { Data = new OrgData() }; 13 stackMain.BindingContext = _vm.Data; 14 this.btn1.Clicked += (sender, e) => 15 { 16 try 17 { 18 var ret = txtData.Text; 19 _vm = JsonConvert.DeserializeObject<JsonData<OrgData>>(ret); 20 } 21 catch(Exception ex) 22 { 23 DisplayAlert("error", ex.Message, "OK"); 24 } 25 }; 26 } 27 } 28}
困っていること
_vm = JsonConvert.DeserializeObject<JsonData<OrgData>>(ret); の場所で、新しくオブジェクトが生成されるためか、PropertyChanged がnullとなり画面に反映されませんでした。
ちなみに、JsonConvertをせず、一つ一つプロパティをセットすると問題なく反映されました。
考えてみたこと
-
Type.GetPropertiesで回してコード上簡潔に1つずつプロパティをセットしようと考えましたが、Xamarin上?ではGetPropertiesはアクセスできず、できませんでした。
-
もう一つ上にViewModelを作成して反映させる
C#
1 public class BindingData:BindableBase 2 { 3 OrgData _data; 4 public OrgData Data 5 { 6 get 7 { 8 return _data; 9 } 10 set 11 { 12 SetProperty(ref _data, value); 13 } 14 } 15 }
こちらもPropertyChangedがnullになりだめでした。
ご回答いただきたいこと
そのままですが、サーバからデータを取得してMVVMで表示したいと思ったときに、皆様はどのような方法をとられていますか?
項目数が多い場合も考慮して、一つ一つプロパティをセットすることは避けたいです。
回答3件
あなたの回答
tips
プレビュー