ScrollBar Exception...

B

Beebs

I'm using the code at the end of this post to display a scrollbar on a
form when the SIP is launched by the user. I'm using VS 2003 and
writing this in VB.NET. I keep getting the following error:

An unhandled exception of type 'System.ObjectDisposedException'
occurred in System.Windows.Forms.dll

on this line of code:

VScrollBar1.Visible = True (in the Sub SetupScrollBar function)

Can anyone tell me why this is possibly happening? The name of the
scrollbar is correct, so I know that isn't the problem.

CODE:

Sub SetupScrollBar()
If (G_SIP = True) Then 'Define the size of the scrollbar
VScrollBar1.Visible = True
VScrollBar1.Height = MINSCROLLSIZE 'Set size of scrollbar
VScrollBar1.Maximum = Panel1.Height - MINSCROLLSIZE 'The
maximum scroll value places bottom of frame at bottom of screen
Else
VScrollBar1.Visible = False 'Hide the scrollbar, SIP isn't
showing
VScrollBar1.Value = 0
'Place the panel at the very top boundaries of the form
Panel1.Left = 0
Panel1.Top = 0
End If

VScrollBar1.Minimum = 0 'Set minimum to zero

'Set our increments to be ratio of current maximums
VScrollBar1.SmallChange = VScrollBar1.Maximum / 100
VScrollBar1.LargeChange = VScrollBar1.Maximum / 10
End Sub

Private Sub VScrollBar1_ValueChanged(ByVal sender As Object, ByVal
e As System.EventArgs) Handles VScrollBar1.ValueChanged
'On scroll bar change move the frame w/r to the form
Panel1.Left = 0
Panel1.Top = -VScrollBar1.Value
End Sub

Private Sub InputPanel1_EnabledChanged(ByVal sender As Object,
ByVal e As System.EventArgs) Handles InputPanel1.EnabledChanged
If InputPanel1.Enabled = True Then
G_SIP = True 'SIP is showing
Else
G_SIP = False 'SIP isn't showing
End If
SetupScrollBar()
End Sub
 
R

Richard Thombs

Beebs, I had a similar problem, and it turned out to be the event
handler for the SIP. What I discovered was that even though you can
create as many InputPanel objects as you want, they all end up
referring back to a single instane. This lead to that instance having a
really long chain of event handlers attached to it, because every time
I created an InputPanel object, I'd then add another delegate to the
EnableChanged event. Some of these event handlers were for forms that
had indeed been disposed, hence the error.

I hope this helps you. In my code I fixed it by reworking my classes so
that I would only ever attempt to create a single instance of the
InputPanel object which I shared throughout my code.

Richard.
 
B

Beebs

Can you give me an example of how you did that in your code. I
believe what you're telling me is what is happening cause when VS
throws the error, and I keep pressing the continue button, it throws
an error on the same line in every class, the exact same line...
 
R

Richard Thombs

Okay, looking through the modifications I made, I wasn't strictly
accurate in what I told you in my previous post.

My problem was that I had a form with a tab control in it, and every
page in the tab would turn the SIP on/off and so needed a reference to
an InputPanel object.

In the first version of the code, I would simply create a new
InputPanel object and add an event handler. When debugging the problems
I started to have, I realised that there was just a single InputPanel
object (when you create a new InputPanel object you just get a
reference to the global one), and so I was creating this long chain of
event handlers.

However, when my form was closed, the instance of the class which
implemented the event handler got disposed automatically, but the
reference to the event handler still in the InputPanel's delegate list,
hence getting ObjectDisposed exceptions.

My solution was to implement the IDisposable interface and ensure that
I removed the event handler reference for each tab page:

public class ScrollableTabPage : TabPageEx
{
protected Microsoft.WindowsCE.Forms.InputPanel sip;
protected EventHandler sipEnabledHandler;

public ScrollableTabPage()
{
sip=new Microsoft.WindowsCE.Forms.InputPanel();
sipEnabledHandler=new EventHandler(sip_EnabledChanged);
sip.EnabledChanged+=sipEnabledHandler;
}

protected override void Dispose(bool disposing)
{
sip.EnabledChanged-=sipEnabledHandler;
base.Dispose (disposing);
}
}
 
B

Beebs

Could I just place this type of code in each one of my form's classes,
or am I missing something?
 
R

Richard Thombs

Not this exact code, no.

But if (and it's a big if) you are having the same problem I was, then
similar code will work for you.

Essentially, every time a class of yours creates an instance of the
InputPanel class and adds a handler to the EnabledChanged event, you
need to make sure that you remove that event when your class is
disposed.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top