【问题标题】:WinForm text box: MenuStrip keyboard shortcuts overriding OS-level copy/pasteWinForm 文本框:覆盖操作系统级复制/粘贴的 MenuStrip 键盘快捷键
【发布时间】:2012-10-20 16:17:03
【问题描述】:

更新:我已经找出了问题的根源,现在正在尝试找出最佳解决方案

我有一个带有自定义 MenuStrip 的表单,其中包含各种花里胡哨的功能。这里需要注意的是,我的许多 MenuStrip 项目都有键盘快捷键 - 即用于剪切/复制/粘贴的快捷键。

此 MenuStrip 的存在似乎覆盖(并因此取消)我的文本框(和其他控件)的默认剪切/复制/粘贴键盘快捷键行为。

所有的。

.

我真的不能说我对 MenuStrip 剪切/复制/粘贴选项有原因,除了我希望在那里看到它们。这就是 Office 类型程序的运行方式,也是用户(包括我自己)所期望的。

我可以从 MenuStrip 中删除剪切/复制/粘贴选项,但那将是认输!那么如何防止过度设计的 MenuStrip 强迫我为每个对剪切/复制/粘贴友好的控件实现自定义代码?

.


** 原帖:**我在工具栏中有一个 TextBox 控件,它将在我的整个程序中使用。想象一下,默认情况下不支持本机操作系统级别的复制/粘贴事件时我会感到惊讶。

当然,我可以手动编写代码,但是当我右键单击控件时,Cut/Copy/Paste 已经内置。如何利用这个现有功能?

我认为使用 Ctrl+C、P 和 X 添加 KeyDown 事件大约是我应该编写的最大代码。对于那些事件,我只是调用一个内置方法或其他东西。或者找到一个启用原生剪切/复制/粘贴的设置。

我忽略/错过了什么?

【问题讨论】:

  • 工具栏是指 ToolStrip 吗?
  • 不,只是一个通用控件,我将添加到很多东西中。工具栏,而不是工具栏
  • 请提供有关此“通用控件”的更多详细信息,因为我们无法知道您要做什么。
  • 忘记那部分,这只是一个引导。如何实现本机复制/粘贴事件,而无需编写所有琐碎的文本替换位?
  • 就我而言,本机复制/粘贴在 TextBox 控件上开箱即用

标签: winforms textbox copy paste


【解决方案1】:

除非您覆盖ContextMenu 或ContextMenuStrip,否则您需要使用ClipBoard Class 自己来实现它。


在进一步查看它时,MSDN Forum article 讨论了使用 SendMessage 方法将命令发送到本机文本框控件。这是在自定义文本框中实现的,听起来就像您正在做的那样。

小节选见文章进一步实现:

protected void itemCut_Click(object sender, EventArgs e)
{
   SendMessage(this.Handle, TextBoxMessages.WM_CUT, 0, 0);
}


public static class TextBoxMessages
{
    public const int EM_UNDO = 0x00C7;
    public const int WM_CUT = 0x0300;
    public const int WM_COPY = 0x0301;
    public const int WM_PASTE = 0x0302;
}

【讨论】:

  • 好的,看起来我的自定义 MenuStrip 正在覆盖它...我已向该 MenuStrip 添加了剪切/复制/粘贴、查找和全选选项。我还为几乎所有这些选项实现了快捷键。看起来这些事件正在取代本机操作系统事件......知道如何绕过它吗?
  • @Tinkerer_CardTracker 我想我找到了另一个选项,请参阅上面编辑中的链接
  • 哇,这是一个有趣的 hack,但这真的不是我想要做的。既然我意识到问题是什么,我会发布一个澄清
  • @Tinkerer_CardTracker 我知道这有点 hack,但是在阅读了您的更新后,我仍然认为这是您能够实现 Native 例程的唯一方法。一旦你替换了默认的上下文菜单,似乎别无他法。
  • 就是这样,我不会替换 TextBox 的默认上下文菜单,我只是在表单顶部添加一个 MenuStrip。
【解决方案2】:

简单的解决方案:在 Click 事件中使用 SendKeys.Send() 调用。

SendKeys.Send("^X"); 

我正在做一些更复杂的事情,所以这里是详细信息: 我正在制作几个表单,它们都共享一些自定义控件:MenuStrip、StatusStrip 和其他一些自定义控件。我决定让所有表单都继承自同一个基类,以允许共同实现很多东西。

public partial class CommonFormBase : Form
{
    private void Initialize()
    {
        //Bind click event for custom MenuStrip to events in the local Form
        CommonMenuStrip.Edit_Cut.Click += new EventHandler(Edit_Cut_Click);
        CommonMenuStrip.Edit_Copy.Click += new EventHandler(Edit_Copy_Click);
        CommonMenuStrip.Edit_Paste.Click += new EventHandler(Edit_Paste_Click);
    }

    //Implement Click events for the MenuStrip by calling local methods
    internal void Edit_Cut_Click(object sender, EventArgs e) { Cut(); }
    internal void Edit_Copy_Click(object sender, EventArgs e) { Copy(); }
    internal void Edit_Paste_Click(object sender, EventArgs e) { Paste(); }

    //Generic implementation of common commands for the CommonFormBase
    public virtual void Cut() { SendKeys.Send("^X"); }
    public virtual void Copy() { SendKeys.Send("^C"); }
    public virtual void Paste() { SendKeys.Send("^V"); }
}

我在表单级别(不是 MenuStrip 级别)实现了 MenuStrip 的单击事件,但在该事件中,我只调用了一个通用方法,该方法执行所有代码。在这个例子中它有点过分了,但是我还有其他 MenuStrip 命令会改变不同子窗体的功能,所以我认为让它们都一样工作会更容易。

无论如何,这几乎可以完美运行!它似乎将快捷键激活的 MenuStrip_Click 事件推送到底层控件(或者可能是表单?),然后实现默认的快捷键事件。

它唯一做错的事情是它仅在您执行 Ctrl + V + V + V... 或按住 Ctrl+V 时触发一次。不过,这只是触发器无法识别多个事件的问题,而不是解决方案本身的问题。

【讨论】:

    猜你喜欢
    • 2011-01-20
    • 1970-01-01
    • 1970-01-01
    • 2023-03-27
    • 1970-01-01
    • 2015-04-17
    • 1970-01-01
    • 1970-01-01
    • 2022-12-31
    相关资源
    最近更新 更多