0

I have desktop Application with many controls. one of the controls is a button for printing...it works fine, it prints a selected area of the form. I want to remove the print button and run the existing print code by pressing Control + p.

I should have explained that the print button and code are on a large user control with many controls on it and as you pointed out there is a problem with controls on containers on containers...Form >>TabControl >> TabPage >> User Control.

The answers were helpful but the big point was what you said.

Private Sub PKey_KeyDown(sender As Object, e As KeyEventArgs) Handles    MyBase.KeyDown
  If e.Control And e.KeyCode = Keys.P Then
     MsgBox("This works fine...Ctrl + P were pressed")
  End If
End Sub

Using the code above works on a simple two or three control app but as of now when I press Ctrl + P on my many controls app, nothing happens.

Ed Jenkins
  • 117
  • 9
  • _"I am aware that the code below needs to have all of the controls tabstop set to off"_ - NO! Don't do that. Just set the `KeyPreview` property of the form to True. – 41686d6564 Jul 15 '19 at 01:21
  • Also, note that `Me.Controls` doesn't include controls placed in other containers on the form like controls on a Panel or a GroupBox. – 41686d6564 Jul 15 '19 at 01:24
  • I should have explained that the print button and code are on a large user control with many controls on it and as you pointed out there is a problem with controls on containers on containers...Form >>TabControl >> TabPage >> User Control – Ed Jenkins Jul 15 '19 at 07:09
  • A UserControl is not the right place to handle a hotkey. Consider doing something like `Private Sub MyForm_KeyDown(....) : If MyTabControl.SelectedTab Is MyTargetTab AndAlso e.KeyData = (Keys.Control Or Keys.P) Then ...`. And don't disable the `TabStop` property of any control _unless that's an actual requirement_ because it can frustrate the user. – 41686d6564 Jul 15 '19 at 15:44
  • Putting the KeyDown code in the Form1.vb code block with: If e.KeyData = (Keys.Control Or Keys.P) Then MsgBox("You Pressed Ctrl + P") works fine. the problem is: writing code to trigger the subroutine code of the Print button located in the UserControl1.vb block of code.. e.g. Form1.UserControl1.btnPrint_Click(sender, e) or something similar. – Ed Jenkins Jul 15 '19 at 18:53
  • Forget about the button (whether you want to keep it or not is irrelevant). Move the "print" code to a separate method with a `Public` (or `Friend`) access modifier, so in Form1, you can call it like this: `UserControl1.PrintMe()` where `PrintMe` is the name of the method. Then, if you want to keep the print button, you'd just have to call `PrintMe()` under `btnPrint_Click`. – 41686d6564 Jul 15 '19 at 19:00
  • I followed your advice changed the Public Sub Click to Public Sub myPrint() and then in the Ctrl + P code I used UserControl1.myPrint() and I get a System.NullReferenceException: 'Object variable or With block variable not set.' – Ed Jenkins Jul 15 '19 at 20:43
  • I can't tell you what the problem is without seeing your current code. You could ask another question but it's almost guaranteed that it will get closed as a duplicate to [this question](https://stackoverflow.com/q/4660142/4934172). Are you sure that `UserControl1` is the name of the UserControl on your form? My advice to you would be to learn how to debug your code. A NullReferenceException is one of the easiest exceptions to fix 99% of the time as soon as you know how to use breakpoints and step through the code. See [this answer](https://stackoverflow.com/a/26761773/4934172) for reference. – 41686d6564 Jul 15 '19 at 20:58

1 Answers1

0

There are a few steps that you need to do:

  1. Move the code that was in your Button's Click event into its own subroutine.
  2. Set the Form's KeyPreview property to True
  3. In the Form's KeyDown event use the following code:

Code:

Private Sub MyForm_KeyDown(ByVal sender As Object, ByVal e As KeyEventArgs) Handles MyBase.KeyDown
    If e.Control AndAlso e.KeyCode = Keys.P Then
        'Run print subroutine
    End If
End Sub
David
  • 2,928
  • 1
  • 13
  • 27
  • 1
    As it is, that will act on `Ctrl+Shift+P`, `Ctrl+Alt+P` and `Ctrl+Shift+Alt+P` as well. To act on only `Ctrl+P`, you should use `If e.KeyData = (Keys.Control Or Keys.P) Then`. – jmcilhinney Jul 15 '19 at 02:44
  • Thanks for showing the code that will respond to Ctrl + P only. I tested it and you are 100% correct. – Ed Jenkins Jul 15 '19 at 07:12
  • The print code is already in its own Subroutine. The problem is it is 3 layers deep, i.e., it is code in the user control which is on a tabpage on a tabcontrol on the form. I need to be able to reference the print subroutine. I tried Form1.TabControl1.UserControl1.btnPrint but the reference doesn't work. – Ed Jenkins Jul 15 '19 at 07:16