【问题标题】:Combobox exception "Cannot find column" in Bindingsource FilterBindingsource 筛选器中的组合框异常“找不到列”
【发布时间】:2014-07-17 00:18:16
【问题描述】:

可能有更好的方法来实现这一点,我现在只是在玩,试图找到执行某项任务的最佳方法。

我有一个 C# Winform,在同一个表单上带有 DataGridView 和 Details。独立地,这很好用,我可以浏览条目并使用顶部出现的菜单中的工具。我在名为 combobox1 的组合框中添加了一个组合框,我想用如下所示的 SQL 表中的值填充它(为简化起见,我删除了 Site_Address、Site_PhoneNumber 等附加字段):

Site_ID Client_ID   Site_Display_Name
1          3        Microsoft
2          2        Google
3          1        Amazon

我需要显示成员是 Site_Display_Name,但实际值是 Site_ID。独立运行时,如果我注释掉这一行,则会填充 Combobox1

sitesBindingSource.Filter = "Site_ID = " + comboBox1.SelectedItem + " ";

上一行的想法是,当组合框更改时,它会刷新表单上的数据网格/详细信息的值。当我包含代码时,我得到了这个异常:

System.Data.EvaluateException was unhandled by user code
  HResult=-2146232032
  Message=Cannot find column [System.Data.DataRowView].
  Source=System.Data
  StackTrace:
       at System.Data.NameNode.Bind(DataTable table, List`1 list)
       at System.Data.BinaryNode.Bind(DataTable table, List`1 list)
       at System.Data.DataExpression.Bind(DataTable table)
       at System.Data.DataExpression..ctor(DataTable table, String expression, Type type)
       at System.Data.DataView.set_RowFilter(String value)
       at System.Data.DataView.System.ComponentModel.IBindingListView.set_Filter(String value)
       at System.Windows.Forms.BindingSource.set_InnerListFilter(String value)
       at System.Windows.Forms.BindingSource.set_Filter(String value)
       at ImpactMessAround2.Form1.comboBox1_SelectedIndexChanged(Object sender, EventArgs e) in c:\Users\Gavin\Documents\Visual Studio 2013\Projects\ImpactMessAround2\ImpactMessAround2\Form1.cs:line 46
       at System.Windows.Forms.ComboBox.OnSelectedIndexChanged(EventArgs e)
       at System.Windows.Forms.ComboBox.set_SelectedIndex(Int32 value)
       at System.Windows.Forms.ComboBox.RefreshItems()
       at System.Windows.Forms.ComboBox.OnDataSourceChanged(EventArgs e)
       at System.Windows.Forms.ListControl.SetDataConnection(Object newDataSource, BindingMemberInfo newDisplayMember, Boolean force)
       at System.Windows.Forms.ListControl.set_DataSource(Object value)
  InnerException: 

代码如下:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void sitesBindingNavigatorSaveItem_Click(object sender, EventArgs e)
        {
            this.Validate();
            this.sitesBindingSource.EndEdit();
            this.tableAdapterManager.UpdateAll(this.gavin_TestDataSet);

        }

        private void Form1_Load(object sender, EventArgs e)
        {
            // TODO: This line of code loads data into the 'gavin_TestDataSet.Sites' table. You can move, or remove it, as needed.
            this.sitesTableAdapter.Fill(this.gavin_TestDataSet.Sites);
            SqlConnection mycon = new SqlConnection("Data Source=REDACTED;Initial Catalog=Gavin_Test;Persist Security Info=True;User ID=sa;Password=REDACTED");
            SqlDataAdapter da = new SqlDataAdapter("select Site_ID, Site_Display_Name from Sites", mycon);
            DataSet ds = new DataSet();
            da.Fill(ds); mycon.Close();
            comboBox1.DataSource = ds.Tables[0];
            comboBox1.DisplayMember = "Site_Display_Name";
            comboBox1.ValueMember = "Site_ID";
            comboBox1.SelectedIndex = -1;

        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            sitesBindingSource.Filter = "Site_ID = " + comboBox1.SelectedValue;
        }
    }
}

截至 2014 年 7 月 21 日的新错误

