Исключение комбинированного списка «Не удается найти столбец» в фильтре Bindingsource

1

Там может быть лучший способ добиться этого, я сейчас просто играю, пытаясь найти лучший способ выполнить определенную задачу.

У меня есть С# Winform с DataGridView и Детали в той же форме. Независимо, это отлично работает, и я могу просматривать записи и использовать инструменты в меню, которое отображается вверху. Я добавил combobox в named 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 + " ";

Идея вышеприведенной строки заключается в том, что при изменении combobox она обновляет значение datagrid/details, которое находится в форме. Когда я включаю код, я получаю это исключение:

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;
        }
    }
}

Новая ошибка с 21/07/2014

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: 
Теги:
winforms

4 ответа

1
Лучший ответ

См. Этот ответ:

Выбранное значение Combobox возвращает DataRowView

Это для VB, но это та же идея.

  • 0
    Это было это - спасибо. Единственное другое изменение, которое я сделал в коде, я изменил выбранный индекс на 1.
0

Попробуй это:

Измените свой код:


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

К этому:

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

Jmcilhinney прав, но причина, по которой это правильно, может быть более понятным, если код был отформатирован несколько иначе.

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

Ошибка, как сказал Jmcilhinney, заключается в том, что она вызывает ToString() в DataRowView в попытке получить значение фильтра строк. Я бы рекомендовал использовать string.format, как я сделал выше, для любого типа фильтра на основе строк, поскольку он делает то, что вы пытаетесь фильтровать, и как вы фильтруете его гораздо читабельнее.

Если это не сработает, какое новое сообщение об ошибке (как вы должны получить совершенно другую ошибку)? Какова ценность comboBox1.SelectedValue незадолго до того, как будет выбрано исключение?

  • 0
    Такое ощущение, что я становлюсь ближе, я поместил новую ошибку в исходное сообщение внизу.
0

Вы привязываете DataTable к ComboBox поэтому каждый элемент будет DataRowView. Эта строка:

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

пытается объединить DataRowView со строкой. Если вы хотите выбрать значение Site_ID, вы должны использовать SelectedValue, а не SelectedItem. Это весь смысл установки ValueMember.

Кстати, какая точка конкатенации строки, содержащей единственное пространство в конце этого? Здесь ничего нет. Не делай этого.

  • 0
    Это то, что у меня было изначально, я просто играл с этим. Конкатенация в конце состоит в том, что я обернул целое число в '', чтобы увидеть, имеет ли это значение, и я пропустил это - спасибо за это. Кстати, я все еще получаю ту же ошибку, даже с SelectedValue

Ещё вопросы

Сообщество Overcoder
Наверх
Меню