I have a rich text box(richTextBox1
) in my program as shown bellow. But when I right click on it, it doesn't pop up a “copy, cut, past” window. Can you please tell me how can I enable this “copy, cut, past” window in to my Rich Text Box? I am new to C#, please let me know step by step, if you know how to solve this
-
8RTB just doesn't have one built-in like TextBox does. .NET makes them look similar but they are very different native Windows components under the hood. You can tell somewhat by the screwed-up border. You'll have to make your own, use ContextMenuStrip. – Hans Passant Sep 23 '13 at 18:41
-
2The WPF `RichTextBox` does have this menu. Just saying. Maybe it's a good idea to not start a new project in a slightly broken legacy technology. – millimoose Sep 23 '13 at 19:13
7 Answers
If you have more than one RichTextBox then you can use this extension method:
public static void AddContextMenu(this RichTextBox rtb)
{
if (rtb.ContextMenuStrip == null)
{
ContextMenuStrip cms = new ContextMenuStrip()
{
ShowImageMargin = false
};
ToolStripMenuItem tsmiUndo = new ToolStripMenuItem("Undo");
tsmiUndo.Click += (sender, e) => rtb.Undo();
cms.Items.Add(tsmiUndo);
ToolStripMenuItem tsmiRedo = new ToolStripMenuItem("Redo");
tsmiRedo.Click += (sender, e) => rtb.Redo();
cms.Items.Add(tsmiRedo);
cms.Items.Add(new ToolStripSeparator());
ToolStripMenuItem tsmiCut = new ToolStripMenuItem("Cut");
tsmiCut.Click += (sender, e) => rtb.Cut();
cms.Items.Add(tsmiCut);
ToolStripMenuItem tsmiCopy = new ToolStripMenuItem("Copy");
tsmiCopy.Click += (sender, e) => rtb.Copy();
cms.Items.Add(tsmiCopy);
ToolStripMenuItem tsmiPaste = new ToolStripMenuItem("Paste");
tsmiPaste.Click += (sender, e) => rtb.Paste();
cms.Items.Add(tsmiPaste);
ToolStripMenuItem tsmiDelete = new ToolStripMenuItem("Delete");
tsmiDelete.Click += (sender, e) => rtb.SelectedText = "";
cms.Items.Add(tsmiDelete);
cms.Items.Add(new ToolStripSeparator());
ToolStripMenuItem tsmiSelectAll = new ToolStripMenuItem("Select All");
tsmiSelectAll.Click += (sender, e) => rtb.SelectAll();
cms.Items.Add(tsmiSelectAll);
cms.Opening += (sender, e) =>
{
tsmiUndo.Enabled = !rtb.ReadOnly && rtb.CanUndo;
tsmiRedo.Enabled = !rtb.ReadOnly && rtb.CanRedo;
tsmiCut.Enabled = !rtb.ReadOnly && rtb.SelectionLength > 0;
tsmiCopy.Enabled = rtb.SelectionLength > 0;
tsmiPaste.Enabled = !rtb.ReadOnly && Clipboard.ContainsText();
tsmiDelete.Enabled = !rtb.ReadOnly && rtb.SelectionLength > 0;
tsmiSelectAll.Enabled = rtb.TextLength > 0 && rtb.SelectionLength < rtb.TextLength;
};
rtb.ContextMenuStrip = cms;
}
}
And use it like this: richTextBox1.AddContextMenu();

- 4,204
- 2
- 34
- 56
-
6A simple solution that works absolutely perfectly. Thanks. People really seem to overcomplicate this... – Nyerguds Feb 18 '16 at 10:07
-
1Great, I use it. But there is always room for improvement - for example add 2 `if (!rtb.ReadOnly) {` - or what about meaningful greying out? You could also add a hint where to paste this, for inexperienced users: it's not possible in Form1.cs, but in Program.cs it works. – maf-soft Apr 09 '16 at 09:40
-
-
-
@Faisal only if you select text then delete option becomes enabled. You can change this behavior from this line: `tsmiDelete.Enabled = !rtb.ReadOnly && rtb.SelectionLength > 0;` – Jaex Jan 01 '20 at 14:12
-
-
This should be the answer! I've placed the extension method in Program.cs and richTextBox1.AddContextMenu(); in Form_Load() event. Works great! Thank you!! – Leo Gurdian Mar 02 '21 at 02:01
Try with this code
UPDATED CODE:
private void richTextBox1_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Right)
{ //click event
//MessageBox.Show("you got it!");
ContextMenu contextMenu = new System.Windows.Forms.ContextMenu();
MenuItem menuItem = new MenuItem("Cut");
menuItem.Click += new EventHandler(CutAction);
contextMenu.MenuItems.Add(menuItem);
menuItem = new MenuItem("Copy");
menuItem.Click += new EventHandler(CopyAction);
contextMenu.MenuItems.Add(menuItem);
menuItem = new MenuItem("Paste");
menuItem.Click += new EventHandler(PasteAction);
contextMenu.MenuItems.Add(menuItem);
richTextBox1.ContextMenu = contextMenu;
}
}
void CutAction(object sender, EventArgs e)
{
richTextBox1.Cut();
}
void CopyAction(object sender, EventArgs e)
{
Graphics objGraphics;
Clipboard.SetData(DataFormats.Rtf, richTextBox1.SelectedRtf);
Clipboard.Clear();
}
void PasteAction(object sender, EventArgs e)
{
if (Clipboard.ContainsText(TextDataFormat.Rtf))
{
richTextBox1.SelectedRtf
= Clipboard.GetData(DataFormats.Rtf).ToString();
}
}
if you want to copy paste with another application like notepad (without styles )
please replace following methods
void CopyAction(object sender, EventArgs e)
{
Clipboard.SetText(richTextBox1.SelectedText);
}
void PasteAction(object sender, EventArgs e)
{
if (Clipboard.ContainsText())
{
richTextBox1.Text
+= Clipboard.GetText(TextDataFormat.Text).ToString();
}
}

