469,623 Members | 1,683 Online
Bytes | Developer Community
New Post

Home Posts Topics Members FAQ

Post your question to a community of 469,623 developers. It's quick & easy.

Find.Closing Event & CancelEventArgs

In VB 6, the Form_QueryUnload event had an UnloadMode parameter that let me
find out *why* a form is unloading, and then conditionally cancel the event.

In VB.NET, the Closing event passes a CancelEventArgs that lets me cancel
the Close() operation, but is there still any way to find out *why* a form
is closing?

This app as a form that needs to be loaded at startup, closed only at
shutdown, and then Show() / Hide() for the user. If the user clicks the [X]
button on the form's title bar, I want to intercept this and Hide() it
instead.

--
Peace & happy computing,

Mike Labosh, MCSD MCT
Owner, vbSensei.Com
"Escriba coda ergo sum." -- vbSensei
Nov 20 '05 #1
5 2728
Nevermind. I finally found my answer after a whole bunch of full-text
searching:

"In Visual Basic 6.0, QueryUnload took two arguments, Cancel and UnloadMode.
In Visual Basic .NET, Cancel can be replaced by using
System.ComponentModel.CancelEventArgs.Cancel. There is no replacement for
UnloadMode."

That sucks.

--
Peace & happy computing,

Mike Labosh, MCSD MCT
Owner, vbSensei.Com
"Escriba coda ergo sum." -- vbSensei
Nov 20 '05 #2
* "Mike Labosh" <ml*****************@vbsensei.com> scripsit:
Nevermind. I finally found my answer after a whole bunch of full-text
searching:

"In Visual Basic 6.0, QueryUnload took two arguments, Cancel and UnloadMode.
In Visual Basic .NET, Cancel can be replaced by using
System.ComponentModel.CancelEventArgs.Cancel. There is no replacement for
UnloadMode."


Determine a Form's UnloadMode
<http://www.fawcette.com/archives/premier/mgznarch/vbpj/2001/11nov01/qa0111/qa0111.asp>

--
Herfried K. Wagner [MVP]
<http://www.mvps.org/dotnet>
Nov 20 '05 #3
> Determine a Form's UnloadMode
<http://www.fawcette.com/archives/pre...1nov01/qa0111/
qa0111.asp>

Cool Tip!

OK, that has some pretty cool hack value, but I was looking for the
politically correct .NET way of doing it. See, there is a reason they
ripped out the UnloadMode feature, so I'm happy with that. Although
subclassing Form to add the functionality would work, subclassing should
never ever be done arbitrarily like that, because it leads to bad design and
maintenance problems [see Design Patterns by GoF]

For the particular problem I am trying to solve, I think I found a more
elegant way. I have this dialog with some functionality in it that I wanted
to be able to use inside the dialog, as well as silently in the application.
If I move the functionality back to the main application, then the main
application can Show() and Close() the dialog at will instead of being a
memory hog, use the functionality silently, and for the sake of the user
using the dialog to do it, the main app can pass either an Interface or a
Delegate to the dialog's constructor. I think this is the better way in
this case, because it has a more flexible and robust design.
--
Peace & happy computing,

Mike Labosh, MCSD MCT
Owner, vbSensei.Com
"Escriba coda ergo sum." -- vbSensei
"Herfried K. Wagner [MVP]" <hi***************@gmx.at> wrote in message
news:br*************@ID-208219.news.uni-berlin.de... * "Mike Labosh" <ml*****************@vbsensei.com> scripsit:
Nevermind. I finally found my answer after a whole bunch of full-text
searching:

"In Visual Basic 6.0, QueryUnload took two arguments, Cancel and UnloadMode. In Visual Basic .NET, Cancel can be replaced by using
System.ComponentModel.CancelEventArgs.Cancel. There is no replacement for UnloadMode."

--
Herfried K. Wagner [MVP]
<http://www.mvps.org/dotnet>

