How do I undo the last change of the text in a text box when I have 30 text boxes on one form and not sure which text box the user may change?
Printable View
How do I undo the last change of the text in a text box when I have 30 text boxes on one form and not sure which text box the user may change?
Don't know if there's a better way, but this works.
Setup a TextBox object to use as reference, then in the TextChanged event for each textbox, set this object to reference the textbox being changed. Then use this object to call the Undo method, i.e...
Code:Private mLastChanged As TextBox
Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged
mLastChanged = TextBox1
End Sub
Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged
mLastChanged = TextBox2
End Sub
Private Sub TextBox3_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox3.TextChanged
mLastChanged = TextBox3
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
mLastChanged.Undo()
End Sub
This is what I have but it DOSEN'T work, any suggestions?
Private mLastChanged As TextBox
Private Sub wt1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles wt1.TextChanged
mLastChanged = wt1
End Sub
Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
mLastChanged.Undo()
End Sub
Ok, I wrote this today. It is in C#. Basically you are going to want to keep track of the changes as they are happening. I wrote a seperate class (static) to do this. Look at the code. If you can't figure it out, I will convert it to VB for you.
Here is the form code:
Here is the code for the static class:Code:using System;
using System.Drawing;
using System.Collections;
using System.ComponentModel;
using System.Windows.Forms;
using System.Data;
namespace Undo_Sample
{
public class Form1 : System.Windows.Forms.Form
{
private System.Windows.Forms.TextBox textBox1;
private System.Windows.Forms.TextBox textBox2;
private System.Windows.Forms.TextBox textBox3;
private System.Windows.Forms.Button button1;
private System.ComponentModel.Container components = null;
public Form1()
{
InitializeComponent();
}
protected override void Dispose( bool disposing )
{
if( disposing )
{
if (components != null)
{
components.Dispose();
}
}
base.Dispose( disposing );
}
private void InitializeComponent()
{
this.textBox1 = new System.Windows.Forms.TextBox();
this.textBox2 = new System.Windows.Forms.TextBox();
this.textBox3 = new System.Windows.Forms.TextBox();
this.button1 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// textBox1
//
this.textBox1.Location = new System.Drawing.Point(8, 16);
this.textBox1.Name = "textBox1";
this.textBox1.TabIndex = 0;
this.textBox1.Text = "";
this.textBox1.TextChanged += new System.EventHandler(this.textBox1_TextChanged);
//
// textBox2
//
this.textBox2.Location = new System.Drawing.Point(8, 40);
this.textBox2.Name = "textBox2";
this.textBox2.TabIndex = 1;
this.textBox2.Text = "";
this.textBox2.TextChanged += new System.EventHandler(this.textBox2_TextChanged);
//
// textBox3
//
this.textBox3.Location = new System.Drawing.Point(8, 64);
this.textBox3.Name = "textBox3";
this.textBox3.TabIndex = 2;
this.textBox3.Text = "";
this.textBox3.TextChanged += new System.EventHandler(this.textBox3_TextChanged);
//
// button1
//
this.button1.Location = new System.Drawing.Point(24, 104);
this.button1.Name = "button1";
this.button1.TabIndex = 3;
this.button1.Text = "Undo";
this.button1.Click += new System.EventHandler(this.button1_Click);
//
// Form1
//
this.AutoScaleBaseSize = new System.Drawing.Size(5, 13);
this.ClientSize = new System.Drawing.Size(152, 190);
this.Controls.AddRange(new System.Windows.Forms.Control[] {
this.button1,
this.textBox3,
this.textBox2,
this.textBox1});
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
this.ResumeLayout(false);
}
[STAThread]
static void Main()
{
Application.Run(new Form1());
}
// All that above is Visual Studio form creation code. Below is the code required
// to do what you want.
// make some private variables to store some information.
private string stringtext1;
private string stringtext2;
private string stringtext3;
private bool undohappening;
private void textBox1_TextChanged(object sender, System.EventArgs e)
{
if(undohappening == false)
{
Undo.AddChange(1,stringtext1);
button1.Enabled = true;
stringtext1 = textBox1.Text;
}
}
private void textBox2_TextChanged(object sender, System.EventArgs e)
{
if(undohappening == false)
{
Undo.AddChange(2,stringtext2);
button1.Enabled = true;
stringtext2 = textBox2.Text;
}
}
private void textBox3_TextChanged(object sender, System.EventArgs e)
{
if(undohappening == false)
{
Undo.AddChange(3,stringtext3);
button1.Enabled = true;
stringtext3 = textBox3.Text;
}
}
private void button1_Click(object sender, System.EventArgs e)
{
int boxlastchanged;
string textbeforechange;
undohappening = true;
// Get the last box changed and the text it was changed from.
boxlastchanged = Undo.BoxLastChanged();
textbeforechange = Undo.TextLastChanged();
// If there is nothing to undo, then the method will return -1.
if(boxlastchanged != -1)
{
switch (boxlastchanged)
{
case 1:
textBox1.Text = textbeforechange;
Application.DoEvents();
break;
case 2:
textBox2.Text = textbeforechange;
Application.DoEvents();
break;
case 3:
textBox3.Text = textbeforechange;
Application.DoEvents();
break;
}
}
else
{
// The boxes started empty, so empty them:
textBox1.Text = "";
textBox2.Text = "";
textBox3.Text = "";
button1.Enabled = false;
}
undohappening = false;
}
private void Form1_Load(object sender, System.EventArgs e)
{
Undo.Initialize();
stringtext1 = "";
stringtext2 = "";
stringtext3 = "";
undohappening = false;
button1.Enabled = false;
}
}
}
Code:using System;
using System.Collections;
namespace Undo_Sample
{
/// <summary>
/// Summary description for Undo.
/// </summary>
public class Undo
{
private Undo()
{
}
private static ArrayList thebox;
private static ArrayList thestrings;
public static void Initialize()
{
thebox = new ArrayList();
thestrings = new ArrayList();
}
public static void AddChange(int BoxChanged, string text)
{
thebox.Add(BoxChanged);
thestrings.Add(text);
}
public static int BoxLastChanged()
{
int x;
int returnvalue;
x = thebox.Count - 1;
if(x == -1)
{
return x;
}
else
{
returnvalue = (int)thebox[x];
thebox.RemoveAt(x);
return returnvalue;
}
}
public static string TextLastChanged()
{
int x;
string returnvalue;
x = thestrings.Count - 1;
if(x == -1)
{
return "blank";
}
else
{
returnvalue = (string)thestrings[x];
thestrings.RemoveAt(x);
return returnvalue;
}
}
}
}
I had some time. Here is the project in VB.Net
Thanks alot it works great!!!
Just what I needed!
No problem. I needed to make one up anyway. I will be using this in a future project.
Just another thought I had, you might want to put the code for updating a change in the textbox's validate event instead of the textchanged event. This would stop every character that is entered from being recorded, and only the whole change to the textbox is recorded.
Just an alternative. If you have say 3 textboxes called t1, t2, t3 then you could have the following:-
Private Sub TextBoxes_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles t1.TextChanged, t2.TextChanged, t3.TextChanged
dim tb as textbox=ctype(sender, textbox)
mLastChanged = tb.text
End Sub
One event can handle multiple controls and the sender object contains a reference to the control in question. You then use ctype to get a textbox ref from the sender.
Good idea, it didn't even cross my mind to do that...lol.