|
-
Aug 12th, 2021, 01:36 PM
#1
Value does not fall within the expected range.
I've run into a problem I'm having a hard time getting a purchase on, so I thought I'd ask here.
I have a very simple form that has nothing but a listbox and two buttons. In the constructor, I query a DB to get some values into a datatable, then bind that to the listbox. I then go through the datatable to see whether or not a stored value happens to be in there, and if it does, I set that to be the selected item in the listbox.
What I've found is that, if the table in the DB is empty, then I get the error that is the subject of this thread (Value does not fall within the expected range.) at some point during setup. This doesn't happen during the constructor when all the work I described is done. The datatable comes back with no rows, it gets bound to the listbox, the code then tries to find that selected value in the rows, but there are no rows, so it doesn't find it. All that is as it should be.
Following the constructor, there is something utterly trivial in the Load event handler. All I am doing is checking a Boolean value and showing a message if it is false. That works as expected, too. The Boolean is true, the messagebox doesn't show, execution steps to the End If....and the next thing that happens is the error message.
There is nothing in the Shown event handler, and there is no code that I wrote between the end of the Load handler and when the error shows up. For that matter, there is barely any more code in the whole form, as all that is happening is that the user makes a choice from the listbox, then the form goes away.
One thing I did to test this out is to put a record into the table that is queried, and the form then works as expected. That shows that this error has something to do with the fact that the datatable bound to the listbox has no rows, but it doesn't really suggest much to me for a solution. Technically, with no choices available, the form is kind of pointless, so there are ways to get around the problem. Still, there are times when that table will have no rows, and I'm curious as to what is causing this error. It isn't at all clear to me why this particular error would result from this situation. Which value? What range? If there is something wrong with binding an empty datatable to a listbox, there shouldn't be, and why this error anyways?
The one thing that seems possible is that the value member in the binding is set to a column in the datatable that should hold GUIDs, though there is no indication that the field should be any particular type.
Any suggestions as to what is causing the error?
My usual boring signature: Nothing
 
-
Aug 12th, 2021, 01:49 PM
#2
Re: Value does not fall within the expected range.
Can you post the constructor code?
There maybe something in there.
-tg
-
Aug 12th, 2021, 02:29 PM
#3
Re: Value does not fall within the expected range.
Sure, but keep in mind that the error doesn't happen in the constructor, and I even get through the Load event before the problem shows up:
Code:
mNotNow = True
' This call is required by the designer.
InitializeComponent()
mHatchID = HatcheryID
' Add any initialization after the InitializeComponent() call.
Using lcon As New SqlClient.SqlConnection(globalERaiser.IDAL.CommonConnectionString)
Using da As New SqlClient.SqlDataAdapter
Using cmd As SqlClient.SqlCommand = lcon.CreateCommand
Try
lcon.Open()
da.SelectCommand = cmd
cmd.CommandText = "SELECT HatcheryID,Hatchery FROM Core.HATCH_Hatchery"
da.Fill(mDT)
Catch ex As SqlClient.SqlException
mErrors.AddString("ERROR Filling Hatchery Table: " & ex.Message, ex)
mImValid = False
Return
Catch ex As Exception
mErrors.AddString("ERROR Filling Hatchery Table: " & ex.Message, ex)
mImValid = False
Return
End Try
End Using
End Using
End Using
mImValid = True
lbHatch.DataSource = mDT
lbHatch.DisplayMember = "Hatchery"
lbHatch.ValueMember = "HatcheryID"
Me.lbHatch.SelectedIndex = -1
For x = 0 To Me.lbHatch.Items.Count - 1
If DirectCast(CType(Me.lbHatch.Items(x), DataRowView).Item("HatcheryID"), Guid) = mHatchID Then
Me.lbHatch.SelectedIndex = x
End If
Next
mNotNow = False
By the way, in the meantime, I decided that it doesn't make sense for the table to be empty, so the underlying problem has been solved, but I'm still curious as to why this particular error happened and what caused it.
My usual boring signature: Nothing
 
-
Aug 12th, 2021, 04:07 PM
#4
Re: Value does not fall within the expected range.
Yeah, but the form doesn't actually RENDER until it's shown... So you can actually do some conjigggery to the list and the problems don't show up until later.
Code:
lbHatch.DataSource = mDT
lbHatch.DisplayMember = "Hatchery"
lbHatch.ValueMember = "HatcheryID"
Me.lbHatch.SelectedIndex = -1
For x = 0 To Me.lbHatch.Items.Count - 1
If DirectCast(CType(Me.lbHatch.Items(x), DataRowView).Item("HatcheryID"), Guid) = mHatchID Then
Me.lbHatch.SelectedIndex = x
End If
Next
Two things, the first of which shouldn't have impact, but you should set the .ValueMember and .DisplayMember first, then the .DataSource - with data tables it's largely irrelevant, but sometimes it matters (altho agin, it's not something germain to this issue, just one of those things that triggers my CDO.)
Second... the bits marked in red... I'm curious what would happen if you were to comment those out and feed it an empty table... do you still get the error or not? (I'm not in an environment where I can check this stuff out myself). But to me that spot seems the most likely candidate... why? I don't know.
-tg
-
Aug 12th, 2021, 05:52 PM
#5
Re: Value does not fall within the expected range.
You're right. There are reasons to believe I wrote that code a LONG time back. I recognize some style changes I have made, and that is one of them. In this case, it makes no difference at all. The difference it might make is performance, but....that table will likely never have more than two records, so performance...meh. Furthermore, it happens when performance doesn't matter anyways. Still, it's a good point and I'll change it around.
That part in red seemed like the most likely candidate to me, too, except that the table will have no rows when empty, so the loop will run 0 times, which means that the red line is this:
Me.lbHatch.SelectedIndex = -1
Could that EVER cause such an error? I would think not. However, if you bind to a datatable, then VS tries to set the first row as the selected index. In this case, there is no first row...or any other, so that might cause trouble.
Commenting that whole section out had no impact, but getting the code back to a state where I COULD comment that out revealed a bug that I will need to address, so that was a positive development.
My usual boring signature: Nothing
 
