双向与Windows结合形态改变组合框时抛出的NullReferenceException [英] Two-way binding with Windows Forms ComboBox throws NullReferenceException when changed

查看:148
本文介绍了双向与Windows结合形态改变组合框时抛出的NullReferenceException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个Windows窗体应用程序,和的一种形式有几个组合框,它们都绑定到同一ES的的BindingList 对象我已经通过实体框架映射。

的Form_Load 事件调用这样的:

 私人无效SetFacilityDropdowns()
{
    dbContext.Facilities.Load();
    变种的BindingSource = dbContext.Facilities.Local.ToBindingList();
    字典<组合框,串> selectedDropDownsAndBoundFields =新词典<组合框,串>
        {
            {FacilityId,DataConstants.Facility.FacilityId},
            {FacilityName,DataConstants.Facility.FacilityName}
        };
    SetDropdowns(BindingSource的,selectedDropDownsAndBoundFields);
}

SetDropdowns 方法是这样的:

 私有静态无效SetDropdowns< T>(&的BindingList LT; T>数据源,字典<组合框,串> dropdownsAndBoundFields)
{
    如果(dropdownsAndBoundFields == NULL)
    {
        返回;
    }    的foreach(在dropdownsAndBoundFields VAR下拉)
    {
        dropdown.Key.DataSource =数据源;
        dropdown.Key.DisplayMember = dropdown.Value;
        dropdown.Key.ValueMember = dropdown.Value;
        dropdown.Key.AutoCompleteSource = AutoCompleteSource.ListItems;
        dropdown.Key.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
        dropdown.Key.SelectedIndexChanged + = Dropdown_SelectedIndexChanged;
    }
}

一切都看起来不错,两个组合框 ES似乎包含了所有,我会希望他们的项目。但是,也有从设施表数基金对象所在的 FacilityName 属性是。这似乎在组合框为空字符串,虽然我不知道这是否只是显示这种方式,或者当它势必都会转换。

通常情况下,当我改变了 FacilityName 下拉列表中, FacilityId 下拉菜单更改其匹配的值。然而,当我换 FacilityName 为空/空字符串值中的一个,我得到一个的NullReferenceException 抛出。这似乎是由Windows抛出窗体UI线程,所以我不能设置一个断点在任何组合框改变的事件,因为异常被之前的任何抛出事件被解雇。

任何想法,为什么会这样?

编辑:

