Mic*_*ker 5 c# events copy-paste winforms
我目前有一个C#winforms应用程序,Ctrl + C和Ctrl + V绑定为编辑主菜单上的键盘快捷键.代码中有一些自定义复制/粘贴行为,它们响应这些菜单项,例如复制和粘贴listviews中的行.
但是,我的问题是您可以编辑行内的文本,当您这样做时,我希望Ctrl + C和Ctrl + V不会触发编辑菜单命令,而应该默认为基于正常文本的复制/粘贴.
我尝试过的一件事是触发BeforeLabelEdit和AfterLabelEdit事件,并从那里手动禁用/重新启用菜单项.不幸的是,似乎禁用的菜单项上的键盘快捷键仍会触发menu_Popup事件,该事件当前用于决定应启用/禁用哪些菜单项.(例如,"粘贴"仅在剪贴板上有文本时才有效).因此,即使禁用菜单项,键盘快捷键仍将激活Popup事件,这将重新启用菜单项.(这是一个错误吗?)
我找不到任何临时禁用菜单项键盘快捷方式的方法,无需手动存储旧快捷方式,将快捷方式设置为null,然后在需要重新启用时感觉脏(但感觉很脏).
当然要覆盖复制/粘贴行为或添加它,这是常见的事情吗?这里有更好的模式吗?
如果您想覆盖默认的复制/粘贴行为,您似乎需要使用比 C# 提供的更低级别的东西(请参阅剪贴板事件 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)*/ }
}
}
Run Code Online (Sandbox Code Playgroud)
要使用该类,您需要创建该类,然后在和事件guardedCommand.CurrentlyEditing
中适当设置其属性。然后,无论您在哪里按下 CTRL+C 快捷键,只需调用,它就会处理剩下的事情。BeforeLabelEdit
AfterLabelEdit
guardedCommand.DoCopy()
如果您想了解您想要做的事情的模式,请查看状态模式,上面的代码就是它的一种和实现。要成为真正的状态(或策略)模式,它需要有单独的具体类来实现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();
}
}
}
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,当只有两个状态时,这可能有点矫枉过正(并且状态数量可能不会增加)。