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