C# WinForms (.NET 3.5):第一次选择后 ComboBox returns 空引用
C# WinForms (.NET 3.5): ComboBox returns null reference after first selection
注意:这是一个普通的 WinForms 应用程序。没有 WPF 或 WCF 或其他任何东西。
大家好,我正在开发一个 WinForms (.NET 3.5) 应用程序,但遇到了一个问题。我正在尝试根据所选州获取城市(都在 2 个不同的 ComboBox
-es 中 DropDownStyle
设置为 DropDownList
)。
我已经使用 SelectedValue
属性 在 SelectedIndexChanged
事件处理程序中实现了这个逻辑。 DataSource
是从数据库方法返回的 DataTable
,SelectedValue
returns 是 DataRowView
.
的实例
在表单构造函数 中,我填充状态 ComboBox 并使用 SelectedIndex
属性 以编程方式设置默认状态选择;然后进入事件处理程序,正确执行,并填充该州的城市 ComboBox
。
现在,当我使用鼠标更改选定状态 post-construction 和 运行 时,问题就来了。这再次转到事件处理程序,但是 SelectedValue
属性 returns 是空引用 。请帮忙。我附上下面的代码。
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
连第二次都没有进入范围,所以数据库没有问题。
编辑: 仅供参考,我已经从 绝对开始 comboFindState
为 tcomboFindState
设置了 ValueMember
属性 =52=]。所以这不是它不起作用的原因。另请注意,它第一次运行正常,因此证明 ValueMember
设置正确。
只要正确使用DataSource
,没有变通方法。
在设置 DataSource
之前,将 属性 ValueMember
设置为您用于获取城市的列名称
comboFindState.ValueMember = "State Code";
comboFindState.DisplayMember = "StateName"; //will be displayed in the combobox
comboFindState.DataSource = yourDataTableOfStates;
然后SelectedValue
将return的值State Code
作为整数类型(在Object类型中装箱)
或 null
如果 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 为空,编译器如何知道 'State Code' 的含义?如果不同,请解释
编译器与这个问题无关。这发生在运行时
当您设置 ValueMember
而 DataSource
是 null
( 之前 )。然后 ValueMember
的值将被保存并仅在您调用 SelectedValue
.
时使用
如果无法从 DataSource
的 properties/columns 中找到 ValueMember
,则整个选定对象将被 returned,以防 DataSource
为 DataTable
DataRowView
将 returned
当您设置 ValueMember
而 DataSource
不是 null
(after)。
如果 DataSource
的类型中存在 properties/columns,则将检查 ValueMember
的新值。如果不存在,则 ArgumentException
将被抛出
注意:这是一个普通的 WinForms 应用程序。没有 WPF 或 WCF 或其他任何东西。
大家好,我正在开发一个 WinForms (.NET 3.5) 应用程序,但遇到了一个问题。我正在尝试根据所选州获取城市(都在 2 个不同的 ComboBox
-es 中 DropDownStyle
设置为 DropDownList
)。
我已经使用 SelectedValue
属性 在 SelectedIndexChanged
事件处理程序中实现了这个逻辑。 DataSource
是从数据库方法返回的 DataTable
,SelectedValue
returns 是 DataRowView
.
在表单构造函数 中,我填充状态 ComboBox 并使用 SelectedIndex
属性 以编程方式设置默认状态选择;然后进入事件处理程序,正确执行,并填充该州的城市 ComboBox
。
现在,当我使用鼠标更改选定状态 post-construction 和 运行 时,问题就来了。这再次转到事件处理程序,但是 SelectedValue
属性 returns 是空引用 。请帮忙。我附上下面的代码。
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
连第二次都没有进入范围,所以数据库没有问题。
编辑: 仅供参考,我已经从 绝对开始 comboFindState
为 tcomboFindState
设置了 ValueMember
属性 =52=]。所以这不是它不起作用的原因。另请注意,它第一次运行正常,因此证明 ValueMember
设置正确。
只要正确使用DataSource
,没有变通方法。
在设置 DataSource
之前,将 属性 ValueMember
设置为您用于获取城市的列名称
comboFindState.ValueMember = "State Code";
comboFindState.DisplayMember = "StateName"; //will be displayed in the combobox
comboFindState.DataSource = yourDataTableOfStates;
然后SelectedValue
将return的值State Code
作为整数类型(在Object类型中装箱)
或 null
如果 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 为空,编译器如何知道 'State Code' 的含义?如果不同,请解释
编译器与这个问题无关。这发生在运行时
当您设置 ValueMember
而 DataSource
是 null
( 之前 )。然后 ValueMember
的值将被保存并仅在您调用 SelectedValue
.
时使用
如果无法从 DataSource
的 properties/columns 中找到 ValueMember
,则整个选定对象将被 returned,以防 DataSource
为 DataTable
DataRowView
将 returned
当您设置 ValueMember
而 DataSource
不是 null
(after)。
如果 DataSource
的类型中存在 properties/columns,则将检查 ValueMember
的新值。如果不存在,则 ArgumentException
将被抛出