- 5,754
- 6
- 26
- 56
-
3Thanks a lot for showing me with an example. In order to use this code, do I have to make a `MenuStrip` as well? because when I use your code `private void richTextBox1_MouseUp(object sender, MouseEventArgs e)` did not get called. If I double click on the `richTextBox1` as showing in the original picture, it will generate codes automatically at `Form1.Designer.cs` and `Form1.cs` :- `private void richTextBox1_TextChanged(object sender, EventArgs e)` Can you please tell me what should I do to make my program generate code for `private void richTextBox1_MouseUp(object sender, MouseEventArgs e)` – D P. Sep 24 '13 at 11:12
-
just click the richTextBox controller's properties and check the Event tab you can find that event .So just double click on MouseUp event. – Thilina H Sep 24 '13 at 12:09
-
2Thank you very much for providing me with all these information. If I were to do `copy, cut, past` things only inside this `richTextBox1`, it works. If I cut from the ` richTextBox1` and past in a notepad, it works too. But if I try to copy from `richTextBox1` and paste it in a notepad, it doesn’t work. And most importantly, if I have some text in a notepad that I want to copy over to this ` richTextBox1`, the code doesn’t work. Thank a lot for looking in to this. – D P. Sep 24 '13 at 12:54
-
if you want to get only text without styles then it can be done . i updated the code – Thilina H Sep 24 '13 at 14:01
-
1Thanks a lot for all your help and explaining things to me with examples. Appreciate your help. – D P. Sep 26 '13 at 09:04
-
1I think that it is not MouseUp event, it should be MouseDown event. ` private void richTextBox1_MouseDown(object sender, MouseEventArgs e)` – Jul 09 '14 at 18:51
-
5@Thilina H nice answer, but you really don't need to do the context menu creation every time you right click on the text. It is laggy and inconvenient. Instead, create and attach the context menu at Form_Load just once. – Christos Lytras Feb 07 '16 at 23:41
-
Seems like you could replace Clipboard.GetText(TextDataFormat.Text).ToString() with Clipboard.GetText(TextDataFormat.Text) – blitz_jones Sep 13 '18 at 20:36
A standard RichTextBox does not contain a context menu for cut, copy and paste. However, you can look at this article which has the complete code needed to implement your own!

- 47,519
- 50
- 171
- 296
I think the solution provided by Thilina H is excellent except few bugs.
MouseUp event causes the right click to start after second click. I recommend using MouseDown event instead of MouseUp event.
I tested secondly provided CopyAction method. In my case CopyAction method didn't copy enter characters. I had to edit the code like this:
Clipboard.SetText(richTextBox1.SelectedText.Replace("\n", "\r\n"));
When richTextBox1.SelectedText is empty the program showed an exception. I simply edited the CopyAction method shown by below to fix the issue.
if (chatBox.SelectedText != null && chatBox.SelectedText != "") { Clipboard.SetText(richTextBox1.SelectedText.Replace("\n", "\r\n")); }
Happy Coding!

