索引超出范围异常 visual studio

3
在我的winform中,我试图通过传递物品的名称从数据库中获取该物品的价格。用户可以在下拉框中看到从数据库中读取的物品。当用户选择一个物品并点击“添加”时,它会将该特定物品添加到数据库中。
同时,当用户添加物品时,其中一个文本框会添加价格。如果用户添加了五个物品,则文本框会显示五个物品价格的总和。到这里为止一切正常。
现在,当用户想要从列表框中删除物品时,用户选择该物品并单击“删除物品”,Visual Studio会抛出“索引超出范围”的错误。
我在添加方法和减法方法中使用相同的代码来获取价格,但不确定为什么只有添加方法有效而减法无效。 添加价格的代码:
public int addPrice()
        {

            DataSet ds = searchforPrice(comboBox2.Text);
            int sum;
            bool success = int.TryParse(maskedTextBox10.Text, out sum);
            int price = Convert.ToInt32(ds.Tables[0].Rows[0]["Price"]);
            return sum + price;

        }

减去价格的代码

 public int subPrice()
        {

            DataSet ds = searchforPrice(listBox1.GetItemText(listBox1.SelectedItem));
            int sum;
            bool success = int.TryParse(maskedTextBox10.Text, out sum);
            int price = Convert.ToInt32(ds.Tables[0].Rows[0]["Price"]);
            return sum - price;

        }

从数据库获取价格的代码

public DataSet searchforPrice(string itemName)
{
    DataSet dataSet = new DataSet();

    // Create connection object
    OleDbConnection oleConn = new OleDbConnection(connString);
    try
    {
        oleConn.Open();
        string sql = "SELECT [Price]  FROM [Product] WHERE [Product Name] ='" + itemName + "'";
        OleDbDataAdapter dataAdapter = new OleDbDataAdapter(sql, oleConn);
        dataAdapter.Fill(dataSet, "Product");

    }
    catch (Exception ex)
    {
        Console.WriteLine(ex.ToString());
    }
    finally
    {
        oleConn.Close();
    }
    return dataSet;
}

enter image description here


3
在这种情况下,它意味着您的表为空。请自己考虑一下参数化查询,并使其更易于理解。 - Anthony Pegram
在代码中设置断点,查看异常出现的位置。如果出现索引超出范围的情况,通常意味着您正在访问一个长度小于该数字的数组。 - TYY
listBox1.GetItemText(listBox1.SelectedItem) 返回 null,不确定原因。 - Amrit Sharma
我认为你的问题出在listBox.GetItemText(listbox.SelectedItem)上。为什么不改用ListBox1.SelectedValue.ToString()呢? - TYY
5个回答

1

要么没有表格,要么结果集中没有行。这意味着访问第一个条目(索引0)不起作用,因为没有第一个条目。你会收到一个IndexOutOfRangeException。检查你的请求和数据源。


但是它对于“add”方法完美地运作,为什么对于“subtract”方法却不行,因为我从两种方法中都传递了项目名称作为字符串。 - Amrit Sharma

1
这是失败的原因,因为searchForPrice在表格中没有返回任何行。因此发生了错误。

在位置0处没有行。

因此,如果您更改该行以从列表框或表单的其他地方获取值,该值将返回数据,您的错误将得到修复。
真正的潜在问题是传递给searchForPrice的值。

0
方法searchforPrice返回了一个没有行的数据集。因此,Rows[0]不存在。请检查您的方法,并使其适应searchforPrice未返回任何数据(未找到任何价格)的情况。
if (ds.Tables[0].Rows.Count != 0

{ ...}


0
问题是因为您的数据集返回了0行。这是因为项目名称没有传递到SQL查询中。 您只需要在subPrice()函数中进行微小的更改即可。
public int subPrice()
        {

            DataSet ds = searchforPrice(listBox1.SelectedItem.ToString());
            int sum;
            bool success = int.TryParse(maskedTextBox10.Text, out sum);
            int price = Convert.ToInt32(ds.Tables[0].Rows[0]["Price"]);
            return sum - price;

        }

Visual Studio无法识别ListBoxItem。 - Amrit Sharma
http://stackoverflow.com/questions/7887829/listbox-selected-item-content-to-textblock - Ankit
直接使用listBox1.SelectedValue.ToString即可。如果所选项是复杂对象,则可以使用((CAST)ListBox.SelectedItem).THE_PROPERTY_YOU_NEED。 - TYY
1
@Amrit 如果我是你,我会在快速监视窗口中设置断点并查看listbox.selectedItem和selectedvalue的值。我们给你的场景应该是可行的,如果它们不起作用,那么前进的唯一方法就是查看这些属性所得到的内容。 - TYY

0

提供的代码应该可以工作。

您需要检查实际数据源中的列是否与通过 ListBox 项传递的列相匹配。我认为您很可能在命名约定上存在差异。

如果 ListBox 传递的列名与数据源中的列名匹配,则以下代码应该可以工作:

public int subPrice()
        {
            if (listBox1.SelectedItems.Count > 0)
            {
                string SearchString = listBox1.SelectedItem.ToString().Trim();
                DataSet ds = searchforPrice(SearchString);

                if (ds.Tables["Product"].Rows.Count > 0)
                {
                    bool success = int.TryParse(maskedTextBox10.Text, out sum);
                    int price = Convert.ToInt32(ds.Tables["Product"].Rows[0]["Price"]);
                    return sum - price;
                }                
            }

          return null;
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接