Xamarin формы читают локальный json файл и отображают в окне выбора - PullRequest
0 голосов
/ 27 марта 2020

Я пытаюсь разобрать файл json контактов в список и отобразить этот список пользователю в средстве выбора на моей странице с отображением имен контактов.

У меня есть файл json в root моего проекта под названием "контакты. json" и его действие по сборке установлено на встроенный ресурс.

мои контакты. 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
    }

моя страница.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 в сборщике.

edit 1: Мне удалось заставить их отображаться в списке, поэтому я попытался оттуда получить их в сборщике, но я получаю только список моих типов объектов, а не имен в сборщике. обновлен код для отражения изменений. изображение телефона с видом и списком контактов (пока не могу вставлять картинки, недостаточно реп.).

edit2: изменен код для отображения @Cherry Bu- MSFT Реализация

1 Ответ

0 голосов
/ 27 марта 2020

Согласно вашему описанию, я делаю один пример, который вы можете посмотреть:

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 и отобразить данные в ListView с помощью mvvm, пожалуйста, посмотрите следующий код, я использую Mvvm Mode.

 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 - это класс, реализующий 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)
                    {

                    }
                }
            }
        }
    }

enter image description here

...