tba*_*t17 4 c# data-binding json picker xamarin.forms
我正在尝试将联系人的 json 文件解析为列表,并在显示联系人姓名的页面上的选择器中向用户显示该列表。
我的项目根目录中有一个名为“contacts.json”的 json 文件,其构建操作设置为嵌入资源。
我的 contact.json 文件
{
"contacts": [
{
"name": "JOE",
"email": "name@handle",
"phoneNumber": "123-456-7890"
},
{
"name": "JYM",
"email": "name@handle",
"phoneNumber": "123-456-7890"
}
]
}
Run Code Online (Sandbox Code Playgroud)
我的联系方式:
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; }
}
Run Code Online (Sandbox Code Playgroud)
我的页面视图模型,我在其中实现了 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;
}
}
Run Code Online (Sandbox Code Playgroud)
我的基本视图模型
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
}
Run Code Online (Sandbox Code Playgroud)
我的页面.xaml.cs
public partial class Page10 : ContentPage
{
public Page10()
{
InitializeComponent();
this.BindingContext = new contactviewmodel();
}
}
Run Code Online (Sandbox Code Playgroud)
我的页面 xaml
<ContentPage.Content>
<StackLayout>
<Picker Title="contacts" ItemsSource="{Binding contacts}" ItemDisplayBinding="{Binding Name}"/>
</StackLayout>
</ContentPage.Content>
Run Code Online (Sandbox Code Playgroud)
尝试上述操作后,我在选择时得到一个空的选择器,但我希望在选择器中看到 JOE 和 JYM。
编辑1:我设法让它们显示在列表中,所以我尝试将它们放入选择器中,但我只得到对象类型的列表,而不是选择器中的名称。更新代码以反映更改。 带联系人列表视图和选择器的手机图像(尚无法嵌入图片,代表数量不够)。
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>
Run Code Online (Sandbox Code Playgroud)
请不要忘记实现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;
}
}
Run Code Online (Sandbox Code Playgroud)
ViewModelBase 是实现 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));
}
}
}
Run Code Online (Sandbox Code Playgroud)
再次更新:
您可以使用以下代码来获取 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)
{
}
}
}
}
}
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
5970 次 |
最近记录: |