在 C# 中使用 Linq 单击按钮时,Json 不会转到下一个或上一个文本

Posted

技术标签:

【中文标题】在 C# 中使用 Linq 单击按钮时,Json 不会转到下一个或上一个文本【英文标题】:Json does not go to next or previous text when clicking on button with using Linq in C# 【发布时间】:2021-12-21 22:43:18 【问题描述】:

在我的 json 文件的步骤中,我想构建一个 linq,根据您是点击后退按钮(上一个 id)还是下一个按钮(下一个 contentid)来移动到下一个或上一个文本。如果发生这种情况,必须修改标签的文本。我不确定如何在 Linq 中实现这一点。

问题现在是当我第一次单击按钮时文本为空。然后他显示相同的文字!我做错了什么?

按钮的点击处理程序

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;

领域类

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 int Contentid  get; set; 

    [JsonProperty("text")]
    public string Text  get; set; 

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"
    
  ]

我想要的是根据您单击的位置显示下一个或上一个内容 ID 中的文本。

【问题讨论】:

如果将当前显示的内容索引 (currentId) 存储在类级别字段中会怎样?那么上一个按钮代码将是:var index = --currentId &gt; 0 ? currentId : 0; lblText.Text = _step.Contents[index]?.Text;。下一个按钮代码:var index = ++currentId &lt; _step.Contents.Count ? currentId : _step.Contents.Count - 1; lblText.Text = _step.Contents[index]?.Text; 请不要通过破坏您的帖子为他人增加工作量。通过在 Stack Exchange 网络上发帖,您已在 CC BY-SA 4.0 license 下授予 Stack Exchange 分发该内容的不可撤销的权利(即无论您未来的选择如何)。根据 Stack Exchange 政策,帖子的非破坏版本是分发的版本。因此,任何破坏行为都将被撤销。如果您想了解更多关于删除帖子的信息,请参阅:How does deleting work? 【参考方案1】:

每一步都有一个内容:

...
"steps": [
  
    "chapterTitle": "Voorzorg",
    "contents": [
      
        "contentid": "1",
        "text": "voor blabla"
      
    ]
  ,
  ...

首先点击下一个不显示任何内容的按钮:

// Initialized on the first step's content (I think)
private Content content;
public void BtnNext_Clicked(object sender, EventArgs e)

    int index;
    if(content == null)
    
        index = 0;
    
    else // Go here, because content is the first step's content (that is not null)
    
        index = _step.Contents.IndexOf(content)
        // index <= 0
        index = index + 1;
        // index <= 1
    
    content = _step.Contents.ElementAtOrDefault(index);
    // content <= _step.Contents.ElementAtOrDefault(1);
    // content <= the second step's content
    // But the step has ONE content, then ElementAtOrDefault return null
    // content <= null
    lblText.Text = content?.Text;
    // Display nothing

第二次点击下一个按钮:

// After the first click, content is null
private Content content;
public void BtnNext_Clicked(object sender, EventArgs e)

    int index;
    if(content == null) // Go here, because content is null
    
        index = 0;
    
    else 
    
        index = _step.Contents.IndexOf(content) + 1;
    
    content = _step.Contents.ElementAtOrDefault(index);
    // content <= _step.Contents.ElementAtOrDefault(0);
    // content <= the first step's content
    lblText.Text = content?.Text;
    // Redisplay the first step's content

您可以保留索引(而不是内容)并检查它是否在范围内(而不是内容不为空):

private int index;
public void BtnNext_Clicked(object sender, EventArgs e)

    index++;
    // If the index go after the last element
    if(index >= _step.Contents.Count)
        // Then reset
        index = 0;
    var content = _step.Contents.ElementAtOrDefault(index);
    lblText.Text = content?.Text;




public void BtnBack_Clicked(object sender, EventArgs e)

    index--;
    // If the index go before the first element
    if(index < 0)
        // Then go to the last
        index = _step.Contents.Count - 1;
    var content = _step.Contents.ElementAtOrDefault(index);
    lblText.Text = content?.Text;

并在步骤中添加更多内容(否则此循环对唯一步骤的内容):

"steps": [
  
    "chapterTitle": "Voorzorg",
    "contents": [
      
        "contentid": "1",
        "text": "voor blabla"
      ,
      
        "contentid": "2",
        "text": "vuur blabla"
      ,
      
        "contentid": "3",
        "text": "soor blybli"
      
    ]
  ,

【讨论】:

当显示一章的最后内容时,可能next按钮需要显示下一章的第一个内容(而不是在当前章循环)。 在下一个代码中(有效):lblText.Text = content?.Text;。在 prec 代码(即中断)中:lblText.Text = content.Text;。你看到差异了吗? 在我之前的评论中,差异是“?”。 [空条件运算符(docs.microsoft.com/en-us/dotnet/csharp/language-reference/…)避免调用空引用。 问题代码中,BtnNext_Clicked 管理index 字段中的当前元素,BtnBack_Clicked 管理content 字段中的当前元素。您需要将 BtnBack_Clicked 方法重写为使用字段index 您正在接近解决方案。尝试在字段index 的值为0 时执行BtnBack_Clicked 的图像。在index-- 之后,字段索引的值为-1。现在看看 if 检查的内容。它会检查index 是否高于间隔,但在这种情况下index 低于间隔。不一致?

以上是关于在 C# 中使用 Linq 单击按钮时,Json 不会转到下一个或上一个文本的主要内容,如果未能解决你的问题,请参考以下文章

在 c# 中使用 linq 按钮无法从 json 中正确计算章节 ID

如何通过按钮单击将数据导出到 linq c# 中的 .csv 文件

Linq通配符搜索mvc c#

在 C# 中临时更改按钮单击时的按钮颜色

单击另一个表单中的按钮提交时如何在c#中重新加载表单?

使用啥代替 FirstOrDefault 来获取与 C# 中使用 linq 中所选章节关联的 json 文本?