C# 使用Windows窗体组合框的双向绑定在更改时引发NullReferenceException
我有一个Windows窗体应用程序,其中一个窗体有两个C# 使用Windows窗体组合框的双向绑定在更改时引发NullReferenceException,c#,winforms,data-binding,binding,combobox,C#,Winforms,Data Binding,Binding,Combobox,我有一个Windows窗体应用程序,其中一个窗体有两个组合框e,它们都绑定到我通过实体框架映射的对象的同一个绑定列表 Form\u Load事件调用以下内容: private void SetFacilityDropdowns() { dbContext.Facilities.Load(); var bindingSource = dbContext.Facilities.Local.ToBindingList(); Dictionary<ComboBox, str
组合框
e,它们都绑定到我通过实体框架映射的对象的同一个绑定列表
Form\u Load
事件调用以下内容:
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);
}
一切看起来都很好,ComboBox
es似乎都包含了我所期望的所有项目。但是,Facility
表中有一些Facility
对象,其中FacilityName
属性为null
。这在组合框中显示为空字符串,尽管我不知道它是否仅以这种方式显示,或者在绑定时是否转换
通常,当我更改FacilityName
下拉列表时,FacilityId
下拉列表将更改为其匹配值。但是,当我将FacilityName
更改为null/空字符串值之一时,会抛出NullReferenceException
。它似乎是由Windows窗体UI线程引发的,因此我无法在任何组合框
“已更改”事件中设置断点,因为在触发任何事件之前会引发异常
知道为什么会这样吗
编辑:
以下是堆栈跟踪:
> 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]
引发的异常如下所示:
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;
}
}
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)
您可以尝试使用IntelliTrace获取更多信息?您的主要异常显然是
System.NullReferenceException对象引用未设置为对象的实例。System.Windows.Forms.ComboBox.get_Text()中的System.String get_Text()
这让我相信您的combobox试图将DisplayMember
属性设置为空值。由于您自己说过,您不确定从数据库返回的空列在Facility
类中是否表示为空字符串或null,因此您可以在getter中明确地转换它们。此外,如果要向FacilityID属性传递一个可为null的值,则需要将其转换为int,以便combobox可以处理它
所以,在你的设施中
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};
}
}
使用此选项,您将确保您的控件永远不会尝试绑定到空值,并且它将消除异常。您可以显示stacktrace吗?刚刚添加了调用堆栈和异常消息。然后绑定一个没有空项(即空值)的列表或ObservableCollection到组合框。@RaviPatel然后我失去了将两个组合框链接在一起的能力,因此当我更改一个组合框时,另一个组合框也会相应地更改。@Douglas Barbin,但是您可以将两个组合框绑定到同一个集合。因此,如果集合更改,两个组合框都将相应更改。Facility
是一个由实体框架自动生成的类。您可以更改此类的行为以确保不返回空值吗?我可以,这实际上是可行的。我将尝试一些方法,然后返回结果。好的,这解决了异常问题,但引入了一个新的异常。当我选择一个空值时,另一个下拉列表中的伴随值变为System.Data.Entity.DynamicProxies.Facility_F4B14BF33FD7C299E70286AAFB2DE3802F40B0A50A6BF0EFD80BD6C4385597B6
(或结尾的其他长十六进制字符串),而不是正确的FacilityId
值。我将此标记为答案,因为它删除了异常。