TextBox:禁用“粘贴”选项,同时允许右键单击“剪切”和“复制”

我在C#WinForms中有一个TextBox组件。

当我右键单击它时,我想禁用粘贴选项,同时仍允许用户剪切和复制。

我调查了一些选项,但都没有完全符合我的要求 –

  1. 如果我使用此选项,它将阻止剪切和复制以及我不想要的粘贴。

    txt.ShortcutsEnabled = false;

  2. 如果我覆盖TextBoxContextMenu ,我将不得不在新的上下文菜单中自己编写剪切和复制function。

    txt.ContextMenu = new ContextMenu(); // or some other

我是否可以使用任何选项来仅禁用默认上下文菜单的粘贴选项 ,保留剪切和复制?

假设粘贴菜单项始终是文本框上下文菜单中的第五个元素(从零开始,分隔符也计为项目),您可以CustomMenuTextBox TextBox类(此处为: CustomMenuTextBox )并覆盖WndProc方法以禁用该特定菜单项:

 public static class User32 { [DllImport("user32.dll")] public static extern bool EnableMenuItem(IntPtr hMenu, uint uIDEnableItem, uint uEnable); } public class CustomMenuTextBox : TextBox { protected override void WndProc(ref Message m) { if (m.Msg == 0x0093 /*WM_UAHINITMENU*/ || m.Msg == 0x0117 /*WM_INITMENUPOPUP*/ || m.Msg == 0x0116 /*WM_INITMENU*/) { IntPtr menuHandle = m.Msg == 0x0093 ? Marshal.ReadIntPtr(m.LParam) : m.WParam; // MF_BYPOSITION and MF_GRAYED User32.EnableMenuItem(menuHandle, 4, 0x00000400 | 0x00000001); } base.WndProc(ref m); } } 

基于将项添加到默认TextBox上下文菜单 。

以下两个步骤禁用文本框中的“复制/粘贴”function:

  • 禁用默认菜单并将文本框与没有菜单项的空上下文菜单相关联(鼠标操作)。
  • 用户仍然可以使用键盘上的快捷键并执行这些操作。 因此,重写ProcessCmdKey方法,如下所示:

     // Constants private const Keys CopyKeys = Keys.Control | Keys.C; private const Keys PasteKeys = Keys.Control | Keys.V; protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { if((keyData == CopyKeys) || (keyData == PasteKeys)) { return true; } else { return base.ProcessCmdKey(ref msg, keyData); } } 

注意:返回true,这会抑制基类function。

或者您可以使用:

  ContextMenuStrip mnu = new ContextMenuStrip(); ToolStripMenuItem mnuCopy = new ToolStripMenuItem("Copy"); ToolStripMenuItem mnuCut = new ToolStripMenuItem("Cut"); mnuCopy.Click += new EventHandler(mnuCopy_Click); mnuCut.Click += new EventHandler(mnuCut_Click); mnu.MenuItems.AddRange(new MenuItem[] { mnuCopy, mnuCut}); txt.ContextMenu = mnu; 

注意:您无法在默认上下文菜单中禁用“过去”选项,因为您必须在表单中添加contextMenuStrip。

  this.contextMenuStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] { this.Undo, this.Cut, this.Copy, this.Paste, this.Delete, this.SelectAll}); this.contextMenuStrip1.Opening += new System.ComponentModel.CancelEventHandler(this.contextMenuStrip1_Opening); this.txt.ContextMenuStrip = this.contextMenuStrip1; 

希望对你有用

如果您只需要剪切复制和粘贴选项,也许最好创建自定义contentMenuStrip ,您可以在Visual Studio中直观地执行此操作,并且可以非常轻松地实现复制剪切和粘贴选项。 然后,当您想要启用或不启用任何选项时,您可以在程序中进行控制。

例如,自定义ContentMenuStrip的Opening事件中的此代码,如果未在文本框中选择文本,则禁用复制和剪切,并且仅在剪贴板包含文本或图像时启用“粘贴”。

  private void contextSuperEditor_Opening(object sender, CancelEventArgs e) { if (tbText.SelectionLength > 0) { MenuCopy.Enabled = true; MenuCut.Enabled = true; MenuPaste.Enabled = false; } else { MenuCopy.Enabled = false; MenuCut.Enabled = false; if (Clipboard.ContainsText() | Clipboard.ContainsImage()) { MenuPaste.Enabled = true; } } }