- 1,482
- 3
- 17
- 26
-
This working for copying the newline character, but as commented above, @Thilina context menu does not have to be created every time you right click on the text. It is laggy and inconvenient. Instead, create and attach the context menu at Form_Load just once. – Christos Lytras Feb 07 '16 at 23:43
In case that you need to add standard context menu to multiple RichTextBox instances then it may be better to create custom extended component inherited from RichTextBox. New component can be added from Solution Explorer project context menu Add -> New Item... -> Custom Control.
You can also define handler for context menu opening to check if any text is selected, clipboard is not empty and if the control is not set as read only.
It is also good to support other useful standard actions like Undo, Redo, Delete, and Select All.
namespace Common
{
public partial class RichTextBoxEx : RichTextBox
{
public RichTextBoxEx()
{
AddContextMenu();
}
public void AddContextMenu()
{
ContextMenuStrip cms = new ContextMenuStrip { ShowImageMargin = false };
ToolStripMenuItem tsmiUndo = new ToolStripMenuItem("Undo");
tsmiUndo.Click += (sender, e) => { if (CanUndo) Undo(); };
tsmiUndo.ShortcutKeys = Keys.Z | Keys.Control;
cms.Items.Add(tsmiUndo);
ToolStripMenuItem tsmiRedo = new ToolStripMenuItem("Redo");
tsmiRedo.Click += (sender, e) => { if (CanRedo) Redo(); };
tsmiRedo.ShortcutKeys = Keys.Y | Keys.Control;
cms.Items.Add(tsmiRedo);
cms.Items.Add(new ToolStripSeparator());
ToolStripMenuItem tsmiCut = new ToolStripMenuItem("Cut");
tsmiCut.Click += (sender, e) => Cut();
tsmiCut.ShortcutKeys = Keys.X | Keys.Control;
cms.Items.Add(tsmiCut);
ToolStripMenuItem tsmiCopy = new ToolStripMenuItem("Copy");
tsmiCopy.Click += (sender, e) => Copy();
tsmiCopy.ShortcutKeys = Keys.C | Keys.Control;
cms.Items.Add(tsmiCopy);
ToolStripMenuItem tsmiPaste = new ToolStripMenuItem("Paste");
tsmiPaste.Click += (sender, e) => Paste();
tsmiPaste.ShortcutKeys = Keys.V | Keys.Control;
cms.Items.Add(tsmiPaste);
ToolStripMenuItem tsmiDelete = new ToolStripMenuItem("Delete");
tsmiDelete.Click += (sender, e) => { SelectedText = ""; };
cms.Items.Add(tsmiDelete);
cms.Items.Add(new ToolStripSeparator());
ToolStripMenuItem tsmiSelectAll = new ToolStripMenuItem("Select All");
tsmiSelectAll.Click += (sender, e) => { SelectionStart = 0; SelectionLength = Text.Length; };
tsmiSelectAll.ShortcutKeys = Keys.A | Keys.Control;
cms.Items.Add(tsmiSelectAll);
cms.Opening += delegate (object sender, CancelEventArgs e)
{
tsmiUndo.Enabled = CanUndo && !this.ReadOnly;
tsmiRedo.Enabled = CanRedo && !this.ReadOnly;
tsmiCut.Enabled = (SelectionLength != 0) && !this.ReadOnly;
tsmiCopy.Enabled = SelectionLength != 0;
tsmiPaste.Enabled = Clipboard.ContainsText() && !this.ReadOnly;
tsmiDelete.Enabled = (SelectionLength != 0) && !this.ReadOnly;
tsmiSelectAll.Enabled = (TextLength > 0) && (SelectionLength < TextLength);
};
ContextMenuStrip = cms;
}
}
}

- 249
- 2
- 7
I just want to add to Thilina H's answer (the one that was marked as the correct answer by the poster) Here is my copy and paste functions, They are a bit more notepad like.
void CopyAction(object sender, EventArgs e)
{
if (richTextBox1.SelectedText != null && richTextBox1.SelectedText != "")
{
Clipboard.SetText(richTextBox1.SelectedText);
}
}
void PasteAction(object sender, EventArgs e)
{
if (Clipboard.ContainsText())
{
int selstart = richTextBox1.SelectionStart;
if (richTextBox1.SelectedText != null && richTextBox1.SelectedText != "")
{
richTextBox1.Text = richTextBox1.Text.Remove(selstart, richTextBox1.SelectionLength);
}
string clip = Clipboard.GetText(TextDataFormat.Text).ToString();
richTextBox1.Text = richTextBox1.Text.Insert(selstart, clip);
richTextBox1.SelectionStart = selstart + clip.Length;
}
}
I hope it helps someone ;

- 600
- 1
- 7
- 17
Thanks to @Jaex
https://stackoverflow.com/a/36624233/5132252
https://stackoverflow.com/a/435510/5132252
[DllImport("user32.dll", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Winapi)]
internal static extern IntPtr GetFocus();
private Control GetFocusedControl()
{
Control focusedControl = null;
// To get hold of the focused control:
IntPtr focusedHandle = GetFocus();
if (focusedHandle != IntPtr.Zero)
// Note that if the focused Control is not a .Net control, then this will return null.
focusedControl = Control.FromHandle(focusedHandle);
return focusedControl;
}
private void pasteToolStripMenuItem_Click(object sender, EventArgs e)
{
if (Clipboard.ContainsText())
{
var FocusedControl = GetFocusedControl();
if (FocusedControl != null)
switch (FocusedControl.GetType().Name)
{
case "RichTextBox":
{
var RichTextBox = FocusedControl as RichTextBox;
RichTextBox.Paste();
break;
}
case "TextBox":
{
var TextBox = FocusedControl as TextBox;
TextBox.Paste();
break;
}
}
}
}