How to Prevent the Click Event when a Button is Clicked

  • Thread starter Thread starter Charles Law
  • Start date Start date
C

Charles Law

When I click a button I don't want the click event to fire. Is this
possible?

In fact, what I would really like is to be able to intercept the click
event, perform some action, and then prevent the click from passing through
to the button.

Any help or suggestions much appreciated.

Charles
 
Why don't you just remove or condition the code from the Click event?

The button will do nothing by itself.
 
Hi Klaus

I actually have a lot of buttons, and text boxes, and dropdowns, and so on
that I want to do this for. To condition the code in every single one would
be tedious and repetitive.

I am really looking for the principle so that I can apply it to other types
of control as well. For example, I also want to prevent a dropdown from
dropping down, and prevent the button from appearing depressed when it is
clicked. In a nutshell, I want the control to behave like it never got the
click / mouse down event.

Charles
 
Well that's possible, you can simply inherit from the control itself and
make it do anything you want.

For example, you could put some code in the OnClick method and so your stuff
there and prevent things from bubbling up to the container.

But that assumes that you started there - it's going to be hard to retrofit
to your existing code, especially if you have a lot of it.
 
Hi Charles,

Seems like you want to create your own Control-Classes.

Do something like:

Namespace Law
Public Class myButton
Inherits System.Windows.Forms.Button

' Add your code


Namespace Law
Public Class myComboBox
Inherits System.Windows.Forms.ComboBox

' Add your code



Of course you have to fill in the details yourself, use attirbutes, etc.....

HTH,

Michael
 
When I click a button I don't want the click event to fire. Is this
possible?

No. If there's an event handler, the event will fire.
In fact, what I would really like is to be able to intercept the click
event, perform some action, and then prevent the click from passing through
to the button.

The click can "pass through" to the button all day long and nothing will
happen other than it will appear pressed and then unpressed. That's all the
button will do on its own. If you don't want YOUR CODE executed when a Click
event occurs, write more code to detect this condition and then simply DON'T
EXECUTE your code.
 
* "Charles Law said:
When I click a button I don't want the click event to fire. Is this
possible?

In fact, what I would really like is to be able to intercept the click
event, perform some action, and then prevent the click from passing through
to the button.

\\\
Imports System
Imports System.Windows.Forms

Public Class UserControl1
Inherits Button

Private m_Clickable As Boolean

Public Property Clickable() As Boolean
Get
Return m_Clickable
End Get
Set(ByVal Value As Boolean)
m_Clickable = Value
End Set
End Property

Protected Overrides Sub OnClick(ByVal e As EventArgs)
If Me.Clickable Then
MyBase.OnClick(e)
End If
End Sub
End Class
///

Then you can use this button instead of the standard Windows Forms
button. One possible extension would be to provide a 'BeforeClick'
event that passes in a 'BeforeClickEventArgs' object that provides a
'Cancel' property. If the event is handled and 'Cancel' is set to
'True', the 'Click' event would not be raised.

The code above will extend the standard button with a 'Clickable'
property. If this property is set to 'False', the 'Click' event won't
fire.
 
Thanks again Klaus.

Along with the other responses, I think everyone is pointing in the same
direction: basically, I have to create my own control and inherit from
button, etc. As you suggest, though, I'm not starting from there, and retro
fitting is not really an option.

Ho hum.

Charles
 
Hi Michael

Seems like I *don't* really want to create my own class, but it seems that
it is my only option :-(

There has to be another way, doesn't there?

Charles
 
Hi Jeff

As I mentioned, I have a lot of controls already, and retro-fitting
conditional code will be problematic. I even favour the inheritance route at
this stage, but I'm not happy.

But, I will persevere.

Charles
 
Hi Herfried

I was beginning to think I had become invisible. I seem to have a lot of
posts unanswered at the moment - I don't suppose you would care to take a
look?

Anyway, back to the point. A good solution if I had started from there, but
as you may have gathered from my other replies, I haven't.

I wonder how the IDE does it, or SharpDevelop, for that matter. I have
looked at their code but I will never find it in there; there's loads of it.

There must be a way, surely, of intercepting the mouse events, or by using
an API?

Charles
 
Charles,
Have you considered placing a window (control) over the top of your control
that shows the original control, but this second control eats all the mouse
clicks?

Unfortunately I don't have a good .NET example of how to do this, maybe a
Transparent or opaque control will do it...

Hope this helps
Jay
 
Hi Jay

Yes, I had as it happens, but we all know how good GDI+ is at doing
transparent. ;-)

