在事件中将项目添加到组合框时发生InvalidOperationException

时间:2019-04-28 18:50:20

标签: c# wpf combobox enumeration

我正在WPF中创建一个相当简单的SQL Server数据库/表选择器,并且类似于SSMS的“连接属性”选项卡(单击“选项”按钮时),希望组合框中的一项将连接到服务器,找到数据库或表的列表(取决于哪个组合框处于活动状态),并用这些数据库/表填充分隔线下方的组合框。当我运行项目来执行此操作时,我收到一个InvalidOperationException声明“集合已修改;枚举操作可能无法执行。”在表单的ShowDialog行上,而不是在表单本身内。

我已将事件代码包装在Try / Catch块中,以尝试并更好地了解异常从何处引发的,但从未捕获到我自己的代码。仅在事件退出后,事件与WPF后端之间的某个位置以及以下堆栈跟踪(在应用程序实际启动之前的条目已被删除)之后才抛出异常:

   at System.ThrowHelper.ThrowInvalidOperationException(ExceptionResource resource)
   at System.Collections.Generic.List`1.Enumerator.MoveNextRare()
   at System.Collections.Generic.List`1.Enumerator.MoveNext()
   at System.Windows.Controls.Primitives.Selector.SelectionChanger.CreateDeltaSelectionChange(List`1 unselectedItems, List`1 selectedItems)
   at System.Windows.Controls.Primitives.Selector.SelectionChanger.End()
   at System.Windows.Controls.Primitives.Selector.SelectionChanger.SelectJustThisItem(ItemInfo info, Boolean assumeInItemsCollection)
   at System.Windows.Controls.ComboBox.NotifyComboBoxItemMouseUp(ComboBoxItem comboBoxItem)
   at System.Windows.Controls.ComboBoxItem.OnMouseLeftButtonUp(MouseButtonEventArgs e)
   at System.Windows.UIElement.OnMouseLeftButtonUpThunk(Object sender, MouseButtonEventArgs e)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.ReRaiseEventAs(DependencyObject sender, RoutedEventArgs args, RoutedEvent newEvent)
   at System.Windows.UIElement.OnMouseUpThunk(Object sender, MouseButtonEventArgs e)
   at System.Windows.Input.MouseButtonEventArgs.InvokeEventHandler(Delegate genericHandler, Object genericTarget)
   at System.Windows.RoutedEventArgs.InvokeHandler(Delegate handler, Object target)
   at System.Windows.RoutedEventHandlerInfo.InvokeHandler(Object target, RoutedEventArgs routedEventArgs)
   at System.Windows.EventRoute.InvokeHandlersImpl(Object source, RoutedEventArgs args, Boolean reRaised)
   at System.Windows.UIElement.RaiseEventImpl(DependencyObject sender, RoutedEventArgs args)
   at System.Windows.UIElement.RaiseTrustedEvent(RoutedEventArgs args)
   at System.Windows.UIElement.RaiseEvent(RoutedEventArgs args, Boolean trusted)
   at System.Windows.Input.InputManager.ProcessStagingArea()
   at System.Windows.Input.InputManager.ProcessInput(InputEventArgs input)
   at System.Windows.Input.InputProviderSite.ReportInput(InputReport inputReport)
   at System.Windows.Interop.HwndMouseInputProvider.ReportInput(IntPtr hwnd, InputMode mode, Int32 timestamp, RawMouseActions actions, Int32 x, Int32 y, Int32 wheel)
   at System.Windows.Interop.HwndMouseInputProvider.FilterMessage(IntPtr hwnd, WindowMessage msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at System.Windows.Interop.HwndSource.InputFilterMessage(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndWrapper.WndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam, Boolean& handled)
   at MS.Win32.HwndSubclass.DispatcherCallbackOperation(Object o)
   at System.Windows.Threading.ExceptionWrapper.InternalRealCall(Delegate callback, Object args, Int32 numArgs)
   at System.Windows.Threading.ExceptionWrapper.TryCatchWhen(Object source, Delegate callback, Object args, Int32 numArgs, Delegate catchHandler)
   at System.Windows.Threading.Dispatcher.LegacyInvokeImpl(DispatcherPriority priority, TimeSpan timeout, Delegate method, Object args, Int32 numArgs)
   at MS.Win32.HwndSubclass.SubclassWndProc(IntPtr hwnd, Int32 msg, IntPtr wParam, IntPtr lParam)
   at MS.Win32.UnsafeNativeMethods.DispatchMessage(MSG& msg)
   at System.Windows.Threading.Dispatcher.PushFrameImpl(DispatcherFrame frame)
   at System.Windows.Threading.Dispatcher.PushFrame(DispatcherFrame frame)
   at System.Windows.Window.ShowHelper(Object booleanBox)
   at System.Windows.Window.Show()
   at System.Windows.Window.ShowDialog()
   at VDBFImport.App.Application_Startup(Object sender, StartupEventArgs e) 

该异常表明来源只是“ mscorlib”

相关事件如下:

        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.");
            }
        }

我希望这可以正常工作,但是我会抛出异常。宽泛的“ catch(ex ex ex)”永远不会执行,这向我表明这是WPF在后台执行的操作引起的问题。我怀疑这可能是由于在扩展的组合框中选择一个选项而触发了此事件,但是这种类型的行为在SSMS中有效,因此我不确定自己在做什么错。我已经看到,在foreach循环中修改枚举时,经常会发生此问题,但是在此事件或项目的其他任何地方,我都没有使用过任何枚举。

2 个答案:

答案 0 :(得分:1)

您似乎为Selected处理了ComboBoxItem事件。尝试为SelectionChanged处理ComboBox事件。那么您应该不会得到InvalidOperationException

答案 1 :(得分:0)

您正在做

while(cbxDatabase.Items.Count > 2) {
    cbxDatabase.Items.RemoveAt(cbxDatabase.Items.Count - 1);
}

在这里,您正在while循环中修改集合对象。而且我看不到cbxDatabase在上面粘贴的代码中的任何地方被初始化。也许这是导致异常的原因。