#c# #json #linq
Вопрос:
У меня есть программа, в которой пользователь должен получить текст из json на основе главы, нажатой в протоколе элементом listview (главы).
Что происходит не так, так это когда пользователь нажимает кнопку «Далее», когда он не выбирает первую главу в протоколе. Он всегда видит идентификатор 2, который относится к первой главе! Как мне заставить его нажать на любую главу, в которой пользователь видит текст со следующим идентификатором?
следующая проблема, с которой я сталкиваюсь, заключается в том, что когда я нахожусь в последней главе, и я нажимаю «Назад», затем я попадаю в другую главу System.NullReferenceException: 'Object reference not set to an instance of an object.'
, продолжайте string nextTitile = _protocol.Name " - " content.NavTitle;
Как мне это исправить?
Здесь пользователь выбирает выбранную главу в рамках протокола
//for chosen step inside protocol //for chosen step inside protocol public void Handle_ItemTapped(object sender, ItemTappedEventArgs e) { //change title based on clicked step var tappedStep = (Content)MyListView.SelectedItem; int stepIndex = (default); Navigation.PushAsync(new StepView(_protocol, Title, tappedStep.ChapterTitle, stepIndex)); //Deselect item ((ListView)sender).SelectedItem = null; }
вот класс stepview, в котором пользователь получает текст, связанный с выбранной главой. С соответствующей кнопкой назад и далее, чтобы перейти к следующему тексту
public partial class StepView : ContentPage { //get step private Protocol _protocol; //go to selected step public StepView(Protocol protocol, string title, string chapterTitle) { _protocol = protocol; InitializeComponent(); Title = title " - " chapterTitle; // get label text lblText.Text = protocol.Contents.FirstOrDefault(x =gt; x.ChapterTitle == chapterTitle).Text; } private int index; public void BtnBack_Clicked(object sender, EventArgs e) { index--; var firstId = _protocol.Contents.FirstOrDefault(x =gt; x.Contentid != null).Contentid; BtnNext.IsEnabled = true; if (index == firstId - 1) { BtnBack.IsEnabled = false; } var content = _protocol.Contents.ElementAtOrDefault(index); lblText.Text = content?.Text; //get current navTitle on button click getNewNavTitle(content); } public void BtnNext_Clicked(object sender, EventArgs e) { index ; BtnBack.IsEnabled = true; if (index == _protocol.Contents.Count - 1) { BtnNext.IsEnabled = false; } var content = _protocol.Contents.ElementAtOrDefault(index); lblText.Text = content?.Text; //get current navTitle on button click getNewNavTitle(content); } //get new protocol chapter based on btnBack and btnNext private void getNewNavTitle(Content content) { Title = null; string nextTitile = _protocol.Name " - " content.NavTitle; Title = nextTitile; } //go back to home public void btnHome_Clicked(object sender, EventArgs e) { //go to mainpage Navigation.PushAsync(new MainPage()); }
This is the json I use
{ "protocols": [ { "id": "1", "name": "Pols meten", "contents": [ { "chapterTitle": "Voorzorg", "contentid": "1", "navTitle": "Voorzorg", "text": "voor blabla" }, { "contentid": "2", "navTitle": "Voorzorg", "text": "voor blabla2" }, { "contentid": "3", "navTitle": "Voorzorg", "text": "voor blablabla3" }, { "contentid": "4", "chapterTitle": "Handeling", "navTitle": "Handeling", "text": "Handeling blabla" }, { "contentid": "5", "navTitle": "Handeling", "text": "Handeling blabla2" }, { "contentid": "6", "navTitle": "Handeling", "text": "Handeling blybli3" }, { "contentid": "7", "chapterTitle": "Nazorg", "navTitle": "Nazorg", "text": "Nazorg blabla" }, { "contentid": "8", "navTitle": "Nazorg", "text": "Nazorg blabla2" }, { "contentid": "9", "navTitle": "Nazorg", "text": "Nazorg blybli3" } ] } ] }
And this are my Domain Classes
public partial class RootObject { [JsonProperty("protocols")] public Listlt;Protocolgt; Protocols { get; set; } } public partial class Protocol { [JsonProperty("id")] public long Id { get; set; } [JsonProperty("name")] public string Name { get; set; } [JsonProperty("contents")] public Listlt;Contentgt; Contents { get; set; } } public partial class Content { [JsonProperty("contentid")] public long Contentid { get; set; } [JsonProperty("chapterTitle", NullValueHandling = NullValueHandling.Ignore)] public string ChapterTitle { get; set; } [JsonProperty("text")] public string Text { get; set; } }
Как мне решить свою проблему
Ответ №1:
Я думаю, что обе эти проблемы связаны с тем, что вы не задали index
свойство в своем StepView
конструкторе. Без явного значения свойству нового StepView
экземпляра будет index
присвоено значение default(int)
, которое равно 0
.
Нажатие кнопки «Далее» всегда показывает второй шаг , так BtnNext_Clicked
как он увеличивается index
(до 1
, так как это было 0
), а затем отображает элемент по этому индексу.
Аналогично, BtnBack_Clicked
index
уменьшается (до -1
, так как это было 0
), что означает, что вызов _protocol.Contents.ElementAtOrDefault(index)
вернется null
— позже вызовет NullReferenceException
вход getNewNavTitle
.
Вам необходимо обновить StepView
конструктор, чтобы он правильно установил начальное значение index
:
public StepView(Protocol protocol, string title, string chapterTitle, int stepIndex) { _protocol = protocol; InitializeComponent(); Title = title " - " chapterTitle; // get label text lblText.Text = protocol.Contents.FirstOrDefault(x =gt; x.ChapterTitle == chapterTitle).Text; // Set the "index" property here. You need to make sure that the "stepIndex" // constructor parameter has the appropriate value. index = stepIndex; }
Комментарии:
1. В конструкторе StepView установите
index
правильное значение. Возможно, вам потребуется добавить еще один параметр, чтобы вы могли передать правильное значение, что-то вроде:public StepView(Protocol protocol, string title, string chapterTitle, int currentIndex) { index = currentIndex; }
2. @Teun См. обновление. Это примерно самый «полный» пример, который я могу привести.
3. а как насчет того, чтобы моя кнопка была следующей и обратно? @Пончик
4. Мне также нужно вызвать stepIndex в дескрипторе, как я должен это сделать там?
5. Это то, что тебе нужно выяснить. Вам необходимо определить подходящее значение для stepIndex на основе tappedStep.