2011-05-16 52 views
3

我有简单的.net应用程序包含每个选项卡上的选项卡和datargridviews。我已经添加了主菜单的形式,并通过使用标准的财产分配热键菜单项:如何在DataGridView编辑模式下制作工作标准热键(Ctrl + C,Ctrl + Z)?

editMenuItem = new ToolStripMenuItem("Copy", null, new System.EventHandler(onCopyCut_Click)); 
editMenuItem.ShortcutKeys = Keys.Control | Keys.C; 

以上只是复制单元格内容中显示的菜单项目复制到剪贴板。这工作正常,但在DGV的编辑模式 Ctrl + C和其他标准热键不再工作了!

我已经设置Form.KeyPreview属性为true,还试图关闭处理好物业我的窗体对象,但没有任何反应:

void FileOrginizerForm_KeyDown(object sender, KeyEventArgs e) 
    { 
      ... 
     if (gridView.CurrentCell.IsInEditMode) 
      e.Handled = false; 
    } 

什么我失踪?我相信这应该是简单的。

我发现msdn help page's comments一些信息:

一件事,你需要记住,当设置这些属性是,如果 你有你的形式的文本框控件,菜单项的ShortcutKeys会 截取该组合键和文本框永远不会收到它,例如如果你的 有粘贴(ctrl + v)ShortcutKey,你的文本框永远不会收到粘贴 命令。据微软称,这是设计。他们的解决方法是 临时清除菜单项的ShortCutKey属性以允许粘贴 命令(最有可能在事件期间),然后在事件完成后重置该事件 。

SOLUTION:

相反的开启和关闭的菜单快捷方式我结束了从主窗体的KeyDown事件处理程序调用菜单事件处理程序:

void FileOrginizerForm_KeyDown(object sender, KeyEventArgs e) 
    { 
     if (!gridView.CurrentCell.IsInEditMode) 
     { 
      if (e.KeyData == (Keys.Control | Keys.Z)) 
      { 
       this.editToolStripMenuItem.DropDownItems["Undo"].PerformClick(); 
      } 
      else if (e.KeyData == (Keys.Control | Keys.Y)) 
      { 
       this.editToolStripMenuItem.DropDownItems["Redo"].PerformClick(); 
      } 
      else if (e.KeyData == (Keys.Control | Keys.X)) 
      { 
        this.editToolStripMenuItem.DropDownItems["Cut"].PerformClick(); 
      } 
      else if (e.KeyData == (Keys.Control | Keys.C)) 
      { 
        this.editToolStripMenuItem.DropDownItems["Copy"].PerformClick(); 
      } 
      else if (e.KeyData == (Keys.Control | Keys.V)) 
      { 
        this.editToolStripMenuItem.DropDownItems["Paste"].PerformClick(); 
      } 
      else if (e.KeyData == (Keys.Control | Keys.A)) 
      { 

this.selectToolStripMenuItem.DropDownItems["Select All"].PerformClick(); 
      } 
     } 
    } 
+0

当DGV进入“DataGridViewTextBoxColumn”(默认列类型)单元格的编辑模式时,它会创建一个“TextBox”控件并将其移动到单元格的区域中。正是这个控件('DataGridView.EditingControl')具有焦点。这个'TextBox'与窗体上的任何其他'TextBox'相同的快捷规则。 – Tergiver 2011-05-21 15:04:40

+0

是的,但问题是'ToolStripMenuItem.ShortcutKeys'属性重写了'TextBox'的标准快捷方式。 – sergo 2011-05-21 15:32:21

回答

1

你可以使用下面演示中显示的两个事件暂时删除菜单项中的快捷方式。

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 
using System.Windows.Forms; 

public class Form1 : Form 
{ 
    [STAThread] 
    static void Main() 
    { 
     Application.EnableVisualStyles(); 
     Application.SetCompatibleTextRenderingDefault(false); 
     Application.Run(new Form1()); 
    } 

    public Form1() 
    { 
     var dgv = new DataGridView 
     { 
      Dock = DockStyle.Fill, 
      DataSource = new List<DummyObject> 
      { 
       new DummyObject { Name = "One", Value = 1 }, 
       new DummyObject { Name = "Two", Value = 2 }, 
       new DummyObject { Name = "Three", Value = 3 }, 
      } 
     }; 
     dgv.EditingControlShowing += (s, e) => e.Control.VisibleChanged += DgvEditingControlVisibleChanged; 
     Controls.Add(dgv); 
    } 

    void DgvEditingControlVisibleChanged(object sender, EventArgs e) 
    { 
     Control control = sender as Control; 
     if (control.Visible) 
     { 
      // The editing control has become visible. 

      Trace.WriteLine(String.Format("Editing control showing {0}", control)); 
     } 
     else 
     { 
      // The editing control has been removed. 

      // Remove the event handler because the DGV can use multiple 
      // editing controls if it has different column types. 
      control.VisibleChanged -= DgvEditingControlVisibleChanged; 
      Trace.WriteLine(String.Format("Editing control removed {0}", control)); 
     } 
    } 
} 

public class DummyObject 
{ 
    public string Name { get; set; } 
    public int Value { get; set; } 
} 
+0

谢谢你的这种魔术 - 'dgv.EditingControlShowing + =(s,e)=> e.Control.VisibleChanged + = DgvEditingControlVisibleChanged;'但仍然有很多麻烦。 'KeyDown'事件对我来说似乎更容易。 – sergo 2011-05-21 17:10:28

+0

简单的方法是如何在“直接API应用程序”(即sans框架)中完成它。通常,剪切/复制/粘贴菜单项将简单地将WM_COMMAND(ID_CUT,ID_COPY,ID_PASTE)发送给具有焦点的控件。看起来,Windows窗体管道使得这比应该更困难。你可以简单地按照直接api应用程序的方式来执行,并且调用SendMessage(this.ActiveControl.Handle,WM_COMMAND,ID_COPY,0)'。我对WinForms管道知之甚少,不知道是否有更好的方法。 – Tergiver 2011-05-21 17:23:56

0

只需从菜单项中删除快捷方式,并将它的文本放在菜单项文本中。这适用于在表单上使用快捷方式,但是如果点击菜单项本身,您仍然需要编码

1

如果将SendKeys.Send("^c");添加到菜单项的单击事件中,则不需要从中删除快捷方式菜单项