【问题标题】:Custom copy/paste behaviour with C# winforms whilst allowing text edit copy/paste使用 C# winforms 自定义复制/粘贴行为,同时允许文本编辑复制/粘贴
【发布时间】:2012-09-05 11:29:45
【问题描述】:

我目前有一个 C# winforms 应用程序,在编辑主菜单上绑定了 Ctrl+C 和 Ctrl+V 作为键盘快捷键。在响应这些菜单项的代码中有一些自定义复制/粘贴行为,例如在列表视图中复制和粘贴行。

但是,我的问题是您可以在一行内编辑文本,当您这样做时,我希望 Ctrl+C 和 Ctrl+V 不会触发编辑菜单命令,而应该默认为基于普通文本的复制/粘贴。

我尝试过的一件事是触发 BeforeLabelEdit 和 AfterLabelEdit 事件,并从那里手动禁用/重新启用菜单项。不幸的是,禁用菜单项上的键盘快捷键似乎仍会触发 menu_Popup 事件,该事件当前用于决定应启用/禁用哪些菜单项。 (例如,“粘贴”仅在剪贴板上有文本时才有效)。所以即使我禁用了菜单项,键盘快捷键仍然会激活 Popup 事件,这将重新启用菜单项。 (这是一个错误吗?)

如果不手动存储旧快捷方式,将快捷方式设置为空,然后在需要重新启用时将其复制回来(感觉很脏),我找不到任何临时禁用菜单项键盘快捷方式的方法。

肯定会覆盖复制/粘贴行为或添加到它,是一件常见的事情吗?这里有更好的模式吗?

【问题讨论】:

  • 过度复制粘贴对我来说是个坏主意。我习惯了copy/paste 它在所有应用程序上总是一样的。你的应用程序只会让我感到困惑。但如果你坚持,为什么不检查焦点?如果焦点在您的文本框上,则复制粘贴一个,如果没有,则复制另一个
  • 我们的自定义复制/粘贴行为仅在您不编辑文本时处理复制和粘贴行。当您编辑文本时,我想要默认的复制/粘贴行为。
  • 清除菜单的快捷键是最简单的方法。其他选择将是“更脏”。

标签: c# winforms events copy-paste


【解决方案1】:

如果您想覆盖默认的复制/粘贴行为(请参阅Clipboard event C#Detect & Differentiate Clipboard Events (Cut,Copy and Paste)),您似乎需要使用比 C# 提供的更低级别的东西。但是,也许您可​​以将您的逻辑置于一个“守卫”之后,该“守卫”知道如何引导操作请求(如“副本”),然后将其重定向为适当的。

这是一个示例类:

namespace Your.App
{
    public class GuardedCommand
    {
        public bool CurrentlyEditing { get; set; }
        public GuardedCommand()
        {
            CurrentlyEditing = false;
        }
        public void DoCopy()
        {
            if(CurrentlyEditing)
                StandardCopyCommand();
            else
                ShortcutCopyCommand();
        }
        void ShortcutCopyCommand() { /*menu work here (or delegate to another class)*/ }
        void StandardCopyCommand() { /*"normal" work here (or delegate again)*/ }
    }
}

要使用你将创建类,然后在BeforeLabelEditAfterLabelEdit 事件中适当地设置它的guardedCommand.CurrentlyEditing 属性。然后,无论您在何处捕获 CTRL+C 快捷方式,只需调用 guardedCommand.DoCopy(),它就会处理其余的事情。

如果您想阅读有关您想要做什么的模式,请查看State Pattern,上面的代码就是这样的实现。要成为一个真正的状态(或策略)模式,它需要有单独的具体类来实现DoCopy()DoPaste(),而不仅仅是使用 if/else 或 switch。然后,当CurrentlyEditing被改变时,适当的具体实现将被设置为当前用于处理DoCopy()方法的类。

因为我写这一段比给你一些代码要花更长的时间,所以这里有一些代码:

namespace Your.App
{
//correct implementation of the State Pattern
    interface IClipboard
    {
        void Copy();
        void Paste();
    }
    class MyCustomClipboard : IClipboard
    {
        public void Copy() { /*your special code*/ }
        public void Paste() { /*your code again*/ }
    }
    class DefaultClipboard : IClipboard
    {
        public void Copy() { /*default code*/ }
        public void Paste() { /*default code again*/ }
    }
    public class StateClass
    {
        IClipboard State { get; set; }
        public StateClass()
        {
            CurrentlyEditing = false;
        }
        bool _currentlyEditing;
        public bool CurrentlyEditing
        {
            get { return _currentlyEditing; }
            set
            {
                _currentlyEditing = value;
                if(_currentlyEditing)
                    State = new DefaultClipboard();
                else
                    State = new MyCustomClipboard();
            }
        }
        public void Copy()
        {
            State.Copy();
        }
        public void Paste()
        {
            State.Paste();
        }
    }
}

如您所见,当只有两个状态时,这可能有点矫枉过正(状态的数量可能不会增加)。

【讨论】:

  • 这是否意味着我需要自己编写默认的复制/粘贴行为?这是我希望避免的事情。另外,这是否意味着我无法在右侧的快捷键列中列出菜单上的命令?令我惊讶的是,默认情况下,KeyDown 方法在我编辑标签时不会捕获 Ctrl+C,但在我不编辑标签时会捕获(这很有用)。这是与菜单快捷键不同的行为,当分配时,无论我是否正在编辑都会触发。
  • 抱歉,由于某种原因,我觉得您的代码可以使用已实现的默认复制/粘贴。重新阅读您的问题后,我发现您从未提及过。我怀疑“最佳”解决方案将是状态(或Strategy)模式的实现,它会像@John 提到的那样为您设置和清除快捷方式,具体取决于您所处的状态/您想要的策略使用。
猜你喜欢
  • 1970-01-01
  • 2017-09-28
  • 2017-07-15
  • 2018-10-26
  • 1970-01-01
  • 1970-01-01
  • 2015-10-22
  • 2015-10-06
  • 1970-01-01
相关资源
最近更新 更多