Свързване на ComboBox към DataTable (WinForms c#)?

Имам метод, който попълва моя ComboBox от DataTable:

public string populateCompanyTransSellingEntityLookUp(ref System.Windows.Forms.ComboBox Combo, string Id, Contract Contract)
    {
        SqlCommand _comm = new SqlCommand();
        _comm.Parameters.AddWithValue("@id", Id);
        _comm.CommandText = "SELECT [name] FROM dbo.fnGetList(@id) ORDER BY [name]; ";   
        _comm.Connection = _conn;
        _comm.CommandTimeout = _command_timeout;

        DataTable dt = new DataTable();
        try
        {
            SqlDataReader myReader = _comm.ExecuteReader();
            dt.Load(myReader);

            Combo.DataSource = dt;
            Combo.DisplayMember = "name";

            foreach (DataRow dr in dt.Rows)
            {
                if (dr["name"].ToString() == Contract.Company_Name.ToString())
                {                        
                    Combo.Text = dr["company_int_name"].ToString();
                }
            }
        }
        catch
        {
            MessageBox.Show("Unable to populate Company Name LookUp");
        }


        return "";
    }

Предавам запазената си стойност Contract.Company_Name в цикъла forEach, за да намеря необходимия си SelectedItem от DataTable. ComboBox се попълва с моите стойности на DataTable от Combo.Datasource =dt;, но избраният от мен елемент не е зададен. Кодът се компилира без изключение. Ако премахна Datasource = dt;, theSelectedItemis set no problem. Why is theDatasourceoverriding mySelectedItem` и има ли нещо, което съм пропуснал с моето обвързване?

Благодаря на всички


person Hardgraf    schedule 14.03.2014    source източник
comment
задайте ValueMember така: Combo.ValueMember = име;   -  person Karol Marian Słuszniak    schedule 14.03.2014
comment
Все още не е поправено за съжаление...   -  person Hardgraf    schedule 14.03.2014


Отговори (3)


Първо трябва да зададете valueMember със сигурност. След това можете да зададете свойството selectedValue вместо SelectedItem. Елементът е един запис на източник на данни. Така че във вашия случай ще бъде SelectedItem = dr! Но не съм сигурен, че това работи.

person Sebi    schedule 14.03.2014

Опитайте тази:

Combo.SelectedItem = dr;
person chamamo    schedule 14.03.2014
comment
Фиксирана. Извадете SelectedItem всички заедно и задайте Combo.Text = dr[company_int_name].ToString(); в рамките на forEach. Не сте сигурни защо SelectedItem няма да се обвърже? Въпросният редактиран код :) - person Hardgraf; 14.03.2014
comment
Според мен това е грозен начин да изпълниш задачата си. По-добре трябва да използвате SelectedValue Property. И трябва да помислите за IList‹myObject› вместо DataTable. По-лесно е да се работи в сложни случаи. Например можете да използвате ламбда изрази. - person Sebi; 14.03.2014

Бих предложил да използвате SelectedValue, тогава не е необходимо да преминавате през стойности ръчно.

Също така не е необходимо да използвате тежък DataTable, където имате нужда само от колекция от низови стойности.

private IEnumerable<string> LoadNames(string id)
{
    var query = "SELECT [name] FROM dbo.fnGetList(@id) ORDER BY [name]";

    using (var connection = new SqlConnection("connectionString")
    using (var command = new SqlCommand(query, connection)
    {
        // 36 is the size of the VarChar column in database(use your value)
        command.Parameters.Add("@id", SqlDbType.VarChar, 36).Value = id;

        connection.Open();
        using (var reader = command.ExecuteReader())
        {
            var names = new List<string>();
            while(reader.Read())
            {
                names.Add(reader.GetString(0));
            }

            return names;
        }
    }
}


public void Populate(ComboBox combobox, string id, Contract contract)
{
    combobox.DataSource = LoadNames(id);
    combobox.SelectedValue = contract.Copmpany_Name.ToString();
}

Няколко неща, които трябва да забележите:

  1. Изхвърлете всички обекти, които работят с външни ресурси (SqlConnection, SqlCommand и SqlDataReader)
  2. Създайте SqlParameter с точна информация за типа, за низовете е важно да предоставите размера на колоната в базата данни. Тази информация ще подобри производителността на SQL заявките от страна на сървъра.
  3. Не предавайте комбобокса като препратка, методът populate не създава нов екземпляр, а само използва дадения екземпляр ComboBox.
person Fabio    schedule 22.01.2021