2011-05-16 48 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");添加到菜單項的單擊事件中,則不需要從中刪除快捷方式菜單項