Поле со списком C# SelectedValue Null

Не публикуя весь мой код (я просто публикую оскорбительный скрипт), у меня возникла проблема, которая, кажется, была у многих людей, но мой, похоже, не реагирует на другие рекомендуемые исправления. Я использую С# в VS2008.

В основном у меня есть comboBox, и когда элемент инициализации изменяется, он переходит к коду ниже. По сути, код определяет, какая страна была выбрана (myCountryKey), а затем передает ее как параметр хранимой процедуре, которая заполняет последующее поле со списком.

Странно то, что свойство selectedValue объекта cboCountries всегда отображается как Null. Когда я читал об этой проблеме, казалось, что проблема заключается в свойстве dropdownStyle, но я изменил свой на DropDownList, как рекомендовалось, и это не сработало.

Поскольку я часто использую выпадающие списки, я начал экспериментировать и обнаружил, что могу заставить работать свойство SelectedIndex, а также свойство GetItemText (для этого и нужны переменные myCountryKey2 и myCountryKey3). Однако то, что я действительно хотел бы, - это SelectedValue, и я делал такие вещи раньше и просто не могу понять, почему это не работает.

Есть ли какое-либо другое свойство поля со списком, которое я мог случайно изменить, что может привести к тому, что SelectedValue не работает?

private void cboCountries_SelectedIndexChanged(object sender, EventArgs e)
        {
            SqlCommand cmd = null;
            SqlDataReader dr = null;

            try
            {
                cmd = util.SqlConn.CreateCommand();
                cmd.CommandType = CommandType.StoredProcedure;

                myCountryKey = int.Parse(this.cboCountries.SelectedValue.ToString());  //does not work, says value is null
                myCountryKey2 = int.Parse(this.cboCountries.SelectedIndex.ToString());  //Works fine
                string myCountryKey3 = this.cboCountries.GetItemText(this.cboCountries.SelectedItem).ToString(); //Works fine

                cboDivisions.Enabled = true;
                cboDivisions.Items.Clear();

                // Division parameter
                cmd.CommandText = "proc_parms_division";
                dr = cmd.ExecuteReader();
                while (dr.Read())
                    this.cboDivisions.Items.Add(new ListItem(dr["division_name"].ToString(), dr["division_key"].ToString()));

                dr.Close();
                cmd.Parameters.Clear();
            }
            catch (Exception ex)
            {
                util.LogError(ex);
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (dr != null) dr.Dispose();
                if (cmd != null) cmd.Dispose();
            }
        }

Больше кода:

       public frmWriteoff()
        {
            InitializeComponent();
            //this.KeyPreview = true;
            //this.KeyUp += new KeyEventHandler(frmWriteoff_KeyUp);

            // Data objects are unmanaged code.  
            // Declare them above the try{} block and always dispose of them in finally{}.
            SqlCommand cmd = null;
            SqlDataReader dr = null;

            try
            {
                this.cboCountries.DisplayMember = "Label";
                this.cboCountries.ValueMember = "Value";
                this.cboDivisions.DisplayMember = "Label";
                this.cboDivisions.ValueMember = "Value";
                this.cboBusinessUnits.DisplayMember = "Label";
                this.cboBusinessUnits.ValueMember = "Value";
                this.cboMCCs.DisplayMember = "Label";
                this.cboMCCs.ValueMember = "Value";
                this.cboNodes.DisplayMember = "Label";
                this.cboNodes.ValueMember = "Value";
                this.cboProductCodes.DisplayMember = "Label";
                this.cboProductCodes.ValueMember = "Value";


                // Country parameters
                cmd = util.SqlConn.CreateCommand();
                cmd.CommandType = CommandType.StoredProcedure;
                cmd.CommandText = "proc_parms_countries_for_user";
                cmd.Parameters.Add("@whoAmI", SqlDbType.VarChar).Value = WindowsIdentity.GetCurrent().Name;
                dr = cmd.ExecuteReader();
                while (dr.Read())
                    if (dr["country key"].ToString() != "0" && dr["country key"].ToString() != "1")
                    {
                        this.cboCountries.Items.Add(new ListItem(dr["country name"].ToString(), dr["country key"].ToString()));
                    }
                cmd.Parameters.Clear();
                dr.Close();

}
            catch (Exception ex)
            {
                util.LogError(ex);
                MessageBox.Show(ex.Message);
            }
            finally
            {
                if (dr != null) dr.Dispose();
                if (cmd != null) cmd.Dispose();
            }
        }

