【问题标题】:Can't insert string into listview or textbox?无法将字符串插入列表视图或文本框?
【发布时间】:2015-05-07 12:36:05
【问题描述】:

我正在制作一个 winform 应用程序,我可以在其中输入一个名为 Tibia 的游戏的玩家姓名。当我输入球员姓名时,它会转到网站 (www.tibia.com) 并搜索球员,并获取有关球员的一些数据。在这种情况下:返回姓名、职业和级别。为此,我使用 HtmlAgilityPack 从网站上为我抓取数据。

我为此设置了三个字符串变量:charname、voc 和 lvl。

当我将数据放入变量时,我可以制作消息框来打印它们。喜欢:

MessageBox.Show("Your name is: " + charname);

而且效果很好。

但我似乎无法将它们添加到我的 listView(称为:characterList)或文本框(textBox1)。应用程序崩溃并给我这个错误:

在 mscorlib.dll 中发生了“System.AggregateException”类型的未处理异常

而且我似乎无法修复它。我已经尽力了。

这是我的代码:

//Goes to the website and grabs the data from the table
    static async Task<List<List<string>>> GetPlayers()
    {
        playername.Replace(" ", "+");
        string url = "https://secure.tibia.com/community/?subtopic=characters&name=" + playername;
        using (var client = new HttpClient())
        {
            var html = await client.GetStringAsync(url);
            var doc = new HtmlAgilityPack.HtmlDocument();

            doc.LoadHtml(html);

            var table = doc.DocumentNode.SelectSingleNode("//table[@cellpadding='4']");
            return table.Descendants("tr")
                        .Skip(1)
                        .Select(tr => tr.Descendants("td")
                        .Select(td => WebUtility.HtmlDecode(td.InnerText))
                        .ToList())
                        .ToList();
        }
    }

这是我的代码,用于遍历它找到的数据,并将其添加到 ListView (characterList) 中:

private void addCharacter_Click(object sender, EventArgs e)
    {
        playername = Interaction.InputBox("Please enter a character name.", "Input Character Name");
        if (playername.Length > 0)
        {
            //get the player data from the website
            //name, vocation and level
            //add their values to the 3 variables: charname, voc and lvl.
            //and add them to the listview (characterList)
            Task.Run(async () =>
            {
                var players = await GetPlayers();

                foreach (var row in players)
                {
                    if (row[0] == "Name:")
                    {
                        charname = row[1];
                    }
                }

                foreach (var row in players)
                {
                    if (row[0] == "Vocation:")
                    {
                        if (row[1] == "Druid" || row[1] == "Elder Druid")
                        {
                            voc = "ED";
                        }
                        else if (row[1] == "Knight" || row[1] == "Elite Knight")
                        {
                            voc = "EK";
                        }
                        else if (row[1] == "Paladin" || row[1] == "Royal Paladin")
                        {
                            voc = "RP";
                        }
                        else if (row[1] == "Sorcerer" || row[1] == "Master Sorcerer")
                        {
                            voc = "MS";
                        }
                        else if (row[1] == "None")
                        {
                            voc = "None";
                        }
                    }
                }

                foreach (var row in players)
                {
                    if (row[0] == "Level:")
                    {
                        lvl = row[1];
                    }
                }


                if (charname.Length > 0 && lvl.Length > 0 && voc.Length > 0)
                {
                    string[] row1 = { voc, lvl };
                    characterList.Items.Add(charname).SubItems.AddRange(row1);
                }

            }).Wait();
        }
        else if (playername.Length < 1)
        {
            MessageBox.Show("Invalid character name.", "Error");
        }
    }

这里还展示了该网站以及它如何从表格中获取数据。

所以问题不在于获取数据。它正确地得到它,因为我可以添加消息框来打印出来。但是当我尝试将它们添加到我的列表视图或任何文本框中时,它就不起作用了。就像我无法使用数据一样。只需在消息框中打印出来。我不知道为什么。

我还尝试使用按钮将一些自定义数据自己添加到 listView 中,这很有效。所以我添加数据的方式应该不是问题。只是我不想直接插入文本,而是要插入变量。

看看这个例子,我用一个按钮手动添加数据:

【问题讨论】:

  • 您是否发布了将数据添加到列表视图或文本框的代码?没看到
  • 是的,它位于第二个代码块的底部。在characterList.Items.Add 我删除了添加文本到文本框代码,因为那只是为了测试。我只想将字符串添加到列表视图中。

标签: c# winforms listview html-agility-pack


【解决方案1】:

我怀疑这条线:

characterList.Items.Add(charname).SubItems.AddRange(row1);

...正在工作线程上执行;失败,因为不允许非 STA 工作线程更新 UI;因此抛出一个AggregateException,因为它在Task中。

我很确定您不需要 Task.Run() 在您的 addCharacter_Click() 中,尤其是当您执行 .Wait() 时。

改成:

private async void addCharacter_Click(object sender, EventArgs e)
{
    playername = Interaction.InputBox("Please enter a character name.", "Input Character Name");
    if (playername.Length > 0)
    {
        //get the player data from the website
        //name, vocation and level
        //add their values to the 3 variables: charname, voc and lvl.
        //and add them to the listview (characterList)

            var players = await GetPlayers();

            foreach (var row in players)
            {
                if (row[0] == "Name:")
                {
                    charname = row[1];
                }
            }
.
. 
.

注意上面的方法现在如何被标记为async

【讨论】:

  • 当我删除 Task.Run() 它给了我其他错误,说我需要 task.run() 因为它是异步的。检查此图像:i.imgur.com/aPCoz8i.png
  • 请注意,我将方法签名更改为包括上面的async。即private async void addCharacter_Click(object sender, EventArgs e)。您需要包含async。抱歉,我应该更直截了当
  • @aliazik 哈哈。很高兴是我的好先生。祝你好运:)
猜你喜欢
  • 1970-01-01
  • 2010-10-19
  • 1970-01-01
  • 2020-03-13
  • 1970-01-01
  • 2015-09-06
  • 1970-01-01
  • 1970-01-01
  • 2011-07-28
相关资源
最近更新 更多