Xamarin 表单读取本地 json 文件并显示在选择器中
Xamarin forms read local json file and display in picker
我正在尝试将一个 json 联系人文件解析为一个列表,并在我显示联系人姓名的页面上的选择器中将该列表显示给用户。
我的项目根目录中有一个名为 "contacts.json" 的 json 文件,其构建操作设置为嵌入资源。
我的contacts.json文件
{
"contacts": [
{
"name": "JOE",
"email": "name@handle",
"phoneNumber": "123-456-7890"
},
{
"name": "JYM",
"email": "name@handle",
"phoneNumber": "123-456-7890"
}
]
}
我的联系方式:
public partial class RootObject
{
[JsonProperty("contacts")]
public List<Contact> Contacts { get; set; }
}
public partial class Contact
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("email")]
public string Email { get; set; }
[JsonProperty("phoneNumber")]
public string PhoneNumber { get; set; }
}
我的页面视图模型,我在其中实现了 json 解析器
public partial class Page10 : BaseViewModel
{
private List<Contact> _contacts;
public List<InternalContact> contacts
{
get { return _contacts; }
set
{
_contacts = value;
OnPropertyChanged("contacts");
}
}
public Page10()
{
Title = "Spill Info";
contacts = GetJsonData();
}
private List<Contact> GetJsonData()
{
string jsonFileName = "contacts.json";
RootObject ObjContactList = new RootObject();
var assembly = typeof(Page10).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{jsonFileName}");
using (var reader = new System.IO.StreamReader(stream))
{
var jsonString = reader.ReadToEnd();
//Converting JSON Array Objects into generic list
ObjContactList = JsonConvert.DeserializeObject<RootObject>(jsonString);
}
return ObjContactList.Contacts;
}
}
我的 baseViewModel
public class BaseViewModel : INotifyPropertyChanged
{
string title = string.Empty;
public string Title
{
get { return title; }
set { SetProperty(ref title, value); }
}
protected bool SetProperty<T>(ref T backingStore, T value,
[CallerMemberName]string propertyName = "",
Action onChanged = null)
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
return false;
backingStore = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
return true;
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
var changed = PropertyChanged;
if (changed == null)
return;
changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
我的page.xaml.cs
public partial class Page10 : ContentPage
{
public Page10()
{
InitializeComponent();
this.BindingContext = new contactviewmodel();
}
}
我的页面xaml
<ContentPage.Content>
<StackLayout>
<Picker Title="contacts" ItemsSource="{Binding contacts}" ItemDisplayBinding="{Binding Name}"/>
</StackLayout>
</ContentPage.Content>
在尝试以上方法后,我在选择时得到一个空的选择器,但我希望在选择器中看到 JOE 和 JYM。
编辑 1: 我设法让它们显示在列表中,所以我摆弄着试图从那里将它们放入选择器中,但我只得到了我的列表选择器中的对象类型而不是名称。更新代码以反映更改。
image of phone w/ contact list view and picker(还不能嵌入图片,代表不够)。
edit2: 修改代码以显示@Cherry Bu- MSFT 的实现
根据你的描述,我做了一个样品,你可以看看:
public partial class Page10 : ContentPage, INotifyPropertyChanged
{
private List<Contact> _contacts;
public List<Contact> contacts
{
get { return _contacts; }
set
{
_contacts = value;
RaisePropertyChanged("contacts");
}
}
public Page10()
{
InitializeComponent();
contacts = GetJsonData();
this.BindingContext = this;
}
private List<Contact> GetJsonData()
{
string jsonFileName = "contacts.json";
ContactList ObjContactList = new ContactList();
var assembly = typeof(Page10).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{jsonFileName}");
using (var reader = new System.IO.StreamReader(stream))
{
var jsonString = reader.ReadToEnd();
//Converting JSON Array Objects into generic list
ObjContactList = JsonConvert.DeserializeObject<ContactList>(jsonString);
}
return ObjContactList.contacts;
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public partial class ContactList
{
[JsonProperty("contacts")]
public List<Contact> contacts { get; set; }
}
public partial class Contact
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("email")]
public string Email { get; set; }
[JsonProperty("phoneNumber")]
public string PhoneNumber { get; set; }
}
<StackLayout>
<ListView x:Name="MyListView" ItemsSource="{Binding contacts}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Detail="{Binding Email}" Text="{Binding Name}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Picker
x:Name="MyPicker"
ItemDisplayBinding="{Binding Name}"
ItemsSource="{Binding contacts}" />
</StackLayout>
请不要忘记实施 INotifyPropertychanged 接口以更新 nofity 数据。
更新:
如果你想获取本地Json文件并使用mvvm在ListView中显示数据,请看下面的代码,我使用的是Mvvm模式。
public partial class Page10 : ContentPage
{
public Page10()
{
InitializeComponent();
this.BindingContext = new contactviewmodel();
}
}
public class contactviewmodel:ViewModelBase
{
private List<Contact> _contacts;
public List<Contact> contacts
{
get { return _contacts; }
set
{
_contacts = value;
RaisePropertyChanged("contacts");
}
}
public contactviewmodel()
{
contacts = GetJsonData();
}
private List<Contact> GetJsonData()
{
string jsonFileName = "contacts.json";
ContactList ObjContactList = new ContactList();
var assembly = typeof(Page10).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{jsonFileName}");
using (var reader = new System.IO.StreamReader(stream))
{
var jsonString = reader.ReadToEnd();
//Converting JSON Array Objects into generic list
ObjContactList = JsonConvert.DeserializeObject<ContactList>(jsonString);
}
//Binding listview with json string
return ObjContactList.contacts;
}
}
ViewModelBase 是 class 实现 INotifyPropertyChanged:
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
再次更新:
您可以使用以下代码获取 Json 文件。
private void LoadData()
{
var assembly = typeof(Page10).GetTypeInfo().Assembly;
foreach (var res in assembly.GetManifestResourceNames())
{
if (res.Contains("contacts1.json"))
{
Stream stream = assembly.GetManifestResourceStream(res);
using (var reader = new StreamReader(stream))
{
string data = "";
while ((data = reader.ReadLine()) != null)
{
}
}
}
}
}
我正在尝试将一个 json 联系人文件解析为一个列表,并在我显示联系人姓名的页面上的选择器中将该列表显示给用户。
我的项目根目录中有一个名为 "contacts.json" 的 json 文件,其构建操作设置为嵌入资源。
我的contacts.json文件
{
"contacts": [
{
"name": "JOE",
"email": "name@handle",
"phoneNumber": "123-456-7890"
},
{
"name": "JYM",
"email": "name@handle",
"phoneNumber": "123-456-7890"
}
]
}
我的联系方式:
public partial class RootObject
{
[JsonProperty("contacts")]
public List<Contact> Contacts { get; set; }
}
public partial class Contact
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("email")]
public string Email { get; set; }
[JsonProperty("phoneNumber")]
public string PhoneNumber { get; set; }
}
我的页面视图模型,我在其中实现了 json 解析器
public partial class Page10 : BaseViewModel
{
private List<Contact> _contacts;
public List<InternalContact> contacts
{
get { return _contacts; }
set
{
_contacts = value;
OnPropertyChanged("contacts");
}
}
public Page10()
{
Title = "Spill Info";
contacts = GetJsonData();
}
private List<Contact> GetJsonData()
{
string jsonFileName = "contacts.json";
RootObject ObjContactList = new RootObject();
var assembly = typeof(Page10).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{jsonFileName}");
using (var reader = new System.IO.StreamReader(stream))
{
var jsonString = reader.ReadToEnd();
//Converting JSON Array Objects into generic list
ObjContactList = JsonConvert.DeserializeObject<RootObject>(jsonString);
}
return ObjContactList.Contacts;
}
}
我的 baseViewModel
public class BaseViewModel : INotifyPropertyChanged
{
string title = string.Empty;
public string Title
{
get { return title; }
set { SetProperty(ref title, value); }
}
protected bool SetProperty<T>(ref T backingStore, T value,
[CallerMemberName]string propertyName = "",
Action onChanged = null)
{
if (EqualityComparer<T>.Default.Equals(backingStore, value))
return false;
backingStore = value;
onChanged?.Invoke();
OnPropertyChanged(propertyName);
return true;
}
#region INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string propertyName = "")
{
var changed = PropertyChanged;
if (changed == null)
return;
changed.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion
}
我的page.xaml.cs
public partial class Page10 : ContentPage
{
public Page10()
{
InitializeComponent();
this.BindingContext = new contactviewmodel();
}
}
我的页面xaml
<ContentPage.Content>
<StackLayout>
<Picker Title="contacts" ItemsSource="{Binding contacts}" ItemDisplayBinding="{Binding Name}"/>
</StackLayout>
</ContentPage.Content>
在尝试以上方法后,我在选择时得到一个空的选择器,但我希望在选择器中看到 JOE 和 JYM。
编辑 1: 我设法让它们显示在列表中,所以我摆弄着试图从那里将它们放入选择器中,但我只得到了我的列表选择器中的对象类型而不是名称。更新代码以反映更改。 image of phone w/ contact list view and picker(还不能嵌入图片,代表不够)。
edit2: 修改代码以显示@Cherry Bu- MSFT 的实现
根据你的描述,我做了一个样品,你可以看看:
public partial class Page10 : ContentPage, INotifyPropertyChanged
{
private List<Contact> _contacts;
public List<Contact> contacts
{
get { return _contacts; }
set
{
_contacts = value;
RaisePropertyChanged("contacts");
}
}
public Page10()
{
InitializeComponent();
contacts = GetJsonData();
this.BindingContext = this;
}
private List<Contact> GetJsonData()
{
string jsonFileName = "contacts.json";
ContactList ObjContactList = new ContactList();
var assembly = typeof(Page10).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{jsonFileName}");
using (var reader = new System.IO.StreamReader(stream))
{
var jsonString = reader.ReadToEnd();
//Converting JSON Array Objects into generic list
ObjContactList = JsonConvert.DeserializeObject<ContactList>(jsonString);
}
return ObjContactList.contacts;
}
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
public partial class ContactList
{
[JsonProperty("contacts")]
public List<Contact> contacts { get; set; }
}
public partial class Contact
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("email")]
public string Email { get; set; }
[JsonProperty("phoneNumber")]
public string PhoneNumber { get; set; }
}
<StackLayout>
<ListView x:Name="MyListView" ItemsSource="{Binding contacts}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell Detail="{Binding Email}" Text="{Binding Name}" />
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<Picker
x:Name="MyPicker"
ItemDisplayBinding="{Binding Name}"
ItemsSource="{Binding contacts}" />
</StackLayout>
请不要忘记实施 INotifyPropertychanged 接口以更新 nofity 数据。
更新:
如果你想获取本地Json文件并使用mvvm在ListView中显示数据,请看下面的代码,我使用的是Mvvm模式。
public partial class Page10 : ContentPage
{
public Page10()
{
InitializeComponent();
this.BindingContext = new contactviewmodel();
}
}
public class contactviewmodel:ViewModelBase
{
private List<Contact> _contacts;
public List<Contact> contacts
{
get { return _contacts; }
set
{
_contacts = value;
RaisePropertyChanged("contacts");
}
}
public contactviewmodel()
{
contacts = GetJsonData();
}
private List<Contact> GetJsonData()
{
string jsonFileName = "contacts.json";
ContactList ObjContactList = new ContactList();
var assembly = typeof(Page10).GetTypeInfo().Assembly;
Stream stream = assembly.GetManifestResourceStream($"{assembly.GetName().Name}.{jsonFileName}");
using (var reader = new System.IO.StreamReader(stream))
{
var jsonString = reader.ReadToEnd();
//Converting JSON Array Objects into generic list
ObjContactList = JsonConvert.DeserializeObject<ContactList>(jsonString);
}
//Binding listview with json string
return ObjContactList.contacts;
}
}
ViewModelBase 是 class 实现 INotifyPropertyChanged:
public class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public void RaisePropertyChanged(string propertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(propertyName));
}
}
}
再次更新:
您可以使用以下代码获取 Json 文件。
private void LoadData()
{
var assembly = typeof(Page10).GetTypeInfo().Assembly;
foreach (var res in assembly.GetManifestResourceNames())
{
if (res.Contains("contacts1.json"))
{
Stream stream = assembly.GetManifestResourceStream(res);
using (var reader = new StreamReader(stream))
{
string data = "";
while ((data = reader.ReadLine()) != null)
{
}
}
}
}
}