下面是一个堆栈跟踪:

 > NITS.exe!NITS.Program.CurrentDomain_UIThreadException(对象发件人,System.Threading.ThreadExceptionEventArgs t)的50号线C#
    System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.OnThreadException(System.Exception T)+为0x8E字节
    System.Windows.Forms.dll中!System.Windows.Forms.Control.WndProcException(System.Exception的E)+ 0x16字节
    System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnThreadException(System.Exception E)+字节的0xA
    System.Windows.Forms.dll中!System.Windows.Forms.NativeWindow.Callback(System.IntPtr的HWND,INT味精,System.IntPtr WPARAM,LPARAM System.IntPtr)+ 0x9b字节
    [原产于托管过渡]
    [托管到本机转换]
    System.Windows.Forms.dll中!System.Windows.Forms.Control.SendMessage(INT味精,System.IntPtr WPARAM,LPARAM System.IntPtr)+ 0×21字节
    System.Windows.Forms.dll中!System.Windows.Forms.Control.ReflectMessageInternal(System.IntPtr的hWnd,楼盘System.Windows.Forms.Message米)+ 0x3b字节
    System.Windows.Forms.dll中!System.Windows.Forms.Control.WmCommand(参考System.Windows.Forms.Message米)+ 0x1b字节
    System.Windows.Forms.dll中!System.Windows.Forms.Control.WndProc(参考System.Windows.Forms.Message米)+ 0x3b7字节
    System.Windows.Forms.dll中!System.Windows.Forms.ScrollableControl.WndProc(参考System.Windows.Forms.Message米)+ 0x2a字节
    System.Windows.Forms.dll中!System.Windows.Forms.Form.WndProc(参考System.Windows.Forms.Message米)+ 0x5e字节
    System.Windows.Forms.dll中!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(参考System.Windows.Forms.Message米)+ 0×11字节
    System.Windows.Forms.dll中!System.Windows.Forms.Control.ControlNativeWindow.WndProc(参考System.Windows.Forms.Message米)+ 0x35字节
    System.Windows.Forms.dll中!System.Windows.Forms.NativeWindow.Callback(System.IntPtr的HWND,INT味精,System.IntPtr WPARAM,LPARAM System.IntPtr)+ 0x80的字节
    [原产于托管过渡]
    [托管到本机转换]
    System.Windows.Forms.dll中!System.Windows.Forms.NativeWindow.DefWndProc(参考System.Windows.Forms.Message米)+ 0x56字节
    System.Windows.Forms.dll中!System.Windows.Forms.Control.DefWndProc(参考System.Windows.Forms.Message米)+字节的0xA
    System.Windows.Forms.dll中!System.Windows.Forms.Control.WmMouseDown(参考System.Windows.Forms.Message男,System.Windows.Forms.MouseButtons按钮,点击诠释)+ 0x3a字节
    System.Windows.Forms.dll中!System.Windows.Forms.Control.WndProc(参考System.Windows.Forms.Message米)+ 0x8da字节
    System.Windows.Forms.dll中!System.Windows.Forms.ComboBox.WndProc(参考System.Windows.Forms.Message米)+ 0x864字节
    System.Windows.Forms.dll中!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(参考System.Windows.Forms.Message米)+ 0×11字节
    System.Windows.Forms.dll中!System.Windows.Forms.Control.ControlNativeWindow.WndProc(参考System.Windows.Forms.Message米)+ 0x35字节
    System.Windows.Forms.dll中!System.Windows.Forms.NativeWindow.Callback(System.IntPtr的HWND,INT味精,System.IntPtr WPARAM,LPARAM System.IntPtr)+ 0x80的字节
    [原产于托管过渡]
    [托管到本机转换]
    System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID,诠释原因,诠释pvLoopData)+ 0x24d字节
    System.Windows.Forms.dll中!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(INT原因,System.Windows.Forms.ApplicationContext上下文)+ 0x155字节
    System.Windows.Forms.dll中!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(INT原因,System.Windows.Forms.ApplicationContext上下文)+ 0x4a字节
    System.Windows.Forms.dll中!System.Windows.Forms.Application.Run(System.Windows.Forms.Form中的MainForm)+ 0X31字节
    NITS.exe!NITS.Program.Main()行37 + 0x1d字节C#
    [原产于托管过渡]
    [托管到本机转换]
    mscorlib.dll中!System.AppDomain.ExecuteAssembly(字符串assemblyFile,System.Security.Policy.Evidence assemblySecurity,字串[] args)+ 0x6b字节
    Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0×27字节
    mscorlib.dll中!System.Threading.ThreadHelper.ThreadStart_Context(对象状态)+ 0x6f字节
    mscorlib.dll中!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext的ExecutionContext,System.Threading.ContextCallback回调,对象状态,布尔preserveSyncCtx)+ 0xa7字节
    mscorlib.dll中!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext的ExecutionContext,System.Threading.ContextCallback回调,对象状态,布尔preserveSyncCtx)+ 0x16字节
    mscorlib.dll中!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext的ExecutionContext,System.Threading.ContextCallback回调,对象的状态)+ 0×41字节
    mscorlib.dll中!System.Threading.ThreadHelper.ThreadStart()+ 0x44进行字节
    [原产于托管过渡]

被抛出的异常是这样的:

  System.NullReferenceException对象引用未设置到对象的实例。 System.String get_Text()在System.Windows.Forms.ComboBox.get_Text()
   在System.Windows.Forms.ComboBox.WmReflectCommand(消息&放大器;米)
   在System.Windows.Forms.ComboBox.WndProc(消息&放大器;米)
   在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(消息&放大器;米)
   在System.Windows.Forms.Control.ControlNativeWindow.WndProc(消息&放大器;米)
   在System.Windows.Forms.NativeWindow.Callback(IntPtr的的HWND,味精的Int32,IntPtr的WPARAM,LPARAM的IntPtr)


