Hi,
Using button, How to undo the last click event?

use a boolean variable. In the handler code, have 2 sets of code, run a set based on the condition of the boolean.

in which handler?

That question is really generic, so i'll try to answer in a generic way.

As you can expect, the answer is 'That depends on what the click does'

  • If the button click adds one to a counter, the undo can subtract one from the same counter. In this case, once undone, the undo option should be disabled.

  • If the button click deletes a file, then the undo must recreate the file and fill it with the original content.

In general, in order to be able to do an undo, you need to persist the current status, before doing the action by the click, in order to be able to restore it from the result, if an undo is required. When the undo is done, then you must 'destroy' the containter that holded the status, because you cannot use it to 'repeat' the undo.

You will be aware that if more tan one undo is required, then you'll need to persist the status several times, being able to know the exact order of creation.

Hope this helps

commented: nice description +6
commented: Agree +8

in which handler?

The button with the click event.

lulafuertes;
i have multiple buttons and text boxes that recieve's its corresponding button.
if i do subtracting the count, how to catch the last action of Click event?

The button with the click event.

Ok then,

Sorry for reply a little late. This is also a generic answer...

If you have many 'click evente' to catch, in my opinión, the best solution is to create an ordered list of events catched, including info about the order of caching, the 'title' of what you cached, and the location of the persisted info.

The undo action, will allways be done from newest to older. So, you need to get the highest order value in the list and retrieve this info, get the persisted info, and act according, and remove this entry from the list.

Hope this helps.

Thanks for the idea.

If you are wanting the button - you can try to reference the last clicked button to figure out which one was clicked.

Example:

Dim btnLastClicked As New Button

Private Sub Button2_Click(sender As Object,e As EventArgs) Handles Button1.Click
    btnLastClicked=CType(sender,Button)
    'btnLastClicked will now reference Button1
End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
    btnLastClicked = Ctype(sender,Button)
    'btnLastClicked will now reference Button2
End Sub

Just food for thought.

Just adding a little bit of food...

i have multiple buttons and text boxes that recieve's its corresponding button

Maybe you'll need a table (lets name persistInfo) having 2 string fields: variableName and value.
Then an structure (lets call it undoStatus) is needed to

  • Identify the order of each click
  • Identify the event cached
  • Identify the old status persisted temp file having the variables modified by the click, and their values before the click has been done.

With this structure, you 'should' declare an static List<undoStatus> and fill it with a new undoStatus each time you handle a click event (or whatelse event you want to catch for undo).

When you'll catch an event, you'll need to:

  • Create a new persistInfo table in a new Dataset
  • Fill it with the relevant variable names and their old values
  • Save the dataset with a unique name (IE using the DateTime.Now with a mask of yyyyMMddhhmmssffffff)
  • Get the new order for the structure: can be obtained using the Linq Max function againt the list and adding one to the obtained value, or setting a 0 value if nothing is in the list. Remember this value in a static variable.
  • Set the event info and the file name for the dataset saved.
  • Add this to the list.

To undo:

  • Get the item in the list having the highest value remembered.
  • Read the referenced file into a new dataset.
  • For each row in the table, assign the old values to the variables.
  • Delete the file.
  • Remove the entry from the list.
  • Refresh the screen.

Hope this helps.

Each of my buttons do have sql statements updating to database which has 3 tables to be updated during the event. It looks like this:

'increment the variable value
variablename += 2
TextBox1.text = variablename

'sql statements
conn="server=localhost;username=root;password=****;database=*****;

connstring = "UPDATE `fieldname`='" & variablename & "' FROM `database`.`tabename` WHERE `date`='" & storeddate & "';"

Try

'procedure

Catch

'exception

End Try

is that possible to catch? I have that 40 buttons, all have sql statements and have different tables to update.
BOLEAN Variable is my hint to that sql statement but I don't know how to.

in your form load handler

'This tells each button to use the same handler for the click event
For Each SQLButton As Button In Me.Controls.OfType(Of Button)()
    AddHandler SQLButton.Click, AddressOf Button_Click
Next

If there are other buttons, name the buttons for the database in a unique way,"SQL1, SQL2, etc", perhaps. then use For Each SQLButton As Button In Me.Controls.Find("SQL", True).OfType(Of Button)()

in the form class add this sub

    'With this code you can identify the button that is clicked.  From here you can pass the Name, or Text, or even the Button, whatever works for you, to the sub handling the connection and query to your database.
    Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
        Dim TempButton As Button = DirectCast(sender, Button)
    End Sub

This code will work for however many buttons you have

Hi, how to properly use that code.

I am trying but it seems to have error in this sub:

Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
Dim TempButton As Button = DirectCast(sender, Button)
End Sub

Do this sub handles the undo button?

You said you wanted to run an SQL command for each button. My code was to give you a start, to show you how to use one set of code to handle every button. I also showed you how to use the code for only certain buttons.

What kind of error do you get?

Probably you have seen that there are some applications that are able to 'undo' the last action. There is no magic behind.

The programmer of those applications had to define how and what an undo button does, like any other button.

Now, on your application, you just need to write the code to be executed when the undo button is pressed.

The info by @tinstaafl is an example of a handler to determine which button has been pressed, but you need to add the necessary code to undo the action.

Using your example,

"UPDATE fieldname='" & variablename & "' FROM database.tabename WHERE date='" & storeddate & "';"

in order to undo this action, you need to do one (or many) UPDATE sentence to restore the values before you did the UPDATE.

How you can handle that?

Before doing your "UPDATE fieldname='" & variablename & "' FROM database.tabename WHERE date='" & storeddate & "';" you will need to create a command like

"SELECT TOP 100 PERCENT * FROMdatabase.tabenameWHEREdate='" & storeddate & "';"
Whith this command, yu'll need to create a data adapter to retrieve the info from the DB and fill a new Dataset (using the data adapter) with a table having the result of this select. Remember that your table must contain a field that identifies each row.

This way you'll have the values before doing the update. But this is not enough.

Also you need to save this info in a file using the Dataset save method, and store the info about the button pressed, the table affected, the key field and the name of the file containing the Dataset Info, in order to have all the elements to restore the table to the previuos state before the update.

On the first step, please change your button click events to manage this.

When you have all the info, we can continue to the undo.

Hope this helps

You said you wanted to run an SQL command for each button. My code was to give you a start, to show you how to use one set of code to handle every button. I also showed you how to use the code for only certain buttons.

What kind of error do you get?

It says Unhandled exception. But I guess, I know what causes error.

Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click which is conflict with this
Dim TempButton As Button = DirectCast(sender, Button)

You didn't follow the code I gave you.
When you set the handles option on an event handler it will only handle the one object, unless you include other objects in the statement, Handles Button1.Click, Button2.Click, etc.. When you have alot of objects it's easier to add the handler to each one like my code showed you. When you do it this way you can't use the handles option.

Okay. Thank's a lot.

You're very welcome.

Thank's again guys!

More than happy to help. Please remember to mark this solved

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.