Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/311.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C#WinForms(.NET 3.5):组合框在第一次选择后返回空引用_C#_Winforms_Combobox_.net 3.5 - Fatal编程技术网

C#WinForms(.NET 3.5):组合框在第一次选择后返回空引用

C#WinForms(.NET 3.5):组合框在第一次选择后返回空引用,c#,winforms,combobox,.net-3.5,C#,Winforms,Combobox,.net 3.5,注意:这是一个普通的WinForms应用程序。没有WPF或WCF或其他任何东西 大家好,我正在开发一个WinForms(.NET3.5)应用程序,遇到了一个问题。我正在尝试根据所选状态获取城市(都在两个不同的组合框-es中,DropDownStyle设置为DropDownList) 我使用SelectedValue属性在SelectedIndexChanged事件处理程序中实现了此逻辑。DataSource是从DB方法返回的DataTable,SelectedValue返回DataRowView

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

大家好,我正在开发一个WinForms(.NET3.5)应用程序,遇到了一个问题。我正在尝试根据所选状态获取城市(都在两个不同的
组合框
-es中,
DropDownStyle
设置为
DropDownList

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

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

现在,当我使用鼠标在表单启动和运行时,在构建后更改所选状态时出现问题。这再次转到事件处理程序,但
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'
            }
        }
请注意,所有这些都发生在已填充的状态组合框中。城市
组合框
甚至第二次都没有进入范围,因此没有数据库问题


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

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

comboFindState.ValueMember = "State Code";
comboFindState.DisplayMember = "StateName"; //will be displayed in the combobox
comboFindState.DataSource = yourDataTableOfStates;
然后
SelectedValue
状态代码的值返回为整数类型(在对象类型中装箱)
或者如果
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
事件

…关于评论…
如果数据源为空,编译器如何知道“状态代码”的含义?如果不同,请务必解释
编译器与这个问题无关。这在运行时发生 当设置
ValueMember
DataSource
null
之前的)时。然后,
ValueMember
的值将被保存并仅在您调用
SelectedValue
时使用
如果从
DataSource
的属性/列中找不到
ValueMember
,则将返回整个选定对象,如果
DataSource
DataTable
DataRowView

当设置
ValueMember
DataSource
不是
null
之后)时。

然后,如果
DataSource
类型中存在属性/列,则将检查
ValueMember
的新值。如果不存在,则会抛出
ArgumentException

您可以尝试用comboFindState.SelectedValue替换comboFindState.SelectedItem吗?瞧!它起作用了!先生/女士,您将被称为我的救世主。然而,我仍然不明白为什么
SelectedValue
在第二次测试中不起作用。对此有何想法?正如法比奥所解释的,问题在于数据源属性的使用。您需要设置ValueMember。我已经设置了
ValueMember
属性。与Fabio的代码唯一不同的是,我首先设置
数据源
,然后设置
值成员
。这似乎是合乎逻辑的,否则,如果数据源为空,编译器如何知道“状态代码”的含义?如果不同,请解释。您可以在
DataSource
之前或之后,以两种方式设置
ValueMember
。如果在分配
数据源
后设置
ValueMember
,则可能会使用数据源属性/列对新的
ValueMember
执行一些额外的检查。然后SelectedValue将状态代码的值返回为整数类型(在对象类型中装箱)-这不会发生。它返回一个DataRowView对象。如果我尝试直接将SelectedValue对象转换或强制转换为int或string,它会抛出一个InvalidCastException。这是最让我烦恼的。它不返回标量值,而是返回DataRowView对象。我认为是因为将<代码> DATABATE
设置为<代码>数据源。如果设置<代码> COMPOFIDENSTATE.ValueMeNe= =“状态代码”,则是正确的;code>另外,您是否介意解释一下为什么应该在
数据源
之前设置
ValueMember
?当基本数据甚至不可用时,指定一些相对值似乎不合逻辑。我已经设置了
comboFindState.ValueMember=“State code”。从绝对开始。因此问题就来了。