locked
How to have a button act as clicked RRS feed

  • Question

  • I want to within an If statement have a button be clicked without the user having to do so manually. How can I do this besides copying the code from within the Clicked sub?
    Friday, January 12, 2018 7:03 PM

All replies

  • I want to within an If statement have a button be clicked without the user having to do so manually. How can I do this besides copying the code from within the Clicked sub?

    Call the sub and pass in Nothing, Nothing as the parameters.

    ***** EDIT *****

    As an example, I have this in a button's click event handler:

        Private Sub _
            BarButtonItem_Help_General_ItemClick(sender As System.Object, _
                                                 e As DevExpress.XtraBars.ItemClickEventArgs) _
                                                 Handles BarButtonItem_Help_General.ItemClick
    
            Dim sb As New System.Text.StringBuilder
    
            sb.AppendLine("In general, hovering your mouse over most of the")
            sb.AppendLine(String.Format("labels will show you quick {0}general{0} help about the", Chr(34)))
            sb.AppendLine("topic.")
    
            XtraMessageBox.Show(sb.ToString, "General Help", MessageBoxButtons.OK, MessageBoxIcon.None, DevExpress.Utils.DefaultBoolean.True)
    
        End Sub

    For testing it, I used this in the form's .Load event handler:

    BarButtonItem_Help_General_ItemClick(Nothing, Nothing)

    The result is shown below:


    "A problem well stated is a problem half solved.” - Charles F. Kettering


    • Edited by Frank L. Smith Friday, January 12, 2018 7:15 PM
    • Proposed as answer by IronRazerz Friday, January 12, 2018 11:42 PM
    Friday, January 12, 2018 7:07 PM
  • I want to within an If statement have a button be clicked without the user having to do so manually. How can I do this besides copying the code from within the Clicked sub?

    Hi

    Alternatively, you can use Button1.PerformClick


    Regards Les, Livingston, Scotland

    • Proposed as answer by Reed KimbleMVP Friday, January 12, 2018 10:56 PM
    Friday, January 12, 2018 7:19 PM
  • Alternatively, you can use Button1.PerformClick

    Regards Les, Livingston, Scotland

    That has been proven to be unreliable. As an example:

    http://www.dreamincode.net/forums/topic/70241-problem-with-calling-this-button1performclick/


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Friday, January 12, 2018 7:26 PM
  • Alternatively, you can use Button1.PerformClick


    Regards Les, Livingston, Scotland

    That has been proven to be unreliable. As an example:

    http://www.dreamincode.net/forums/topic/70241-problem-with-calling-this-button1performclick/


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Hi Frank

    I don't see it that way. OP was using a Button event without a signature - maybe that had something to do with his issues. A 9 year old thread doesn't carry quite so much authority either.

    I have used the PerformClick without issue.


    Regards Les, Livingston, Scotland

    Friday, January 12, 2018 7:39 PM
  • Create a new method. Move the code from the click event handler to there. Replace with a call to the method. Then you can easily do the same thing from elsewhere.


    Sam Hobbs
    SimpleSamples.Info

    • Proposed as answer by Reed KimbleMVP Friday, January 12, 2018 10:56 PM
    Friday, January 12, 2018 7:53 PM
  • Hello,

    Anytime you might do such an operations use the following pattern where I created a procedure which is called in Button1 or from elsewheres such as in a if condition in form shown event or any place you want this to occur. 

    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
        ForButton1()
    End Sub
    Private Sub ForButton1()
        MessageBox.Show("Hello from button1")
    End Sub
    
    Private Sub Form1_Shown(sender As Object, e As EventArgs) Handles Me.Shown
        If Now.Hour = 14 Then
            ForButton1()
        End If
    End Sub


    Please remember to mark the replies as answers if they help and unmark them if they provide no help, this will help others who are looking for solutions to the same or similar problem. Contact via my Twitter (Karen Payne) or Facebook (Karen Payne) via my MSDN profile but will not answer coding question on either.
    VB Forums - moderator
    profile for Karen Payne on Stack Exchange, a network of free, community-driven Q&A sites

    Friday, January 12, 2018 10:43 PM
  • Just because i have seen this discussion about the PerformClick method before,  i looked into it real quick.  Here are my findings just to clear it up for others and myself....

     The problem with the Button.PerformClick Method is related to it's CanSelect Property.  If you look at the .Net Source Code for the Button Class's PerformClick method,  it starts off with checking to see if the CanSelect property is True before calling it's OnClick method.  However,  the CanSelect property will only be True if the button control's Enabled and Visible properties are both True and it's Parent container control's Enabled or Visible properties are both True.

     So basically,  if the Button's Enabled property or Visible property is False,  or it's Parent container control's Enabled or Visible properties are set to False,  the PerformClick method will not call the OnClick method of the button.

     This happens to be a specific problem with a TabControl because,  when the tabs are un-selected,  their Visible property is changed to False and the selected tabpage's Visible property is set to True.   So,  if the button was on a tabpage other than the selected tabpage,  the button's parent tabpage's Visible property is set to false.

     As is stated in the Control.CanSelect documents....

    "This property returns true if the Selectable value of System.Windows.Forms.ControlStyles is set to true, is contained in another control, the control itself is visible and enabled, and all its parent controls are visible and enabled."

     So,  PerformClick is fine to use if you are certain the control can be selected (is Visible and Enabled).  However it is more reliable to just directly call the click event sub of the button.  After all,  it is just a sub like any other sub you might add to your code,  it just happens to have a handler added to it.  It also does not have the limitations i have mentioned about the PerformClick method.  8)


    If you say it can`t be done then i`ll try it

    • Edited by IronRazerz Friday, January 12, 2018 11:44 PM
    Friday, January 12, 2018 11:36 PM
  • So basically,  if the Button's Enabled property or Visible property is False,  or it's Parent container control's Enabled or Visible properties are set to False,  the PerformClick method will not call the OnClick method of the button.

    That makes sense, correct? The developer typically would want Windows to do that. If a control is disabled or hidden then the developer does not want it to be used. I have not checked the Windows API documentation but I assume that is how the Windows API controls work.

    This happens to be a specific problem with a TabControl because,  when the tabs are un-selected,  their Visible property is changed to False and the selected tabpage's Visible property is set to True.

    Typically something that works as designed is not considered a bug. The TabControl and the other controls should work like that. I am not sure what you mean by "problem"; I will assume you mean the question is a problem to be solved and the issue of a control being disabled and/or hidden is a complication.

    So,  PerformClick is fine to use if you are certain the control can be selected (is Visible and Enabled).  However it is more reliable to just directly call the click event sub of the button.

    The simple and most reliable solution is to simply move the relevant code into a separate method.



    Sam Hobbs
    SimpleSamples.Info

    Sunday, January 14, 2018 5:42 AM
  • The simple and most reliable solution is to simply move the relevant code into a separate method.



    Sam Hobbs
    SimpleSamples.Info

    What's wrong with using the sub that's already built? Why move code at all?

    Most of the eventargs (including the button's click event) are empty. Passing "Nothing" in its place brings no harm to it - it's the same.

    As for caller, unless multiple handles are being used, then it's also irrelevant.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Sunday, January 14, 2018 12:05 PM
  • Unless you have a computer with hands you cannot. 

    But you can of course at any moment let the method be done which does the same as when the program gets the signal that a button is clicked. 

    Frank and Sam Hobbs (simple samples) has given that. 

    Be aware that there are functions who starts a the signal that a message click has done. But those are insecure because they only work if the button is visible. 


    Success Cor



    Sunday, January 14, 2018 12:25 PM
  • Nothing Frank,

    Some say it is not decent code and wants than something like

    TheClickMethod(me, new eventsargs), but that serves again nothing. 

    :-)


    Success Cor

    Sunday, January 14, 2018 12:30 PM
  •  Sam,  this is getting a little old already.  You seem to have picked up the habit of ripping apart my posts lately and trying to point out what you think is wrong with my posts.  I am getting a little tiered of it to tell you the truth.  It seems like you are more interested in trying to harass me than trying to help the questioner of the thread(s).

     As i said the other day in the last thread you did this in,  just post your answer to the questioner and quit quoting my posts and trying to make them look bad or wrong in some way.  It is only making you look like the "I Think I Know It All A**hole" around the forum if you want to know what I think,  which i am sure you probably don't.

     

    Typically something that works as designed is not considered a bug. The TabControl and the other controls should work like that. I am not sure what you mean by "problem"; I will assume you mean the question is a problem to be solved and the issue of a control being disabled and/or hidden is a complication.

      Here we go again... I never said it was a bug.  Apparently you are not understanding the scope of what i was saying so,  i will try to explain it again just for you....

     If a button is not on the selected TabPage and the designer of the application wants to perform a click on the button for some reason,  PerformClick will not call the OnClick method.  If the designer of the application wants it to work and it does not work,  and there is no explanation anywhere of why it does not work,  then that would be a problem in my book.  Luckily for the designer of the application,  they can solve that problem by just simply calling the button's click event sub.

     

     

    The simple and most reliable solution is to simply move the relevant code into a separate method.

      Well,  that would just be your opinion,  everyone has one.  To me,  it makes no sense to move the code to another sub if you can simply just call the sub that is already there.  That is my opinion.

     Now,  lets stop with the BS and concentrate on the questioners problem.


    If you say it can`t be done then i`ll try it

    • Edited by IronRazerz Sunday, January 14, 2018 9:11 PM
    Sunday, January 14, 2018 2:09 PM
  • What's wrong with using the sub that's already built? Why move code at all?

    Most of the eventargs (including the button's click event) are empty. Passing "Nothing" in its place brings no harm to it - it's the same.

    As for caller, unless multiple handles are being used, then it's also irrelevant.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Hi Frank, here's my take on this.

    The problem is that it breaks convention.  There are some risks associated with that directly, but moreover, breaking convention can lead to confusion, particularly for a new developer.

    There is the risk of calling a sub which does rely on the event args or assumes the value of sender.  There's also the risk of confusing yourself or another developer later when the program requires a modification.  It can affect readability of the code.  When you come to a line that says "Button27_Click(Nothing, Nothing)" a year after it was written, you (or another developer) may find it to be a rather cryptic line of code.

    As an aside, instead of passing Nothing when the "e" parameter is just plain EventArgs, you can use EventArgs.Empty which returns a static instance of event args with no parameters.  If the type of "e" is a derived EventArgs then there is a good chance that it is NOT safe to call the method directly because there is a fair probability that the handing code will need the parameter value(s) provided on the derived event args.

    When someone who is new to this, or just doesn't understand the finer points, sees an example like this for the Button.Click() event they may be led to think that they can do something like Form1_Paint(Nothing, Nothing) to make the Form redraw itself (not knowing about Invalidate). 

    -EDIT-

    Just thought of a better (worse!) example:

    Form1_Paint(Me, New PaintEventArgs(Me.CreateGraphics, Me.DisplayRectangle))

    That will compile and execute, but the results won't be what was intended.  When you see examples like Button1_Click(Me, EventArgs.Empty) it can lead you to believe that the above should work too.

    -/EDIT-

    That's the main reason I prefer to not suggest this kind of solution - its not applicable in just any scenario and can lead to confusion for new developers.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"


    Sunday, January 14, 2018 2:22 PM

  • Hi Frank, here's my take on this.

    The problem is that it breaks convention.  There are some risks associated with that directly, but moreover, breaking convention can lead to confusion, particularly for a new developer.

    There is the risk of calling a sub which does rely on the event args or assumes the value of sender.  There's also the risk of confusing yourself or another developer later when the program requires a modification.  It can affect readability of the code.  When you come to a line that says "Button27_Click(Nothing, Nothing)" a year after it was written, you (or another developer) may find it to be a rather cryptic line of code.

    As an aside, instead of passing Nothing when the "e" parameter is just plain EventArgs, you can use EventArgs.Empty which returns a static instance of event args with no parameters.  If the type of "e" is a derived EventArgs then there is a good chance that it is NOT safe to call the method directly because there is a fair probability that the handing code will need the parameter value(s) provided on the derived event args.

    When someone who is new to this, or just doesn't understand the finer points, sees an example like this for the Button.Click() event they may be led to think that they can do something like Form1_Paint(Nothing, Nothing) to make the Form redraw itself (not knowing about Invalidate). 

    That's the main reason I prefer to not suggest this kind of solution - its not applicable in just any scenario and can lead to confusion for new developers.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    A bigger issue would be with the sender being nothing.

    If the signature is wrong, it will show a compile error and that's as far as that goes. If there's an identification routine in the sub such that casting the sender for the sake of the name is used, it will end up generating an ObjectNullReference Exception at run-time.

    For me, it's rare that I'd not already have something (in a class or an assembly) that it would call, but that's not why Sam posted what he did - I think that's obvious.

    *****

    It doesn't really matter - I can already tell what the OP will mark as the answerer: Les' original code.

    Why? Because it's short.

    In this forum, more than three lines of code is a veritable curse. I'm at the point now that I look in every once in a while but I don't see any point in trying to participate much.


    "A problem well stated is a problem half solved.” - Charles F. Kettering


    Sunday, January 14, 2018 2:38 PM

  • That's the main reason I prefer to not suggest this kind of solution - its not applicable in just any scenario and can lead to confusion for new developers.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"


    Reed,

    Your argumentation is more a kind of many C# programmers doing things. Very theoretical. The passed parameters serve only something if they are used. If that can be the case. There were it can go wrong I would prefer putting as first a test in the method than relying that something is passed. 

    If Sender = Nothing andalso e = Nothing ......

    In VB you can even use Nothing in some cases where it is in C# forbidden. For instance the Invariant culture serves in many cases nothing. In VB you can than use Nothing, in C# it is than even not allowed to pass Null. 

    You understand that it is not the first time I'm in this kind of discussions. 


    Success Cor

    Sunday, January 14, 2018 4:15 PM
  • What's wrong with using the sub that's already built? Why move code at all?

    You provided some good reasons in the post I replied to.

    Also, why not create a relevant method? I don't understand the problem of creating a method to do what the method is named for doing. The method should have a relevant name.



    Sam Hobbs
    SimpleSamples.Info

    Sunday, January 14, 2018 9:06 PM
  • Who are you addressing Sam?

    We don't all see this forum the same way and I can't tell -- they're all serial to me.


    "A problem well stated is a problem half solved.” - Charles F. Kettering

    Sunday, January 14, 2018 10:04 PM
  • Cor,

    You should quote my first statement, not the last...

    "The problem is that it breaks convention."

    The statement you quoted is my personal reasoning for why it is bad, in this case, to break convention.

    But there are other reasons, as you have shown.  No one should ever need to write "If Sender Is Nothing" because the sender in an event handler will never be Nothing, by convention.

    Its not theory, its the practice of the development of the .Net framework.


    Reed Kimble - "When you do things right, people won't be sure you've done anything at all"

    Monday, January 15, 2018 2:34 AM