System.Data.EvaluateException was unhandled by user code
  HResult=-2146232032
  Message=Cannot perform '=' operation on System.Int32 and System.String.
  Source=System.Data
  StackTrace:
       at System.Data.BinaryNode.BinaryCompare(Object vLeft, Object vRight, StorageType resultType, Int32 op, CompareInfo comparer)
       at System.Data.BinaryNode.EvalBinaryOp(Int32 op, ExpressionNode left, ExpressionNode right, DataRow row, DataRowVersion version, Int32[] recordNos)
       at System.Data.BinaryNode.Eval(DataRow row, DataRowVersion version)
       at System.Data.DataExpression.Invoke(DataRow row, DataRowVersion version)
       at System.Data.Index.AcceptRecord(Int32 record, IFilter filter)
       at System.Data.Index.InitRecords(IFilter filter)
       at System.Data.Index..ctor(DataTable table, IndexField[] indexFields, Comparison`1 comparison, DataViewRowState recordStates, IFilter rowFilter)
       at System.Data.DataTable.GetIndex(IndexField[] indexDesc, DataViewRowState recordStates, IFilter rowFilter)
       at System.Data.DataView.UpdateIndex(Boolean force, Boolean fireEvent)
       at System.Data.DataView.UpdateIndex(Boolean force)
       at System.Data.DataView.SetIndex2(String newSort, DataViewRowState newRowStates, IFilter newRowFilter, Boolean fireEvent)
       at System.Data.DataView.SetIndex(String newSort, DataViewRowState newRowStates, IFilter newRowFilter)
       at System.Data.DataView.set_RowFilter(String value)
       at System.Data.DataView.System.ComponentModel.IBindingListView.set_Filter(String value)
       at System.Windows.Forms.BindingSource.set_InnerListFilter(String value)
       at System.Windows.Forms.BindingSource.set_Filter(String value)
       at ImpactMessAround2.Form1.comboBox1_SelectedIndexChanged(Object sender, EventArgs e) in c:\Users\Gavin\Documents\Visual Studio 2013\Projects\ImpactMessAround2\ImpactMessAround2\Form1.cs:line 46
       at System.Windows.Forms.ComboBox.OnSelectedIndexChanged(EventArgs e)
       at System.Windows.Forms.ComboBox.set_SelectedIndex(Int32 value)
       at System.Windows.Forms.ComboBox.RefreshItems()
       at System.Windows.Forms.ComboBox.OnDataSourceChanged(EventArgs e)
       at System.Windows.Forms.ListControl.SetDataConnection(Object newDataSource, BindingMemberInfo newDisplayMember, Boolean force)
       at System.Windows.Forms.ListControl.set_DataSource(Object value)
  InnerException: 

【问题讨论】:

    标签: c# winforms


    【解决方案1】:

    看到这个答案:

    Combobox selected value return DataRowView

    它适用于 VB,但它是相同的想法。

    【讨论】:

    • 就是这样 - 谢谢。我对代码所做的唯一其他更改是将 selectedindex 更改为 1。
    【解决方案2】:

    您将DataTable 绑定到ComboBox,因此每个项目都将是DataRowView。这一行:

    sitesBindingSource.Filter = "Site_ID = " + comboBox1.SelectedItem + " ";
    

    正在尝试将DataRowView 与字符串连接。如果您想要选定的 Site_ID 值,那么您应该使用SelectedValue,而不是SelectedItem。这就是设置ValueMember 的重点。

    顺便说一句,连接一个在其末尾包含一个空格的字符串有什么意义?空无一人。不要这样做。

    【讨论】:

    • 这就是我原来在里面的东西,我只是在玩它。最后的连接是因为我将整数包装在 ' ' 中以查看它是否有所作为,而我错过了它 - 谢谢。顺便说一句,即使使用 SelectedValue,我仍然会遇到同样的错误
    【解决方案3】:

    Jmcilhinney 是正确的,但如果代码格式稍有不同,其正确的原因可能会更清楚。

    sitesBindingSource.Filter = string.format("Site_ID = '{0}'", comboBox1.SelectedValue);
    

    正如 Jmcilhinney 所说,错误是因为它在 DataRowView 上调用 ToString() 以尝试获取字符串过滤器值。我建议使用 string.format,就像我在上面对任何类型的基于字符串的过滤器所做的那样,因为它使您尝试过滤的内容以及您过滤它的方式更具可读性。

    如果这不起作用,新的错误消息是什么(因为您应该得到一个完全不同的错误)?在抛出异常之前,comboBox1.SelectedValue 的值是多少?

    【讨论】:

    • 这感觉离我越来越近了,我已经把新的错误放到了底部的原帖中了。
    【解决方案4】:

    试试这个:

    从此更改您的代码:

    comboBox1.DataSource = ds.Tables[0]; comboBox1.DisplayMember = "Site_Display_Name"; comboBox1.ValueMember = "Site_ID"; 组合框1.SelectedIndex = -1;

    到这个:

    comboBox1.DisplayMember = "Site_Display_Name";
    comboBox1.ValueMember = "Site_ID";
    comboBox1.DataSource = ds.Tables[0];
    comboBox1.SelectedIndex = -1;
    

    【讨论】:

      猜你喜欢
      • 2023-03-21
      • 2010-09-28
      • 2014-07-13
      • 2022-11-17
      • 1970-01-01
      • 2021-09-29
      • 1970-01-01
      • 1970-01-01
      • 2020-06-02
      相关资源
      最近更新 更多