双向与Windows结合形态改变组合框时抛出的NullReferenceException [英] Two-way binding with Windows Forms ComboBox throws NullReferenceException when changed
问题描述
我有一个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 ComboBox
es 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 ComboBox
es 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屋!