Кнопки неправильно подсчитывают идентификаторы глав из json, используя linq в c#

#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.