C#WinForms(.NET 3.5):首次选择后,ComboBox返回空引用

时间:2015-07-30 05:50:12

标签: c# winforms combobox .net-3.5

注意:这是一个vanilla WinForms应用程序。没有WPF或WCF或其他任何东西。

嘿嘿,我正在开发一个 WinForms(.NET 3.5)应用程序,我遇到了问题。我正在尝试根据所选状态获取城市(两个ComboBox - DropDownStyle设置为DropDownList

我已使用SelectedIndexChanged属性在SelectedValue事件处理程序中实现了此逻辑。 DataSource是从DB方法返回的DataTableSelectedValue返回DataRowView的实例。

在表单构造函数中,我填充状态ComboBox并使用SelectedIndex属性以编程方式设置默认状态选择;然后转到事件处理程序,正确执行,并为该状态填充 ComboBox

现在当我改变所选状态构建后时,问题出现了,当表格已经完成&用我的鼠标跑步。这再次转到事件处理程序,但SelectedValue属性返回空引用。请帮忙。我附上下面的代码。

private void comboFindState_SelectedIndexChanged(object sender, EventArgs e)
        {

            DataRowView selectedState;
            int selectedStateId;
            DataTable citiesTable;

            selectedState = comboFindState.SelectedValue as DataRowView;


            if (selectedState != null) //Is true the first time around when the event is
            //triggered due to programmatic change of the index.
            //Then null afterwards, on change via mouse click.
            {
                selectedStateId = Convert.ToInt32(selectedState.Row["State Code"]);
                citiesTable = DatabaseHelper.getStateCities(selectedStateId);

                comboFindCity.DataSource = citiesTable; //Same binding for state ComboBox
                //in the form's constructor;
                comboFindCity.DisplayMember = "City"; //only here it says "State",
                comboFindCity.ValueMember = "City Code";// and here it says "State Code".

                comboFindCity.SelectedIndex = 0; //Same thing in the form's constructor for
                //setting default selected index of state ComboBox.
            }
            else
            {
                //just populates an error TextBox saying 'No Cities Found'
            }
        }

请注意,所有这些都发生在已填充的状态ComboBox上。城市ComboBox甚至没有第二次进入范围,因此没有数据库问题。

编辑:仅供参考,我已从绝对开始为t ValueMember设置comboFindState属性。所以这不是它不起作用的原因。另请注意,它第一次正常工作,因此证明ValueMember设置正确。

1 个答案:

答案 0 :(得分:2)

正确使用DataSource,无需解决方法 在将DataSource设置属性ValueMember设置为您用于获取城市的列名称之前

comboFindState.ValueMember = "State Code";
comboFindState.DisplayMember = "StateName"; //will be displayed in the combobox
comboFindState.DataSource = yourDataTableOfStates;

然后SelectedValue将返回State Code的值作为整数类型(在对象类型中加框)
null if comboFindState.SelectedIndex = -1

private void comboFindState_SelectedIndexChanged(object sender, EventArgs e)
{
    if (comboFindState.SelectedValue != null)
    {
        int selectedStateId = (int)comboFindState.SelectedValue;
        DataTable citiesTable = DatabaseHelper.getStateCities(selectedStateId);

        //Your code after getting list of the cities
    }
}

另外
如果您设置ValueMember,则可以使用SelectedValueChanged事件

...关于评论......
如果DataSource为null,编译器将如何知道'State Code'意味着什么?如果不同,请解释
编译器与此问题无关。这发生在运行时 当ValueMember DataSourcenull之前)时设置ValueMember。然后,SelectedValue的值将被保存并仅在您调用ValueMember时使用 如果无法从DataSource的属性/列中找到DataSource,则会返回整个所选对象,以防DataTable DataRowView ValueMember将被返回

DataSource不是null 之后)时设置ValueMember。 然后,如果DataSource的类型中存在属性/列,则将检查ArgumentException的新值。如果不存在,则会抛出media="print"