C# Combo Box SelectedValue Null

Без да публикувам целия си код (просто публикувам обидния скрипт), имам проблем, който изглежда като много хора са имали, но моят изглежда не отговаря на други препоръчани корекции. Използвам C# във VS2008.

По принцип имам comboBox и когато елементът init се промени, той отива към кода по-долу. По същество кодът ще определи коя държава е била избрана (myCountryKey) и след това ще предаде това като параметър към съхранена процедура, която попълва следващ comboBox.

Странното е, че свойството 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