如何在 C# 中使用 Linq to JSON 在单击按钮时检索下一个和上一个 id
Posted
技术标签:
【中文标题】如何在 C# 中使用 Linq to JSON 在单击按钮时检索下一个和上一个 id【英文标题】:How to retrieve the next and previous ids on a button click using Linq to JSON in C# 【发布时间】:2021-12-21 06:50:16 【问题描述】:在我的 json 文件的步骤中,我想构建一个 linq,它根据您是点击后退按钮(上一个 id)还是下一个按钮(下一个 contentid)移动到下一个或上一个 id。如果发生这种情况,必须修改标签的文本。我不确定如何在 Linq 中实现这一点。
这是我的 JSON,我需要基于 contentid 步骤中的下一个或上一个文本
"protocols": [
"id": "1",
"name": "Pols meten",
"steps": [
"chapterTitle": "Voorzorg",
"contents": [
"contentid": "1",
"text": "voor blabla"
]
,
"contents": [
"contentid": "2",
"text": "voor blabla2"
]
,
"chapterTitle": "Handeling",
"contents": [
"contentid": "3",
"text": "handeling blabla"
]
,
"contens": [
"contentid": "4",
"text": "handeling blabla2"
]
,
"chapterTitle": "Nazorg",
"contents": [
"contentid": "5",
"text": "nazorg blabla"
]
,
"contents": [
"contentid": "6",
"text": "nazorg blabla2"
]
],
"versie": "1"
]
我的 json 类
public class RootObject
[JsonProperty("protocols")]
public List<Protocol> Protocols get; set;
public class Protocol
[JsonProperty("id")]
public string Id get; set;
[JsonProperty("name")]
public string Name get; set;
[JsonProperty("steps")]
public List<Step> Steps get; set;
[JsonProperty("versie")]
public string Versie get; set;
public class Step
[JsonProperty("chapterTitle")]
public string ChapterTitle get; set;
[JsonProperty("contents")]
public List<Content> Contents get; set;
public class Content
[JsonProperty("contentid")]
public string Contentid get; set;
[JsonProperty("text")]
public string Text get; set;
坐下是我的 2 个按钮,当我点击它时,我会转到下一个或上一个 id(如果它们存在)
readonly Step _step;
private Protocol protocol;
public StepView(Step step, string nextTitle)
_step = step;
InitializeComponent();
Title = nextTitle;
// krijg label text
lblText.Text = step.Contents.FirstOrDefault(x => x.Text != null).Text;
public void BtnNext_Clicked(object sender, EventArgs e)
if (_step == null)
lblText.Text = _step.Contents.FirstOrDefault(x => x.Text != null).Text;
else
var index = protocol.Steps.IndexOf(_step) + 1;
_step = protocol.Steps.Count >= index ? protocol.Steps.LastOrDefault() : protocol.Steps[index];
lblText.Text = _step?.Contents.FirstOrDefault(x => x.Text != null).Text;
public void BtnBack_Clicked(object sender, EventArgs e)
//voor als het de allerlaatste stap is en je geen stap meer terug kan
if (_step == null)
_step = protocol.Steps.LastOrDefault();
//als je nog wel een stap terug kunt
else
var index = protocol.Steps.IndexOf(_step) - 1;
_step = index >= 0 ? protocol.Steps[index] : protocol.Steps.FirstOrDefault();
lblText.Text = _step?.Contents.FirstOrDefault(x => x.Text != null).Text;
如果有的话,我怎样才能让按钮在上一个文本或下一个文本之后?
【问题讨论】:
BtnClicked = true; if (BtnClicked) .... 该代码的用途是什么?如果您想跟踪当前步骤,您至少需要从 _step 中删除 readonly 并在使用索引计算单击按钮时更改它。 你能举个例子吗? @AlexeyRumyantsev 这个布尔值没有意义,我不认为在这种情况下用户可以同时按下多个按钮来担心并发性。您应该担心正确的 null 和范围检查,而不是多线程。 【参考方案1】:引入字段private Content content;
处理程序:
public void BtnNext_Clicked(object sender, EventArgs e)
var index = content == null ? 0 : _step.Contents.IndexOf(content) + 1;
content = _step.Contents.ElementAtOrDefault(index);
lblText.Text = content?.Text;
public void BtnBack_Clicked(object sender, EventArgs e)
var index = content == null ? _step.Contents.Count - 1 : _step.Contents.IndexOf(content) - 1;
content = _step.Contents.ElementAtOrDefault(index);
lblText.Text = content?.Text;
【讨论】:
我得到 System.NullReferenceException:Object reference not set to an instance of an object.
var index = protocol.Steps.IndexOf(_step) - 1;
那要改什么?
协议为空
rootObject.Protocols.FirstOrDefault().Steps.ElementAtOrDefault(startingIndex -/+1) 会得到你想要的索引
你能给出一个带有@PowerMouse的代码示例【参考方案2】:
如您所愿。我做了一个例子。您传递所选项目的索引和方向以选择下一个项目,例如上一个或下一个 (您可以删除 where 条件 - 我将在此示例中查看包含标题的记录)
void Main()
string json = "\"protocols\":[\"id\":\"1\",\"name\":\"Pols meten\",\"steps\":[\"chapterTitle\":\"Voorzorg\",\"contents\":[\"contentid\":\"1\",\"text\":\"voor blabla\"],\"contents\":[\"contentid\":\"2\",\"text\":\"voor blabla2\"],\"chapterTitle\":\"Handeling\",\"contents\":[\"contentid\":\"3\",\"text\":\"handeling blabla\"],\"contens\":[\"contentid\":\"4\",\"text\":\"handeling blabla2\"],\"chapterTitle\":\"Nazorg\",\"contents\":[\"contentid\":\"5\",\"text\":\"nazorg blabla\"],\"contents\":[\"contentid\":\"6\",\"text\":\"nazorg blabla2\"]],\"versie\":\"1\"]";
rootObject = JsonConvert.DeserializeObject<RootObject>(json);
rootObject.Dump();
GetPrevNextItem(1,Direction.Up).Dump("Previous record");
GetPrevNextItem(1,Direction.Down).Dump("Next Record");
public Step GetPrevNextItem(int startingIndex, Direction dir)
if (dir == Direction.Up)
return rootObject.Protocols.FirstOrDefault().Steps
.Where(ss=> !string.IsNullOrEmpty(ss.ChapterTitle))
.ElementAtOrDefault(startingIndex -1);
else
return rootObject.Protocols.FirstOrDefault().Steps
.Where(ss=> !string.IsNullOrEmpty(ss.ChapterTitle))
.ElementAtOrDefault(startingIndex +1);
public enum Direction
Up,
Down
public RootObject rootObject get;set;
public class RootObject
[JsonProperty("protocols")]
public List<Protocol> Protocols get; set;
public class Protocol
[JsonProperty("id")]
public string Id get; set;
[JsonProperty("name")]
public string Name get; set;
[JsonProperty("steps")]
public List<Step> Steps get; set;
[JsonProperty("versie")]
public string Versie get; set;
public class Step
[JsonProperty("chapterTitle")]
public string ChapterTitle get; set;
[JsonProperty("contents")]
public List<Content> Contents get; set;
public class Content
[JsonProperty("contentid")]
public string Contentid get; set;
[JsonProperty("text")]
public string Text get; set;
【讨论】:
以上是关于如何在 C# 中使用 Linq to JSON 在单击按钮时检索下一个和上一个 id的主要内容,如果未能解决你的问题,请参考以下文章
在JS和.NET中使用JSON (以及使用Linq to JSON定制JSON数据)
在 c# 中使用 linq 按钮无法从 json 中正确计算章节 ID
如何在 c# 中添加特定条件项后对特定元素进行分组 linq to sql