I think that this is by far the best solution because it takes care of
absolutely everything underneath by masking it. If only there was a control
that I could use, that would show the stuff below, but, as you say, eat the
mouse clicks.

Do you have one in mind?

Charles
 
Charles,
As I stated I do not have an example!

The closest I think of is to create a form and change the Form.Opacity value
to 0. Place this second form over the first, this second form will get all
the mouse clicks...

However as I stated I DO NOT have an working example!

Ideally you want a control that does not paint ANYTHING, so the window below
it shows through...

Hope this helps
Jay
 
Charles,

* "Charles Law said:
I was beginning to think I had become invisible. I seem to have a lot of
posts unanswered at the moment - I don't suppose you would care to take a
look?

Anyway, back to the point. A good solution if I had started from there, but
as you may have gathered from my other replies, I haven't.

I wonder how the IDE does it, or SharpDevelop, for that matter. I have
looked at their code but I will never find it in there; there's loads of it.

\\\
Imports System
Imports System.Windows.Forms

Public Class UserControl1
Inherits Control

Private Declare Auto Function GetWindowLong Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal nIndex As Int32) As Int32
Private Declare Auto Function SetWindowLong Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal nIndex As Int32, ByVal dwNewLong As Int32) As Int32

Private Const GWL_EXSTYLE As Int32 = -20
Private Const WS_EX_TRANSPARENT As Int32 = &H20

Public Sub New()
SetStyle(ControlStyles.SupportsTransparentBackColor, True)
Me.BackColor = Color.Transparent
End Sub

Protected Overrides Sub OnHandleCreated(ByVal e As EventArgs)
Dim nStyle As Int32 = GetWindowLong(Me.Handle, GWL_EXSTYLE)
nStyle = nStyle Or WS_EX_TRANSPARENT
Call SetWindowLong(Me.Handle, GWL_EXSTYLE, nStyle)
End Sub

Protected Overrides Sub OnPaintBackground(ByVal pevent As PaintEventArgs)
'
End Sub
End Class
///

Add an instance of this class to your form's controls and place it in
front of all other controls.
 
Herfried. I'm all out of superlatives, so a simple thank you. A fine answer.

Charles


Herfried K. Wagner said:
Charles,

it.

\\\
Imports System
Imports System.Windows.Forms

Public Class UserControl1
Inherits Control

Private Declare Auto Function GetWindowLong Lib "user32.dll" (ByVal
hWnd As IntPtr, ByVal nIndex As Int32) As Int32
Private Declare Auto Function SetWindowLong Lib "user32.dll" (ByVal
hWnd As IntPtr, ByVal nIndex As Int32, ByVal dwNewLong As Int32) As Int32
 
No need for Interop.

\\\
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or WS_EX_TRANSPARENT
Return cp
End Get
End Property
///
 
Hi Mick

Which bit does this replace, or does it replace it all?

Charles


"Mick Doherty"
 
Hi Charles

This method does not improve on Herfrieds, it just does away with InterOp.
The Class will look as follows:

\\\
Public Class UserControl1
Inherits UserControl

Private Const WS_EX_TRANSPARENT As Int32 = &H20

Public Sub New()
SetStyle(ControlStyles.SupportsTransparentBackColor, True)
Me.BackColor = Color.Transparent
End Sub

Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or WS_EX_TRANSPARENT
Return cp
End Get
End Property

Protected Overrides Sub OnPaintBackground(ByVal pevent As
PaintEventArgs)
'
End Sub

End Class
///
 
* "Mick Doherty said:
No need for Interop.

\\\
Protected Overrides ReadOnly Property CreateParams() As CreateParams
Get
Dim cp As CreateParams = MyBase.CreateParams
cp.ExStyle = cp.ExStyle Or WS_EX_TRANSPARENT
Return cp
End Get
End Property
///

That's the better solution, indeed.
 
Back
Top