Nov 20 '05 #4
On Tue, 9 Dec 2003 17:25:30 -0500, Mike Labosh wrote:
OK, that has some pretty cool hack value, but I was looking for the
politically correct .NET way of doing it. See, there is a reason they
I'm not sure I agree that this is a hack. All that article is doing is
overriding a base method of the form class. It seems very OO to me.
subclassing Form to add the functionality would work, subclassing should
never ever be done arbitrarily like that, because it leads to bad design and
Just by creating any form you are subclassing the base form and creating
your own class. Why is that bad design? Just curious on your thoughts on
this question.

For the particular problem I am trying to solve, I think I found a more
elegant way. I have this dialog with some functionality in it that I wanted


I'm glad you found a good solution.

Cheers

--
Chris

To send me an E-mail, remove the underscores and lunchmeat from my E-Mail
address.
Nov 20 '05 #5
First, this turned out to be way longer than I had intended. But that's for
my benefit as well as anyone else that is also from a classic VB (non-OO)
background. Composing this reply has really focused my mind on design
issues. :)
OK, that has some pretty cool hack value, but I was looking for the
politically correct .NET way of doing it. See, there is a reason they
I'm not sure I agree that this is a hack. All that article is doing is
overriding a base method of the form class. It seems very OO to me.


I wouldn't quite call it a hack either. I said it had "hack value", as in
it's an interesting thing to read and experiment with.
subclassing Form to add the functionality would work, subclassing should
never ever be done arbitrarily like that, because it leads to bad design

and
Just by creating any form you are subclassing the base form and creating
your own class. Why is that bad design? Just curious on your thoughts on
this question.

Subclassing is not bad design. Subclassing arbitrarily to add or change one
feature *can lead to* bad design. For example, suppose I design a subclass
of Windows.Forms.Form that adds this single feature. I would likely wind up
using it as a base from which to build lots of different forms in different
applications:

QueryUnloadForm Inherits Windows.Forms.Form

Then, let's say I want to add another embellishment or feature later on that
I can use independently, and does not make use of this QueryUnload thing.
That would be another subclass of Windows.Forms.Form that I would likely
wind up using as a base from which to derive many other forms in different
applications.

EmbellishedForm Inherits Windows.Forms.Form

Sooner or later, I am going to want to use one of those that ALSO has the
QueryUnload feature. Since we don't have multiple inheritance, I couldn't
make a form deriving from both:

EmbellishedQueryUnloadForm Inherits Windows.Forms.Form

As you can see, as the number of customizations increases, there is an
explosion of subclasses of Form, because of the presumed need to have a Form
subclass for each possible combination of customizations.

Although code reuse is a benefit of inheritance, it is not the true power.
The true power of inheritance is that a client can treat subclasses
uniformly, so that application code is less cumbersome, less
"straight-down", and less brute-force, and therefore, easier to maintain.
Plus, the sibling subclasses get to share common parent implementation code.
This type of polymorphism is vastly superior to that filthy hack that VB5 &
VB6 called Interface Polymorphism.

The context here is a Notepad application as a real world design /
implementation sample case study for students. The project is highly
focused on best practices, not just banging out an app, and it is intended
to be of good design, not just simply functional.

The problem at hand was how to implement the Edit->Find functionality in a
way that yields great design. See, if I put the implementation of the text
searching inside the find dialog, then how should the application implement
the Edit ->FindNext menu command, which invokes the find feature silently
(without displaying the dialog) to find the next occurance of something the
user already searched for? My first thought was to put the searching
algorithm inside the Find class (the dialog). If the user needs to display
the form in Edit-> Find and the application needs to borrow it from
Edit->FindNext, I need a uniform way of treating the dialog. My next
thought was to have the Notebook class (main form) hold a private instance
of Find, passing its constructor a reference to the TextBox on the Notebook
form:

Private _find As New Find(txt)

At first glance, this would free me to have Find implement the QueryUnload /
UnloadMode thing. But that's not clean enough, because now the Find class
is wired to the Notebook class by the control it's hooked up to. The Find
class is now no longer portable between other apps, and it still doesn't
lend itself to be flexible enough to Find other things besides text.

