C# 在富文本框中启用复制、剪切、过去窗口

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/18966407/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 13:44:28  来源:igfitidea点击:

Enable copy, cut, past window in a rich text box

c#vb.netvisual-studio

提问by D P.

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

我的程序中有一个富文本框(richTextBox1),如下所示。但是当我右键单击它时,它不会弹出“复制、剪切、过去”窗口。你能告诉我如何在我的富文本框中启用这个“复制、剪切、过去”窗口吗?我是 C# 新手,如果你知道如何解决这个问题,请一步一步告诉我

enter image description here

在此处输入图片说明

采纳答案by Thilina H

Try with this code

尝试使用此代码

UPDATED 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

如果您想使用记事本等其他应用程序复制粘贴,(without styles )请替换以下方法

       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();
            }
        }  

回答by Icemanind

A standard RichTextBox does not contain a context menu for cut, copy and paste. However, you can look at this articlewhich has the complete code needed to implement your own!

标准 RichTextBox 不包含用于剪切、复制和粘贴的上下文菜单。但是,您可以查看这篇文章,其中包含实现您自己的完整代码!

回答by Jaex

If you have more than one RichTextBoxthen you can use this extensionmethod:

如果你有多个RichTextBox,那么你可以使用这个扩展方法:

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();

并像这样使用它: richTextBox1.AddContextMenu();

Screenshot: screenshot

截屏: 截屏

回答by Barry Guvenkaya

I think the solution provided by Thilina His excellent except few bugs.

我认为Thilina H提供的解决方案非常好,除了很少的错误。

  1. MouseUpevent causes the right click to start after second click. I recommend using MouseDownevent instead of MouseUpevent.

  2. I tested secondly provided CopyActionmethod. In my case CopyActionmethod didn't copy enter characters. I had to edit the code like this:

    Clipboard.SetText(richTextBox1.SelectedText.Replace("\n", "\r\n"));
    
  3. When richTextBox1.SelectedTextis empty the program showed an exception. I simply edited the CopyActionmethod shown by below to fix the issue.

        if (chatBox.SelectedText != null && chatBox.SelectedText != "")
        {
            Clipboard.SetText(richTextBox1.SelectedText.Replace("\n", "\r\n"));
        }
    
  1. MouseUp事件导致在第二次单击后开始右键单击。我建议使用MouseDown事件而不是MouseUp事件。

  2. 我测试了其次提供的CopyAction方法。就我而言,CopyAction方法没有复制输入字符。我不得不像这样编辑代码:

    Clipboard.SetText(richTextBox1.SelectedText.Replace("\n", "\r\n"));
    
  3. richTextBox1.SelectedText为空时,程序显示异常。我只是编辑了下面显示的CopyAction方法来解决这个问题。

        if (chatBox.SelectedText != null && chatBox.SelectedText != "")
        {
            Clipboard.SetText(richTextBox1.SelectedText.Replace("\n", "\r\n"));
        }
    

Happy Coding!

快乐编码!

回答by Kia.g

Thanks to @Jaex

感谢@Jaex

https://stackoverflow.com/a/36624233/5132252

https://stackoverflow.com/a/36624233/5132252

https://stackoverflow.com/a/435510/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;
                        }

                }
        }
    }

回答by Chronos

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.

如果您需要向多个 RichTextBox 实例添加标准上下文菜单,那么创建从 RichTextBox 继承的自定义扩展组件可能会更好。可以从解决方案资源管理器项目上下文菜单添加 -> 新项目... -> 自定义控件添加新组件。

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;
        }
    }
}

回答by DarkPh03n1X

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.

我只想添加到 Thilina H 的答案(被海报标记为正确答案的答案)这是我的复制和粘贴功能,它们更像是记事本。

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 ;

我希望它可以帮助某人;