C# 向事件中的组合框添加项目时出现InvalidOperationException
我正在WPF中制作一个相当简单的SQL Server数据库/表选择器,与SSMS的“连接属性”选项卡(单击“选项”按钮时)类似,我希望组合框中有一个项目可以连接到服务器,查找数据库或表的列表(取决于哪个组合框处于活动状态),并用这些数据库/表填充分隔线下方的组合框。当我运行我的项目来执行此操作时,我得到一个InvalidOperationException,声明“集合已修改;枚举操作不能在窗体的ShowDialog行上执行,而不能在窗体本身内执行 我将事件代码包装在一个Try/Catch块中,以尝试更好地理解异常从何处抛出,但它从未在我自己的代码中捕获。只有在“我的事件”退出之后,在事件和WPF后端之间的某个地方,才会抛出异常,并带有以下堆栈跟踪(应用程序实际启动之前的条目已被删除): 例外情况是源代码只是“mscorlib” 所讨论的事件如下所示:C# 向事件中的组合框添加项目时出现InvalidOperationException,c#,wpf,combobox,enumeration,C#,Wpf,Combobox,Enumeration,我正在WPF中制作一个相当简单的SQL Server数据库/表选择器,与SSMS的“连接属性”选项卡(单击“选项”按钮时)类似,我希望组合框中有一个项目可以连接到服务器,查找数据库或表的列表(取决于哪个组合框处于活动状态),并用这些数据库/表填充分隔线下方的组合框。当我运行我的项目来执行此操作时,我得到一个InvalidOperationException,声明“集合已修改;枚举操作不能在窗体的ShowDialog行上执行,而不能在窗体本身内执行 我将事件代码包装在一个Try/Catch块中,以
private void CbiBrowseDB_Selected(object sender, RoutedEventArgs e) {
try {
using(SqlConnection conn = new SqlConnection(GetConnectionString())) {
try {
conn.Open();
} catch(Exception ex) {
MessageBox.Show("Failed to connect to the SQL Server: " + ex.Message);
return;
}
DataTable dbs = new DataTable();
SqlDataAdapter adapter = new SqlDataAdapter("SELECT [name] FROM sys.databases WHERE [name] NOT IN ('master', 'tempdb', 'model', 'msdb')", conn);
try {
adapter.Fill(dbs);
} catch(InvalidOperationException ex) {
MessageBox.Show("Failed to retrieve table list from the SQL Server: " + ex.Message);
}
try {
while(cbxDatabase.Items.Count > 2) {
cbxDatabase.Items.RemoveAt(cbxDatabase.Items.Count - 1);
}
for(int i = 0; i < dbs.Rows.Count; ++i) {
ComboBoxItem item = new ComboBoxItem();
item.Content = dbs.Rows[i].Field<string>("name");
cbxDatabase.Items.Add(item);
}
cbxDatabase.Items.Refresh();
} catch(InvalidOperationException ex) {
MessageBox.Show("Failed to update the list of databases: " + ex.Message + "\r\n" + ex.StackTrace);
}
}
} catch (Exception ex) {
MessageBox.Show("Failed.");
}
}
private void CbiBrowseDB_选中(对象发送方,路由目标){
试一试{
使用(SqlConnection conn=newsqlconnection(GetConnectionString())){
试一试{
conn.Open();
}捕获(例外情况除外){
MessageBox.Show(“未能连接到SQL Server:+ex.Message”);
返回;
}
DataTable dbs=新DataTable();
SqlDataAdapter=newsqldataadapter(“从sys.databases中选择[name],其中[name]不在('master'、'tempdb'、'model'、'msdb')、conn中);
试一试{
适配器填充(dbs);
}捕获(无效操作异常ex){
MessageBox.Show(“未能从SQL Server检索表列表:”+ex.Message);
}
试一试{
而(cbxDatabase.Items.Count>2){
cbxDatabase.Items.RemoveAt(cbxDatabase.Items.Count-1);
}
对于(int i=0;i
我原以为这会起作用,但我却抛出了异常。广义的“catch(exception ex)”从未执行过,这向我表明这是WPF在后台做的某件事引起的问题。我怀疑这可能是因为在扩展的组合框中选择一个选项触发了此事件,但这种行为在SSM中起作用,所以我不确定我做错了什么。我已经看到,在修改foreach
循环中的枚举时,经常会出现此问题,但我没有在本事件中或本项目中的任何其他地方使用任何枚举。您正在执行的操作
while(cbxDatabase.Items.Count > 2) {
cbxDatabase.Items.RemoveAt(cbxDatabase.Items.Count - 1);
}
这里您正在修改while循环中的集合对象。我看不到在上面粘贴的代码中任何地方初始化
cbxDatabase
。可能这就是异常的原因。您似乎在处理ComboBoxItem
的选定事件。尝试为组合框处理选择更改的事件。然后您应该不会得到任何invalidoOperationException
您似乎在处理ComboBoxItem
的所选事件。请尝试处理组合框的SelectionChanged
事件。@mm8恼人的是,这似乎已经解决了它。我更希望通过项目的click事件来执行此操作,而不是在selection changed事件中检查索引,但它是这样工作的,而不是另一种方式,因此SelectionChanged事件就是这样。如果你能把它作为一个答案,我可以为你接受它。谢谢你的帮助!所有控件都是作为窗口的一部分创建的,为了避免问题过于拥挤,我省略了窗口。如果控件为null,则引发的异常将是NullReferenceException而不是InvalidOperationException,并且代码中的try/catch块也将能够捕获该异常。据我所知,这是WPF本身的一个问题。
while(cbxDatabase.Items.Count > 2) {
cbxDatabase.Items.RemoveAt(cbxDatabase.Items.Count - 1);
}