-
Aug 12th, 2021, 08:24 PM
#6
Re: Value does not fall within the expected range.
Can we see the stack trace of the exception?
As for that constructor code, I'd change this:
vb.net Code:
lbHatch.DataSource = mDT
lbHatch.DisplayMember = "Hatchery"
lbHatch.ValueMember = "HatcheryID"
Me.lbHatch.SelectedIndex = -1
For x = 0 To Me.lbHatch.Items.Count - 1
If DirectCast(CType(Me.lbHatch.Items(x), DataRowView).Item("HatcheryID"), Guid) = mHatchID Then
Me.lbHatch.SelectedIndex = x
End If
Next
to this:
vb.net Code:
lbHatch.DisplayMember = "Hatchery"
lbHatch.ValueMember = "HatcheryID"
lbHatch.DataSource = mDT
Me.lbHatch.SelectedItem = mDT.DefaultView.Cast(Of DataRowView)().FirstOrDefault(Function(drv) DirectCast(drv("HatcheryID"), Guid) = mHatchID)
FirstOrDefault will return a matching item if there is one or Nothing if there isn't and that is then assigned to SelectedItem.
-
Aug 12th, 2021, 09:50 PM
#7
Re: Value does not fall within the expected range.
 Originally Posted by jmcilhinney
FirstOrDefault will return a matching item if there is one or Nothing if there isn't and that is then assigned to SelectedItem.
My guess was that it had something to do with setting the SelectedIndex, but when I went to the documentation there wasn't any indication that the specific exception would be thrown so I double guessed myself. I'm curious if Shaggy implements your solution and no longer gets the exception.
So basically I have nothing to add other than I'm curious as to how this turns out.
-
Aug 12th, 2021, 10:08 PM
#8
Re: Value does not fall within the expected range.
 Originally Posted by jmcilhinney
vb.net Code:
lbHatch.DisplayMember = "Hatchery"
lbHatch.ValueMember = "HatcheryID"
lbHatch.DataSource = mDT
Me.lbHatch.SelectedItem = mDT.DefaultView.Cast(Of DataRowView)().FirstOrDefault(Function(drv) DirectCast(drv("HatcheryID"), Guid) = mHatchID)
I guess you could also use:
vb.net Code:
lbHatch.Items.Cast(Of DataRowView)()
instead of:
vb.net Code:
mDT.DefaultView.Cast(Of DataRowView)()
as the items are the same objects.
-
Aug 13th, 2021, 09:28 AM
#9
Re: Value does not fall within the expected range.
Is there any reason to think that any of those changes would impact the error in question? After all, it doesn't happen early on, and removing that entire block of code has no impact on the error.
In general, I've been reluctant to use LINQ in this project, though my objection doesn't stand in this particular case. Much of this program consists of models that will be exposed via interfaces for the use of others. I have no idea how efficient those others will be, nor any control on that, so I squeezed as much speed as I could out of the models, which included squeezing out all LINQ. However, this particular block of code is not part of any model, and is nothing more than a very rarely frequented form that might show up on startup under just the right circumstances, so I can do whatever I want with this part.
Here are a couple points:
When I look at the exception details, the StackTrace is Nothing. However, this is the stack trace at the time the exception happens:
System.Windows.Forms.dll!System.Windows.Forms.AccessibleObject.Accessibility.IAccessible.get_accChil d(object childID) Unknown
System.Windows.Forms.dll!System.Windows.Forms.InternalAccessibleObject.System.Windows.Forms.UnsafeNa tiveMethods.IAccessibleInternal.get_accChild(object childID) Unknown
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DefWndProc(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.DefWndProc(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.WmSetFocus(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.WndProc(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.ListBox.WndProc(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) Unknown
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.ContainerControl.FocusActiveControlInternal() Unknown
System.Windows.Forms.dll!System.Windows.Forms.Form.Active.set(bool value) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Form.WmActivate(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Form.WndProc(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.OnMessage(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.ControlNativeWindow.WndProc(ref System.Windows.Forms.Message m) Unknown
System.Windows.Forms.dll!System.Windows.Forms.NativeWindow.DebuggableCallback(System.IntPtr hWnd, int msg, System.IntPtr wparam, System.IntPtr lparam) Unknown
[Native to Managed Transition]
[Managed to Native Transition]
System.Windows.Forms.dll!System.Windows.Forms.Control.SetVisibleCore(bool value) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Form.SetVisibleCore(bool value) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Control.Visible.set(bool value) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(int reason, System.Windows.Forms.ApplicationContext context) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Application.ThreadContext.RunMessageLoop(int reason, System.Windows.Forms.ApplicationContext context) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Application.RunDialog(System.Windows.Forms.Form form) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Form.ShowDialog(System.Windows.Forms.IWin32Window owner) Unknown
System.Windows.Forms.dll!System.Windows.Forms.Form.ShowDialog() Unknown
> HIS.exe!HIS.StartUpForm.FinishSetup() Line 114 Basic
The very bottom line of that is the method that shows the form (FinishSetup()).
I'm about to head out to a beautiful mountain stream in one of the most scenic places in the world, to stagger through a meadow along the banks of said stream for the purpose of counting spawning salmon. I'll be back in eight hours, or so, but out of communication until then.
My usual boring signature: Nothing
 
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|