-
Dec 18th, 2017, 03:12 PM
#1
Thread Starter
PowerPoster
[RESOLVED] Setting e.SuppressKey = True in called Procedure?
I have a windows application in which a need has arisen to not disable all ComboBoxes on a Winform but essentially make it ReadOnly. Since a ComboBox does not have a ReadOnly property, I've created a routine where I pass in the ComboBox and the "e" parameter sets the SuppressKey = True. My problem is, and I know this is probably elementary, but I just don't know. How do I declare a variable of KeyEventArgs so I can pass it into the routine? Below is my routine.
Code:
Public Sub cmbSuppressKey(sender As Object, e As KeyEventArgs)
Dim cmb As ComboBox = DirectCast(sender, ComboBox)
Try
EH.ErrorMessage = String.Empty
e.SuppressKeyPress = True
Catch ex As Exception
EH.ErrorMessage = "cmbSuppressKey() - " & ex.Message & "...Contact Software Engineering!" & "~E"
End Try
End Sub
Thanks
-
Dec 18th, 2017, 03:33 PM
#2
Re: Setting e.SuppressKey = True in called Procedure?
Just wondering why you don't just handle the keypress event or set the Enabled property to False.
-
Dec 18th, 2017, 03:53 PM
#3
Thread Starter
PowerPoster
Re: Setting e.SuppressKey = True in called Procedure?
Setting the enable property to true changes the color of the lettering. The customer wants to be able to see the control as if it were in edit mode. As far as the KeyDown Event, I'm passing multiple ComboBox controls to this. If there is a better way, believe me, I'm all ears!
-
Dec 18th, 2017, 04:02 PM
#4
Re: Setting e.SuppressKey = True in called Procedure?
Originally Posted by blakemckenna
I have a windows application in which a need has arisen to not disable all ComboBoxes on a Winform but essentially make it ReadOnly. Since a ComboBox does not have a ReadOnly property, I've created a routine where I pass in the ComboBox and the "e" parameter sets the SuppressKey = True. My problem is, and I know this is probably elementary, but I just don't know. How do I declare a variable of KeyEventArgs so I can pass it into the routine? Below is my routine.
Code:
Public Sub cmbSuppressKey(sender As Object, e As KeyEventArgs)
Dim cmb As ComboBox = DirectCast(sender, ComboBox)
Try
EH.ErrorMessage = String.Empty
e.SuppressKeyPress = True
Catch ex As Exception
EH.ErrorMessage = "cmbSuppressKey() - " & ex.Message & "...Contact Software Engineering!" & "~E"
End Try
End Sub
Thanks
You wouldn't declare a variable of type KeyEventArgs you would get it from the KeyDown event of the ComboBox, in fact the Sub itself looks like it should be an event handler as it has the correct signature - you could either use the AddHandler statement to dynamically attach this to the correct event on each combobox or use the Handles clause to attach it at design time.
-
Dec 18th, 2017, 04:05 PM
#5
Thread Starter
PowerPoster
Re: Setting e.SuppressKey = True in called Procedure?
What I have is a routine that contains about 12 calls to this routine.
Code:
cmbSuppressKey(cmbLoadUnitType, e)
.
.
.
This is what the call looks like. So are you saying that I don't need the "e" argument in making this call?
-
Dec 18th, 2017, 04:21 PM
#6
Re: Setting e.SuppressKey = True in called Procedure?
Originally Posted by blakemckenna
What I have is a routine that contains about 12 calls to this routine.
Code:
cmbSuppressKey(cmbLoadUnitType, e)
.
.
.
This is what the call looks like. So are you saying that I don't need the "e" argument in making this call?
No, what I am saying is that you don't directly declare a variable of type KeyPressEventArgs - you would get the value from the event handler.
If you are doing what I think you are doing then you are expecting to call this method once for each combobox and prevent each combobox from reacting to a keypress, that is not how this works.
The argument e is generated in response to a key press by .Net and you would act on it in the event handler.
e.g. If you had two comboboxes called ComboBox1 and ComboBox2 on a form you could have done
Code:
Public Sub cmbSuppressKey(sender As Object, e As KeyEventArgs) Handles ComboBox1.KeyDown, ComboBox2.KeyDown
Dim cmb As ComboBox = DirectCast(sender, ComboBox)
Try
EH.ErrorMessage = String.Empty
e.SuppressKeyPress = True
Catch ex As Exception
EH.ErrorMessage = "cmbSuppressKey() - " & ex.Message & "...Contact Software Engineering!" & "~E"
End Try
End Sub
to suppress the keypress on each of them
-
Dec 18th, 2017, 04:28 PM
#7
Re: Setting e.SuppressKey = True in called Procedure?
That's not how it works. (PD had a conversation with you while I typed this!)
If you want to use keyboard event handlers to turn off key events, you're on the right track. I don't think the Try..Catch is useful in that code, since nothing inside of it can throw an exception. But that's an aside. What you have is a valid KeyDown or KeyUp handler that probably causes every keystroke to be ignored.
You don't call that. The ComboBox calls it. It's not a property of the ComboBox. It's a property of an item that only exists in the KeyPress event. What really happens is when you press a key, Windows does some work to figure out where the mouse was and which Window the mouse is over. (In API, they don't have "Controls". Everything is a Window.) Then that Window gets a message telling it where the mouse was and some other things. The .NET ComboBox is a bunch of .NET code around an API Window, so when its Window gets that message the ComboBox raises the KeyDown event. That causes your handler to be called. After your handler finishes, the ComboBox checks if e.SuppressKeyPress was set to True. If so, it stops. If not, it keeps doing what it normally does.
So if you just call this event handler, nothing happens. No keys were pressed, so there's nothing to suppress.
What you should be doing is adding or removing the handler to turn "on" or "off" the feature, or using some other mechanism to control how it works. I like what I just suggested though.
To be clear, I'd write this:
Code:
Sub EnableKeysFor(ByVal target As ComboBox)
RemoveHandler target.KeyDown, AddressOf WhenComboKeyIsPressed
End Sub
Sub DisableKeysFor(ByVal target As ComboBox)
AddHandler target.KeyDown, AddressOf WhenComboKeyIsPressed
End Sub
Sub WhenComboKeyIsPressed(sender As Object, e As keyEventArgs)
e.SuppressKeyPress = True
End Sub
If you call DisableKeysFor(), it will add the handler to the ComboBox and that will have the effect of disabling all keys, including things like down arrow that make no sense. It'll be just like you Disabled the control, only more confusing and your users will likely tell you "Sometimes the combo box gets bugged and I can't do anything with it." I'm 99% certain they can still click the drop-down and change the value.
If you call EnableKeysFor(), it will remove the handler, which will let the keys be pressed again.
Overall I disagree with your decision: users understand disabled ComboBoxes and there's generally not a good reason to do something different.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Dec 18th, 2017, 04:29 PM
#8
Thread Starter
PowerPoster
Re: Setting e.SuppressKey = True in called Procedure?
This is what my routine looks like. It is a global routine placed in a Module that is called from three different Windows Forms code-behind.
Code:
Public Sub EnableDisableParameters(uc As userParameters)
Dim e As New System.Windows.Forms.KeyEventArgs(???) 'This is where I want to declare the "e" argument
Try
EH.ErrorMessage = String.Empty
cmbSuppressKey(uc.cmbLoadPoints, e)
cmbSuppressKey(uc.cmbLoadUnitType, e)
cmbSuppressKey(uc.cmbLoadUnit, e)
cmbSuppressKey(uc.cmbLoadDecimal, e)
cmbSuppressKey(uc.cmbAnalogUnitType, e)
cmbSuppressKey(uc.cmbAnalogUnit, e)
cmbSuppressKey(uc.cmbAnalogDecimal, e)
cmbSuppressKey(uc.cmbOutputUnitType, e)
cmbSuppressKey(uc.cmbOutputUnit, e)
cmbSuppressKey(uc.cmbOutputDecimal, e)
cmbSuppressKey(uc.cmbConversionUnitType, e)
cmbSuppressKey(uc.cmbConversionUnit, e)
cmbSuppressKey(uc.cmbConversionDecimal, e)
cmbSuppressKey(uc.cmbNominalExci, e)
uc.grpCreepSettings.Enabled = True
uc.txtCreepCapacity.ReadOnly = True
uc.txtDurationHH.ReadOnly = True
uc.txtDurationMM.ReadOnly = True
uc.txtDurationSS.ReadOnly = True
uc.txtIntervalHH.ReadOnly = True
uc.txtIntervalMM.ReadOnly = True
uc.txtIntervalSS.ReadOnly = True
uc.txtLoadCapacity.ReadOnly = True
uc.txtRepeatCapacity.ReadOnly = True
uc.updRepeatIteration.ReadOnly = True
Catch ex As Exception
EH.ErrorMessage = "CalibrationTests/EnableDisableParameters() - " & ex.Message & "...Contact Software Engineering!" & "~E"
End Try
End Sub
-
Dec 18th, 2017, 04:34 PM
#9
Re: Setting e.SuppressKey = True in called Procedure?
Originally Posted by blakemckenna
This is what my routine looks like. It is a global routine placed in a Module that is called from three different Windows Forms code-behind.
<code snipped>
Which isn't how you would do it, you would either use the Handles clause like I demonstrated or use the AddHandler / RemoveHandler as shown by Sitten.
-
Dec 18th, 2017, 04:55 PM
#10
Thread Starter
PowerPoster
Re: Setting e.SuppressKey = True in called Procedure?
Sitten,
I see what you are doing and I will give that a try.
thanks
-
Dec 18th, 2017, 05:25 PM
#11
Thread Starter
PowerPoster
Re: Setting e.SuppressKey = True in called Procedure?
Is there anyway to prevent the user from actually opening the dropdown menu?
-
Dec 18th, 2017, 05:29 PM
#12
Re: Setting e.SuppressKey = True in called Procedure?
Yes: set the Enabled property to False, or set the DropDownStyle property to ComboBoxStyle.Simple so it looks like a ListBox.
Any other technique probably involves API and will be error prone because this isn't how you're supposed to use the control.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Dec 18th, 2017, 05:32 PM
#13
Thread Starter
PowerPoster
Re: Setting e.SuppressKey = True in called Procedure?
-
Dec 19th, 2017, 11:30 PM
#14
Re: Setting e.SuppressKey = True in called Procedure?
Originally Posted by blakemckenna
If there is a better way, believe me, I'm all ears!
There is. You inherit from the ComboBox class and implement a read only property yourself:-
vbnet Code:
Public Class ComboBoxEx Inherits ComboBox <System.ComponentModel.DefaultValue(False)> _ Public Property IsReadOnly As Boolean Protected Overrides Sub OnKeyDown(e As System.Windows.Forms.KeyEventArgs) If Me.IsReadOnly Then e.SuppressKeyPress = True End If MyBase.OnKeyDown(e) End Sub End Class
I'm surprised no one suggested this, especially as it's the best way of doing things like this. With the above class, you can enable read only behavior by simply doing this:-
vbnet Code:
ComboBoxEx1.IsReadOnly = True
-
Dec 20th, 2017, 08:35 AM
#15
Re: Setting e.SuppressKey = True in called Procedure?
I mainly didn't suggest it because using the Class keyword is the only quicker way to find your post ignored than mentioning unit tests on a VB forum. Seeing that you can do it as an event handler tends to imply you can generalize to a class, and people here favor the "simplest" solution, with strong opinions about "simple".
My strong opinion about "simple" is the easiest solution is already clear: set Enabled to False and you get a read-only ComboBox.
This answer is wrong. You should be using TableAdapter and Dictionaries instead.
-
Dec 20th, 2017, 09:39 AM
#16
Thread Starter
PowerPoster
Re: Setting e.SuppressKey = True in called Procedure?
Thanks Niya...that did work well...
-
Dec 20th, 2017, 10:13 AM
#17
Thread Starter
PowerPoster
Re: [RESOLVED] Setting e.SuppressKey = True in called Procedure?
Actually Niya...this code doesn't work like I wanted it to. I want the ComboBox to be enabled but not be able to produce the DropDown when clicked on.
-
Dec 20th, 2017, 10:30 AM
#18
Re: [RESOLVED] Setting e.SuppressKey = True in called Procedure?
Originally Posted by blakemckenna
Actually Niya...this code doesn't work like I wanted it to. I want the ComboBox to be enabled but not be able to produce the DropDown when clicked on.
Sitten already provided the answer:-
Originally Posted by Sitten Spynne
...or set the DropDownStyle property to ComboBoxStyle.Simple...
You can implement this into the IsReadOnly property of the derived class. Alternatively, just could just set it when you set IsReadOnly to True.
-
Dec 20th, 2017, 10:35 AM
#19
Re: Setting e.SuppressKey = True in called Procedure?
Originally Posted by Sitten Spynne
I mainly didn't suggest it because using the Class keyword is the only quicker way to find your post ignored than mentioning unit tests on a VB forum.
This is true when dealing with new programmers or programmers new to the language but it goes over well with seasoned programmers and hobbyists.
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
|