How to Undo and Redo in C# (Rich Text Box) - c#

I've been trying to get undo and redo working in my text editor for about 3 days now. It's doing my head in.
I have a text box (named richTextBoxPrintCtrl1), which I would like to be able to undo and *redo *(word by word).
So if I click the undo button, it undoes the last word. And if I then clicked the redo button, it redoes the last word.
Could somebody help me get this working?
richTextBoxPrintCtrl1.Undo(); doesn't work very well. It deletes everything typed in the text box.
Thanks in advance for your help.
I know this question has been asked many times before, but I can't get it working using the information from the questions I've browsed here on SO.

Ok, I'll post some code to help you get started. first you need to listen for the TextChanged event.
textBox1.TextChanged += new EventHandler(textBox1_TextChanged);
and you need to declare a stack in the class
Stack<string> undoList = new Stack<string>();
In the text changed handler, you need to add the contents of the textbox to the stack
void textBox1_TextChanged(object sender, EventArgs e)
{
undoList.Push(textBox1.Text);
}
Then you need to handle the undo, so you could simply use CTRL-Z
textBox1.KeyDown += new KeyEventHandler(textBox1_KeyDown);
void textBox1_KeyDown(object sender, KeyEventArgs e)
{
if(e.KeyCode == Keys.Z && (e.Control)) {
textBox1.Text = undoList.Pop();
}
}

You can have the RichTextBox build the undo stack for you word by word, plus keep track of the caret position, by handling one of the KeyDown-, KeyPress- or KeyUp events like this:
private void rtb_KeyDown(object sender, KeyEventArgs e)
{
// Trick to build undo stack word by word
RichTextBox rtb = (RichTextBox)sender;
if (e.KeyCode == Keys.Space)
{
this.SuspendLayout();
rtb.Undo();
rtb.Redo();
this.ResumeLayout();
}
// eztnap
}
Since the RichTextBox does the job for you, you just have to call rtb.Undo() or rtb.Redo() from wherever you need to.

Related

C# TextBox Change Event in DataGridView

I have a DataGridView with several columns of TextBoxes. I need to capture the event where they are done entering data, and are exiting the box (via Tab, Enter, Mouse click elsewhere, etc)
I have searched SO and Google, and it seems like you have to build an event from scratch. I've tried multiple variations on what I have found since I can't seems to find one that fits with my particular needs.
I've been at this for longer than I care to admit and I need help.
Here is what I have...
// Select DataGridView EditingControlShowing Event
Private void gridData_EditingControlShowing(object sender, DataGridViewEditingControlShowingEventArgs e) {
e.Control.TextChanged += new EventHandler(textBox_TextChanged);
Control cntObject = e.Control;
cntObject.TextChanged += textBox_TextChanged;
}
// TextBox TextChanged Event
Private void textBox_TextChanged(object sender, EventArgs e) {
// Checks to see if the AddlQty field was altered
if (gridData.Columns[e.ColumnIndex].Name == "AddlQty") {
// Validate Entry
if (e.Text is Not numeric) {
MessageBox.Show("Entry Not Valid, Only Numeric Values Accepted");
} else {
CalcFinalQty(e.RowIndex);
}
}
}
For the record, the code does NOT work, the validation is quasi code and I'm getting an error in the function heading. The important part for me is the
if (gridData.Columns[e.ColumnIndex].Name == "AddlQty"){ }
I just need help getting to that point.

Fire an event after Richtextbox Textchanged event

I am writing a lexer and i also want my text editor to change the color of the keywords. While typing! like VS and ... ! but the problem is TextChanged event of a RichTextBox fires BEFOR adding the text to it.
Is there any pre defined event that fire write AFTER adding the text to the richTextBox ? if not how can i create one that fire write after entering the text!
PS : i am writing a WPF project!
private void rtxMain_TextChanged (object sender, TextChangedEventsArgs e) {
visual.getLastWord();
}
TextChnaged event fires after changing the text of RichTextBox. Here is a working example of it:
private void richtextBox1_TextChanged(object sender, TextChangedEventArgs e)
{
string text = new TextRange(richtextBox1.Document.ContentStart, richtextBox1.Document.ContentEnd).Text;
MessageBox.Show(text);
}
Whatever I type into the richtextBox1, it shows me the exact same value in the MessageBox. It means it fires the event after changing the Text.
you can use the keyUp event it will fire when a key on the keyboard is let go off.
RichTextBox r = new RichTextBox();
r.KeyUp += (s, e) =>
{
//your logic
};
You might need to add extra logic to avoid keypresses like shift which isnt hard to do and maybe not even neccesary.

Default editing commands not working in TextBox when filtering KeyPress