So here is the solution that offers a flexible, less tighty coupled, more
portable, more maintainable design. The Find class defines a delegate for
generic searching. FindNExtHandler's interface allows for text-search,
database search, or whatever. Below that, the Notebook class (main
application) implements the specific searching algorithm that is appropriate
for the nature of itself as the application. When the application needs to
do a search, it passes a Delegate (typesafe function pointer) of it's own
FindNext implementation to the Find dialog's Constructor. The find dialog
then invokes the delegate when the user clicks a button. If the user then
clicks Edit->FindNext, The application can call its own method directly.

If I had used inheritance to solve this problem, I easily could have ended
up with a zoo of subclasses: SearchableForm, FindForm, QueryUnloadableForm,
SearchableQueryUnloadableForm, etc...

Here, I have two classes, not a fistful of them. Inheritance is an "OO"
technique, but just because an application uses lots of subclassing, it does
not, however, imply that the application has good design. When I mentioned
in the previous post that arbitrary subclassing can turn into problems, this
what I was on about. Inheritance heirarchies need to be carefully and
thoughtfully planned so that features can be added or customized after the
fact, without the need to disturb existing code, and to not have side
effects.

The resulting advantages:

Find.vb
Is portable because it is not married to this application.
Is flexible because it is not married to this search implementation
Doesn't care who is using it or what is being searched.
Doesn't have to expose unnecessary (sp?) stuff

Notebook.vb
Can supply whatever search it wants and pass a function pointer.
Doesn't care what the Find box looks like or how it works.
Doesn't have to share any unnecessary (sp?) stuff

Public Class Find
Inherits Windows.Forms.Form

Public Delegate Sub FindNextHandler( _
ByVal startPos As Integer, _
ByVal searchFor As String, _
ByVal matchCase As Boolean, _
ByVal down As Boolean)

Private _findNext As FindNextHandler
Private _caretPos As Integer

Sub New(ByVal findNext As FindNextHandler, caretPos As Integer)

Me.New()

_findNext = findNext
_caretPos = caretPos

End Sub

Private Sub btnCancel_Click(...) Handles btnCancel.Click
Close()
End Sub

Private Sub btnFindNext_Click(...) Handles btnFindNext.Click

_findNext.Invoke(_caretPos, txtFind.Text, _
chkMatchCase.Checked, radDown.Checked)

End Sub
....
End Class

Public Class Notebook

Private _findText As String
Private _findCase As Boolean
Private _findDown As Boolean
Private _findPos As Integer

Friend Sub FindNext( _
ByVal startPos As Integer, _
ByVal searchFor As String, _
ByVal matchCase As Boolean, _
ByVal down As Boolean)

'Actual implementation of the Text Search

End Sub

Private Sub mnuEditFind_Click(...) Handles mnuEditFind.Click

'Display the Find dialog, passing it a pointer to FindNext()
'and the current location of the caret within the text.

Dim start As Integer = Math.Max(txt.SelectionStart, 1)
Dim f As New Find(AddressOf FindNext, start)

f.Show()

End Sub

Private Sub mnuEditFindNext_Click(...) Handles mnuEditFindNext.Click
FindNext(_findPos, _findText, _findCase, _findDown)
End Sub
....
End Class

--
Peace & happy computing,

Mike Labosh, MCSD MCT
Owner, vbSensei.Com
"Escriba coda ergo sum." -- vbSensei
Nov 20 '05 #6

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

5 posts views Thread by Ron L | last post: by
4 posts views Thread by Gas | last post: by
6 posts views Thread by Al the programmer | last post: by
7 posts views Thread by Geoff Olding | last post: by
4 posts views Thread by Amalorpavanathan Y \(Amal\) | last post: by
2 posts views Thread by chris in grimsby | last post: by
reply views Thread by devrayhaan | last post: by
By using this site, you agree to our Privacy Policy and Terms of Use.