解决方案

您主要的例外是明显

System.NullReferenceException对象引用未设置到对象的实例。 System.String get_Text()在System.Windows.Forms.ComboBox.get_Text()

这使我相信,你的组合框尝试设置的DisplayMember 属性设置为空值。既然你说你自己,你是不知道,如果未来从数据库后面的空列被重新presented为空字符串或空的基金类,你可以明确地将它们转换你的干将。此外,如果你传递一个可空到你的FacilityID属性,你需要将其转换为int这样的组合框可以处理它。

所以,在你的基金类。

 公共类基金
    {
        私人字符串_facilityName;
        私人诠释_facilityID;        公共字符串FacilityName
        {
            得到
            {
                如果(_facilityName == NULL)
                    返回的String.Empty;
                其他
                    返回_facilityName;
            }
            集合{_facilityName =价值; }
        }        公众诠释FacilityID
        {
            {返回_facilityID; }
            集合{_facilityID =值== NULL?默认值(INT):值};
        }
    }

利用这一点,你会确保你永远不会有你的控制企图绑定到一个空值,它应该摆脱你的异常。

I have a Windows Forms application, and one of the forms has a couple of ComboBoxes that are both bound to the same BindingList of objects I have mapped via Entity Framework.

The Form_Load event calls this:

private void SetFacilityDropdowns()
{
    dbContext.Facilities.Load();
    var bindingSource = dbContext.Facilities.Local.ToBindingList();
    Dictionary<ComboBox, string> selectedDropDownsAndBoundFields = new Dictionary<ComboBox, string>
        {
            {FacilityId,    DataConstants.Facility.FacilityId},
            {FacilityName,  DataConstants.Facility.FacilityName}
        };
    SetDropdowns(bindingSource, selectedDropDownsAndBoundFields);            
}

The SetDropdowns method looks like this:

private static void SetDropdowns<T>(BindingList<T> dataSource, Dictionary<ComboBox, string> dropdownsAndBoundFields)
{
    if (dropdownsAndBoundFields == null)
    {
        return;
    }

    foreach (var dropdown in dropdownsAndBoundFields)
    {
        dropdown.Key.DataSource = dataSource;
        dropdown.Key.DisplayMember = dropdown.Value;
        dropdown.Key.ValueMember = dropdown.Value;
        dropdown.Key.AutoCompleteSource = AutoCompleteSource.ListItems;
        dropdown.Key.AutoCompleteMode = AutoCompleteMode.SuggestAppend;
        dropdown.Key.SelectedIndexChanged += Dropdown_SelectedIndexChanged;
    }
}

Everything looks fine, and both ComboBoxes appear to contain all of the items that I would expect them to. However, there are a few Facility objects from the Facilities table where the FacilityName property is null. This appears in the ComboBox as an empty string, although I don't know if it is only displayed that way or if it gets converted when it is bound.

Normally, when I change the FacilityName dropdown, the FacilityId dropdown changes to its matching value. However, when I change FacilityName to one of the null/empty string values, I get a NullReferenceException thrown. It appears to be thrown by the Windows Forms UI thread, so I can't set a breakpoint in any of the ComboBox "changed" events, because the exception gets thrown before any of the events get fired.

Any idea why this is happening?

EDIT:

Here is a stack trace:

