I will get few lines of your question and explain it to you:
Stack<string> undoList = new Stack<string>(); //Creates new EMPTY Stack
undoList.Push(txtMain.Text); //Add object to the top of the Stack
undoList.Pop(); //Removes object that is on top of the Stack
So now you have TextBox and when you type something textbox.Text property changes on it's own (not you affecting it). Then you created event that will "also" besides changing text property Push() old text to your Stack on the top.
Now after text change you "have" (you do not have i will explain it later) your string on top of stack and inside your textbox
Now when you press your Undo button you need to do two things.
- Set
textBox.Text property to top object in stack
- Delete top object in stack
Currently what you were doing is just second thing:
undoList.Pop();
But what you forgot to type before that is:
textBox1.Text = undoList.Pop();
This way you will set Text property AND delete object on top of stack.
Now let's get back you my you do not have i will explain it later.
I have said this since txtMain_TextChanged is fired AFTER text is changed.
So when you get txtMain.Text after text is changed, you will get new value instead of old one.
Also you will update your old text every time you type 1 character.
Solution to this is to use Enter event
private void textBox1_Enter(object sender, EventArgs e)
{
//it fires only when you enter textbox with mouse click/tab/etc
//Here add your OLD VALUE to top of stack
}