I have a textbox in my winform in which after puting a validation using regex on keypress event, the default functionalities like copy paste etc of the textbox is not working.
How can i handle this?
Regex used code
private void textbox_keypress(object sender,keypresseventargs e)
{
var regex= new regex(#"^[0-9,]*$");
if(!regex.ismatch(e.keychar.tostring()))
{
e.handled=true;
}
}
after removing the keypress event handler everything is working fine but i have to restrict user to enter comma separated number value and also copy paste delete backspace in that textbox.
The Ctrl-Commands don't work because you abort their entries. To avoid this you must either
check if the Ctrl-Key has been pressed. The KeyPress event doesn't tell you that. This example from MSDN shows you how to do it: You script the KeyDown event to set (or clear) a flag variable, which you can then test in the KeyPress. No, not exactly elegant imho, but that's how MS tells you to do it.. (Note that I have added the Backspace code \b, as it isn't covered by the Ctrl-check..)
bool ctrlPressed = false;
private void textBox1_KeyDown(object sender, KeyEventArgs e)
{
ctrlPressed = (Control.ModifierKeys == Keys.Control);
}
private void textBox1_KeyPress(object sender, KeyPressEventArgs e)
{
if (!ctrlPressed)
{
var regex= new Regex(#"^[0-9,\b]*$");
if (!regex.IsMatch(e.KeyChar.ToString()))
{
e.Handled = true;
}
}
}
Or, if you want better control over which Ctrl-Keys are allowed, skip the whole flags-affair and instead simply include them one by one in the allowed keys-brackets like this for ^C, ^X, ^A, ^V ^Z etc..:
var regex= new Regex(#"^[0-9,\b\cC\cX\cA\cV\cZ]*$");
Here is the description from MSDN:
\cX Matches an ASCII control character, where X is the letter of the
control character. For example, \cC is CTRL-C.
On a side note: The old fashioned copy&paste commands of Ctl-Ins and Shift-Ins work as normal even in your original code.

Richtextbox deletes selected text

I have the following code:
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.N)
{
richTextBox1.Select(1, 3);
}
}
When I press the N key , the selected text is replaced with "n". I read this Selecting text in RichTexbox in C# deletes the text ,but it had no effects.
I am using Windows Forms.
Likely, you will need e.Handled = true; in this to stop the event.
http://msdn.microsoft.com/en-us/library/system.windows.forms.keyeventargs.handled.aspx
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.N)
{
richTextBox1.Select(1, 3);
e.Handled = true;
}
}
Try it yourself:
Open up the editor, type some text, mark some of this text and press N. What happens? The marked text is replaced with n.
The same thing happens in your RichTextBox. Important to understand here is, that with the event you set up, you only add some functionality and leave the default event handling (handled by the OS) intact.
So with your code, on a key press you just do
richTextBox1.Select(1, 3);
which selects some characters and afterwards the default event handling kicks in. Thus there is some marked text which gets replaced with N.
So, you simply have to mark the event as handled by yourself. Not using the Handled-property, but with the SuppressKeyPress-property.
private void richTextBox1_KeyDown(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.N)
{
richTextBox1.Select(1, 3);
e.SuppressKeyPress = true;
}
}
The documentation of Handled clearly states:
If you set Handled to true on a TextBox, that control will
not pass the key press events to the underlying Win32 text
box control, but it will still display the characters that the user typed.
Here is the official documentation of SuppressKeyPress.

Problem with button when text entered into the textbox

I am trying to make the save button visible when text is entered into the text box by using the following code:
if (tbName.TextModified == true)
{
btnCTimetablesOk.Visible = true;
}
else
{
btnCTimetablesOk.Visible = false;
}
but it gives error at tbname.textmodified
is there any other way to visible the button when we enter the text in text box
this is error i am getting "the event textbox.textmodified can only appear on the left hand side of += or -="
Try using the textbox's Enter and Leave events to show/hide your button:
private void textBox1_Enter(object sender, System.EventArgs e)
{
btnCTimetablesOk.Visible = true;
}
private void textBox1_Leave(object sender, System.EventArgs e)
{
btnCTimetablesOk.Visible = false;
}
Then modify your textbox to use these new methods.
If I'm reading your text correctly, you want the save button to be visible when the textbox has text in it and invisible when the text box is blank. If that's the case, you can use the Leave event (which occurs when the textbox loses focus) and a simple if statement:
private void textBox1_Leave(object sender, System.EventArgs e)
{
if(textBox1.Text != "")
btnCTimetablesOk.Visible = true;
else
btnCTimetablesOk.Visible = false;
}
You can also put this conditional block in any other methods kicked off by events that change the text of the box.
Also, you might want to consider using Enabled instead of Visible, it'll leave the button on the form but will gray out the text and clicking will do nothing.
I'm going to take a stab in the dark here and assume that the button is related to the textbox and you probably want someone to be able to type something in the textbox then click the button. You probably don't want the user to have to type something, then tab out or click somewhere else to make the button visible then click the button.
tbName_TextChanged(object sender, EventArgs e)
{
btnCTimetablesOk.Visible = !String.IsNullOrEmpty(tbName.Text)
}
Btw you're getting that error because TextModified isn't a boolean property, it's an event, like TextChanged or Leave or Enter. You can assign an event handler to it but you can't just check it like that.
As an aside I personally hate systems hungarian for winforms controls. I'd much rather have a timetablesOkButton than a btnCTimeablesOK button. That way if you also have a timetablesNameTextBox you can see at a glance that the button and the textbox match. Of course it may not be up to you.

Categories

Resources