组合框异常“无法找到列”;在Bindingsource Filter中

本文关键字:无法找到列 Bindingsource Filter 异常 组合 | 更新日期: 2023-09-27 18:13:13

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

我有一个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

我需要displaymember是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: 

组合框异常“无法找到列”;在Bindingsource Filter中

看答案:

组合框所选值返回DataRowView

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

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

正在尝试将DataRowView与字符串连接起来。如果您想要选择Site_ID值,那么您应该使用SelectedValue,而不是SelectedItem。这就是设置ValueMember的全部意义。

顺便说一下,连接一个末尾包含一个空格的字符串有什么意义?没有。别这么做。

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

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

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

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

试试这个:

修改你的代码:

<>之前comboBox1。DataSource = ds.Tables[0];comboBox1。DisplayMember = "Site_Display_Name";comboBox1。ValueMember = "Site_ID";comboBox1。selecteindex = -1;之前

到这个:

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