当应用程序失去焦点时,Windows窗体ComboBox触发SelectionChangeCommitted,SelectedValueChanged和SelectedIndexChanged事件

时间:2010-08-20 09:21:36

标签: c# winforms events combobox .net-2.0

我有包含组合框的.Net 2.0 Windows窗体。我编写了以下代码来填充组合框,然后将其绑定到Int。

类型的ProductType属性
// Populate Combo

cmbProduct.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
cmbProduct.DataSource = new DataView(productDataSet.Tables[0]);
cmbProduct.DisplayMember = displayColumnName_;
cmbProduct.ValueMember = idColumnaName_;

// Add Databindings

cmbProduct.DataBindings.Add("SelectedValue", this, "ProductType").DataSourceUpdateMode = DataSourceUpdateMode.OnPropertyChanged;

问题

  1. 运行应用程序。
  2. 点击ComboBox的下拉箭头,但不要选择任何项目。
  3. 按任意键(例如ALT + TAB,Windows Key等),这将使焦点从当前的Windows表单应用程序转移。
  4. 这会抛出异常和应用程序崩溃。以下是从“输出”窗口中获取的详细信息。

      

    发生了'System.ArgumentException'类型的第一次机会异常   在System.Windows.Forms.dll中,'System.DBNull'类型的对象不能   转换为'System.Int32'类型。在   System.ComponentModel.ReflectPropertyDescriptor.SetValue(对象   组件,对象值)          在System.Windows.Forms.BindToObject.SetValue(对象值)          在System.Windows.Forms.Binding.PullData(布尔重新格式,布尔力)          在System.Windows.Forms.Binding.Target_PropertyChanged(Object sender,EventArgs e)          在System.EventHandler.Invoke(Object sender,EventArgs e)          在System.Windows.Forms.ListControl.OnSelectedValueChanged(EventArgs e)          在System.Windows.Forms.ComboBox.OnSelectedValueChanged(EventArgs e)          在System.Windows.Forms.ComboBox.OnSelectedIndexChanged(EventArgs e)          在System.Windows.Forms.ComboBox.WmReflectCommand(Message& m)          在System.Windows.Forms.ComboBox.WndProc(消息& m)          在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)          在System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)          在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)          在System.Windows.Forms.UnsafeNativeMethods.SendMessage(HandleRef hWnd,   Int32 msg,IntPtr wParam,IntPtr lParam)          在System.Windows.Forms.Control.SendMessage(Int32 msg,IntPtr wparam,IntPtr lparam)          在System.Windows.Forms.Control.ReflectMessageInternal(IntPtr hWnd,Message& m)          在System.Windows.Forms.Control.WmCommand(Message& m)          在System.Windows.Forms.Control.WndProc(消息& m)          在System.Windows.Forms.ScrollableControl.WndProc(消息& m)          在System.Windows.Forms.ContainerControl.WndProc(消息& m)          在System.Windows.Forms.Form.WndProc(消息& m)          在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)          在System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)          在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)          在System.Windows.Forms.UnsafeNativeMethods.CallWindowProc(IntPtr)   wndProc,IntPtr hWnd,Int32 msg,IntPtr wParam,IntPtr lParam)          在System.Windows.Forms.NativeWindow.DefWndProc(消息& m)          在System.Windows.Forms.Control.DefWndProc(消息& m)          在System.Windows.Forms.Control.WmCommand(Message& m)          在System.Windows.Forms.Control.WndProc(消息& m)          在System.Windows.Forms.ComboBox.WndProc(消息& m)          在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)          在System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)          在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd,Int32 msg,IntPtr wparam,IntPtr lparam)          在System.Windows.Forms.UnsafeNativeMethods.PeekMessage(MSG& msg,HandleRef hwnd,Int32 msgMin,Int32 msgMax,Int32 remove)          在System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(Int32)   dwComponentID,Int32原因,Int32 pvLoopData)          在System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32)   原因,ApplicationContext上下文)          在System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32)   原因,ApplicationContext上下文)          在System.Windows.Forms.Application.Run(Form mainForm)

    我在事件处理程序中添加了一些调试语句来检查事件序列。 输出窗口deatails如下所示:

    cmbProduct_SelectionChangeCommitted occured - SelectedValue is NULL
    cmbProduct_SelectedValueChanged occured - New SelectedValue is NULL
    The thread 0x1728 has exited with code 0 (0x0).
    cmbProduct_SelectedIndexChanged occured - New SelectedIndex is -1
    The thread 0x1250 has exited with code 0 (0x0).
    

    问题

    当应用程序在组合框状态下失去焦点时,为什么.Net会触发SelectionChangeCommittedSelectedValueChangedSelectedIndexChanged个事件?

2 个答案:

答案 0 :(得分:2)

代码看起来很完美。问题可能是因为.net框架中的错误。有些专家可以证实这一点吗?

避免异常的一种解决方法是 - 如果SelectedValue为NULL,则存储“ProductType”属性的默认值。

例如,如果ProductType的默认值为-1,则

cmbProduct.DataBindings["SelectedValue"].DataSourceNullValue = -1; 

希望,这有帮助!

罗宾

答案 1 :(得分:0)

听起来你提出了一个错误的问题:“为什么组合会失去焦点?”而不是“为什么抛出异常?”

罗宾正确地回答了重要人物。

用户无需执行您提供的复杂3个步骤来查看异常 - 仅选择违规(null)索引将导致异常。