C# 带有DataTable的IndexOutOfRangeException。选择

C# 带有DataTable的IndexOutOfRangeException。选择,c#,.net,winforms,combobox,datatable,C#,.net,Winforms,Combobox,Datatable,我有以下代码: private void comboBox2_TextChanged(object sender, EventArgs e) { var price = dt.Select("desc = '" + comboBox2.Text + "'", "price ASC"); textBox9.Text = price[0][2].ToString(); } dt是一个数据表,按如下方式保存库存项目:id、desc、price 当我从由dt填充的组合框中选择一个项目

我有以下代码:

private void comboBox2_TextChanged(object sender, EventArgs e)
{
    var price = dt.Select("desc = '" + comboBox2.Text + "'", "price ASC");

    textBox9.Text = price[0][2].ToString();
}
dt是一个数据表,按如下方式保存库存项目:id、desc、price

当我从由dt填充的组合框中选择一个项目时,它本身的代码运行良好,但如果我开始在组合框中键入内容,就会出现以下错误:索引超出了数组的边界

只有当组合框中包含一个项目时,我如何进行查找


多爱o

当程序的用户更改文本时,即使他尚未完成键入,也始终会触发事件。由于您正在与=进行比较,因此文本必须与desc完全匹配。因此,DataTable.Select不返回任何行,当您尝试访问数组的第一行时,这些行会导致异常

将过滤器更改为也匹配子字符串。您可以通过检查数组是否包含行来防止错误:

一,

二,

旁注,我发现LINQ To DataTable更具可读性:

var foundRows = from row in dt.AsEnumerable()
                let desc = row.Field<string>("desc")
                where desc.Contains(comboBox2.Text)
                select row;
DataRow firstMatch = foundRows.FirstOrDefault();
if(firstMatch != null)
{
    textBox9.Text = firstMatch.Field<string>(2);
}

该事件总是在程序的用户更改文本时触发,即使他尚未完成键入。由于您正在与=进行比较,因此文本必须与desc完全匹配。因此,DataTable.Select不返回任何行,当您尝试访问数组的第一行时,这些行会导致异常

将过滤器更改为也匹配子字符串。您可以通过检查数组是否包含行来防止错误:

一,

二,

旁注,我发现LINQ To DataTable更具可读性:

var foundRows = from row in dt.AsEnumerable()
                let desc = row.Field<string>("desc")
                where desc.Contains(comboBox2.Text)
                select row;
DataRow firstMatch = foundRows.FirstOrDefault();
if(firstMatch != null)
{
    textBox9.Text = firstMatch.Field<string>(2);
}

在您的情况下,var price不会返回任何内容,因为use编写的字符串不是数据表。这段代码应该有帮助

        if (price != null && price.Count() > 0)
        {
            textBox9.Text = price[0][2].ToString();
        }
另一种情况是创建combobox类型下拉列表,用户应仅从datatable设置输入

正如Tim Schmelter所说,用户写的每封信都会执行此文本更改事件。请注意这一点


注意写列名,不要对列名使用索引,这不是好的做法

在您的情况下,var price不会返回任何内容,因为use编写的字符串不是数据表。这段代码应该有帮助

        if (price != null && price.Count() > 0)
        {
            textBox9.Text = price[0][2].ToString();
        }
另一种情况是创建combobox类型下拉列表,用户应仅从datatable设置输入

正如Tim Schmelter所说,用户写的每封信都会执行此文本更改事件。请注意这一点


注意写列名,不要对列名使用索引,这不是好的做法

您可以尝试将代码放入try-catch块中,然后抛出的异常将被静默处理,当给出正确的输入时,将显示有效的答案,您可以使用如下代码:-

private void comboBox2_TextChanged(object sender, EventArgs e)
{
    try
    {
        var price = dt.Select("desc = '" + comboBox2.Text + "'", "price ASC");

        textBox9.Text = price[0][2].ToString();
    }
    catch(Exception xyz)
    {}
}

您可以尝试将代码放入try-catch块中,然后将以静默方式处理正在抛出的异常,当给出正确的输入时,将显示有效的答案,您可以使用如下代码:-

private void comboBox2_TextChanged(object sender, EventArgs e)
{
    try
    {
        var price = dt.Select("desc = '" + comboBox2.Text + "'", "price ASC");

        textBox9.Text = price[0][2].ToString();
    }
    catch(Exception xyz)
    {}
}

我不确定进行类似检查是否是个好主意,因为这将在每个字母更改时执行,并且最终文本框中的值将等于找到一行的最后一个字母。无论如何,我不知道任何方法,谢谢你给我+1@mybirthname:您可能是对的,即使这不是一个数据库查询,Like检查的效率也较低。OP也可以使用…comboBox2.Text+*。。。或desc.StartsWith,仅获取列以输入文本开头的行。然而,我只是想在用户输入之前为不匹配问题提供一个解决方案。OP无论如何都应该防止异常。我不确定进行类似检查是否是个好主意,因为这将在每个字母更改时执行,并且最终文本框中的值将等于找到一行的最后一个字母。无论如何,我不知道任何方法,谢谢你给我+1@mybirthname:您可能是对的,即使这不是一个数据库查询,Like检查的效率也较低。OP也可以使用…comboBox2.Text+*。。。或desc.StartsWith,仅获取列以输入文本开头的行。然而,我只是想在用户输入之前为不匹配问题提供一个解决方案。OP无论如何都应该防止异常。