person Ryan Ward    schedule 25.06.2013    source источник
comment
Вы на самом деле установили привязку к свойству Value неправильного поля со списком или указали значение при добавлении в него нового элемента списка?   -  person James Culshaw    schedule 25.06.2013
comment
Джеймс, я обновил свой код выше, чтобы вы могли видеть мою настройку ValueMember, о которой, я думаю, вы просили. Также включает код для начальной загрузки поля со списком cboCountries. Спасибо.   -  person Ryan Ward    schedule 25.06.2013


Ответы (3)


Я разобрался, снова бьют несвязанные данные. Когда я изменил свой код, чтобы загрузить список стран в таблицу данных, а затем использовать эту таблицу данных в качестве источника моего поля со списком, все было хорошо с миром.

    public frmWriteoff()
    {
        InitializeComponent();
        //this.KeyPreview = true;
        //this.KeyUp += new KeyEventHandler(frmWriteoff_KeyUp);

        // Data objects are unmanaged code.  
        // Declare them above the try{} block and always dispose of them in finally{}.
        SqlCommand cmd = null;
        SqlDataReader dr = null;

        try
        {
            this.cboCountries.DisplayMember = "Label";
            this.cboCountries.ValueMember = "Value";
            this.cboDivisions.DisplayMember = "Label";
            this.cboDivisions.ValueMember = "Value";
            this.cboBusinessUnits.DisplayMember = "Label";
            this.cboBusinessUnits.ValueMember = "Value";
            this.cboMCCs.DisplayMember = "Label";
            this.cboMCCs.ValueMember = "Value";
            this.cboNodes.DisplayMember = "Label";
            this.cboNodes.ValueMember = "Value";
            this.cboProductCodes.DisplayMember = "Label";
            this.cboProductCodes.ValueMember = "Value";


            // Country parameters
            cmd = util.SqlConn.CreateCommand();
            cmd.CommandType = CommandType.StoredProcedure;
            cmd.CommandText = "proc_parms_countries_for_user";
            cmd.Parameters.Add("@whoAmI", SqlDbType.VarChar).Value = WindowsIdentity.GetCurrent().Name;
            dr = cmd.ExecuteReader();

            /////////////////////////////////////////////////////////////////////////////////////////////////

            var dtCountries = new DataTable();
            dtCountries.Columns.Add("Label");
            dtCountries.Columns.Add("Value");

            //DataRow _countries = dtCountries.NewRow();
            //_countries["country key"] = myBusinessUnit;
            //_countries["country name"] = myDataYear;

            //dtCountries.Rows.Add(_fcst);

            while (dr.Read())
                if (dr["country key"].ToString() != "0" && dr["country key"].ToString() != "1")
                {
                    dtCountries.Rows.Add(dr["country name"].ToString(), dr["country key"].ToString());
                }
            cmd.Parameters.Clear();
            dr.Close();

            this.cboCountries.DataSource = dtCountries;
person Ryan Ward    schedule 25.06.2013
comment
Аналогично этому ответу убедитесь, что привязка DataSource уже выполнена, когда вы пытаетесь установить SelectedValue. Я ошибочно предположил, что мое событие Form_Load завершилось к моменту установки SelectedValue (упс). - person Paul J; 30.04.2015

Чтобы использовать comboBox.SelectedValue, вы должны сначала установить comboBox.ValueMember.

ValueMember (MSDN)

Пример на MSDN демонстрирует, как использовать его в ситуации с привязкой к данным.

person Arclight    schedule 25.06.2013
comment
посмотрите мой добавленный код, я думаю, что сделал это правильно, но ценю вторую пару глаз. - person Ryan Ward; 25.06.2013

Я понял вашу боль, пожалуйста, попробуйте следующее

if (myxyzcombo.SelectedItem != null) 
{

 MessageBox.Show(myxyzcombo.SelectedItem.ToString());

 }
person SIDDIQUI JEGAM    schedule 12.09.2015
comment
Альтернативный код: if (myxyzcombo..SelectedIndex!= -1) { MessageBox.Show(myxyzcombo.SelectedItem.ToString()); } - person SIDDIQUI JEGAM; 12.09.2015
comment
Это не отвечает на вопрос. - person Tunaki; 12.09.2015