>   NITS.exe!NITS.Program.CurrentDomain_UIThreadException(object sender, System.Threading.ThreadExceptionEventArgs t) Line 50   C#
    System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.OnThreadException(System.Exception t) + 0x8e bytes  
    System.Windows.Forms.dll!System.Windows.Forms.Control.WndProcException(System.Exception e) + 0x16 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnThreadException(System.Exception e) + 0xa bytes 
    System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x9b bytes   
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    System.Windows.Forms.dll!System.Windows.Forms.Control.SendMessage(int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x21 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.Control.ReflectMessageInternal(System.IntPtr hWnd, ref System.Windows.Forms.Message m) + 0x3b bytes   
    System.Windows.Forms.dll!System.Windows.Forms.Control.WmCommand(ref System.Windows.Forms.Message m) + 0x1b bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x3b7 bytes 
    System.Windows.Forms.dll!System.Windows.Forms.ScrollableControl.WndProc(ref System.Windows.Forms.Message m) + 0x2a bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Form.WndProc(ref System.Windows.Forms.Message m) + 0x5e bytes 
    System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0x11 bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x35 bytes  
    System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x80 bytes   
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m) + 0x56 bytes  
    System.Windows.Forms.dll!System.Windows.Forms.Control.DefWndProc(ref System.Windows.Forms.Message m) + 0xa bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Control.WmMouseDown(ref System.Windows.Forms.Message m, System.Windows.Forms.MouseButtons button, int clicks) + 0x3a bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) + 0x8da bytes 
    System.Windows.Forms.dll!System.Windows.Forms.ComboBox.WndProc(ref System.Windows.Forms.Message m) + 0x864 bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) + 0x11 bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) + 0x35 bytes  
    System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.Callback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) + 0x80 bytes   
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    System.Windows.Forms.dll!System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(System.IntPtr dwComponentID, int reason, int pvLoopData) + 0x24d bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason, System.Windows.Forms.ApplicationContext context) + 0x155 bytes  
    System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) + 0x4a bytes    
    System.Windows.Forms.dll!System.Windows.Forms.Application.Run(System.Windows.Forms.Form mainForm) + 0x31 bytes  
    NITS.exe!NITS.Program.Main() Line 37 + 0x1d bytes   C#
    [Native to Managed Transition]  
    [Managed to Native Transition]  
    mscorlib.dll!System.AppDomain.ExecuteAssembly(string assemblyFile, System.Security.Policy.Evidence assemblySecurity, string[] args) + 0x6b bytes    
    Microsoft.VisualStudio.HostingProcess.Utilities.dll!Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly() + 0x27 bytes  
    mscorlib.dll!System.Threading.ThreadHelper.ThreadStart_Context(object state) + 0x6f bytes   
    mscorlib.dll!System.Threading.ExecutionContext.RunInternal(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0xa7 bytes  
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state, bool preserveSyncCtx) + 0x16 bytes  
    mscorlib.dll!System.Threading.ExecutionContext.Run(System.Threading.ExecutionContext executionContext, System.Threading.ContextCallback callback, object state) + 0x41 bytes    
    mscorlib.dll!System.Threading.ThreadHelper.ThreadStart() + 0x44 bytes   
    [Native to Managed Transition]  

The exception being thrown looks like this:

System.NullReferenceException Object reference not set to an instance of an object. System.String get_Text()    at System.Windows.Forms.ComboBox.get_Text()
   at System.Windows.Forms.ComboBox.WmReflectCommand(Message& m)
   at System.Windows.Forms.ComboBox.WndProc(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
   at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
   at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)

解决方案

Your main exception is obviously

System.NullReferenceException Object reference not set to an instance of an object. System.String get_Text() at System.Windows.Forms.ComboBox.get_Text()

which leads me to believe that your combobox is trying to set the DisplayMember property to a null value. Since you said yourself you're not sure if the empty columns coming back from your database are represented as empty strings or null in the Facility class, you can explicity convert them in your getters. In addition, if you are passing in a Nullable to your FacilityID property, you need to convert it to an int so the combobox can handle it.

So, in your Facility class.

    public class Facility
    {
        private string _facilityName;
        private int _facilityID;

        public string FacilityName
        {
            get
            {
                if (_facilityName == null)
                    return String.Empty;
                else
                    return _facilityName;
            }
            set { _facilityName = value; }
        }

        public int FacilityID
        {
            get { return _facilityID; }
            set { _facilityID = value == null ? default(int) : value};
        }
    }

Using this, you'll make sure that you never have your control attempting to bind to a null value, and it should rid you of the exception.

这篇关于双向与Windows结合形态改变组合框时抛出的NullReferenceException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