2017-03-28 78 views
-1

如何覆蓋文本框的ShortcutsEnabled屬性以接受某些快捷方式並拒絕其他人?如何覆蓋文本框的ShortcutsEnabled

clearify:我試圖創建一個基於textbox的組件庫,並將其context menu更改爲更漂亮。爲了顯示我的context menu我首先使用contextMenu/contextMenuStrip屬性測試了2種方法,但它有一個問題(如果用戶按下鼠標右鍵並移出並離開按鈕,此方法將不起作用)另一種方法是使用ShortcutsEnabled屬性大。但我喜歡ctrl + C等快捷鍵,...保持活動狀態。 here表示可以覆蓋此屬性來指定快捷方式,但我找不到有關如何完成的任何示例。


編輯:我沒有找到好的方法來做到這一點。但爲了解決我的問題(啓用快捷方式時禁用上下文菜單),我找到了@AliTheOne和@ x5657提供的鏈接解決方案。你可以在WndProc中捕獲0x007B message,好的是你仍然可以在mouse down event中捕獲right mouse button click並用它來顯示自定義上下文菜單,並且不會顯示正常的上下文菜單。請注意,這將啓用所有正常的快捷方式。

protected override void WndProc(ref Message m) 
      { 
       if (m.Msg != 0x007B) 
       { 
        base.WndProc(ref m); 
       } 
      } 

void textBox_MouseDown(object sender, MouseEventArgs e) 
     { 
      if (e.Button == System.Windows.Forms.MouseButtons.Right) 
      { 
       //show custom context menu 

      } 
     } 

回答

0

基礎上code for textbox我認爲你需要重寫ProcessCmdKey。

基礎ShortcutsEnabled setter設置在shortcutsToDisable字段中啓用了哪些快捷方式,但不幸的是這是私人的,所以您必須「自己推出」實現。

ProcessCmdKey會是這個樣子:

protected override bool ProcessCmdKey(ref Message msg, Keys keyData) { 
    if (this.ShortcutsEnabled == false) { 
     foreach (int shortcutValue in shortcutsToDisable) { 
      if ((int)keyData == shortcutValue || 
       (int)keyData == (shortcutValue | (int)Keys.Shift)) { 
       return true; 
      } 
     } 
    } 
    // 
    // There are a few keys that change the alignment of the text, but that 
    // are not ignored by the native control when the ReadOnly property is set. 
    // We need to workaround that. 
    if (textBoxFlags[readOnly]) { 
     int k = (int)keyData; 
     if (k == (int)Shortcut.CtrlL  // align left 
      || k == (int)Shortcut.CtrlR  // align right 
      || k == (int)Shortcut.CtrlE  // align centre 
      || k == (int)Shortcut.CtrlJ) { // align justified 
      return true; 
     } 
    } 

    return base.ProcessCmdKey(ref msg, keyData); 
} 
+0

很好的答案,但它拋出'對象引用沒有設置爲一個對象的實例'在'return base.ProcessCmdKey(ref msg,keyData)異常;' – NokhodSiah

0

在此基礎上:TextBoxBase.cs

你可以這樣做:我們想通過按Ctrl + R鍵設置對齊和Ctrl + L

如果你想禁用任何內置的快捷方式像Ctrl + Z和分配新的方法,只需將其從public override bool ShortcutsEnabled {}中刪除並將其放入protected override bool ProcessCmdKey(..)switch..case

 public class MyTextBox : TextBox 
    { 

    private static readonly int _readOnly = BitVector32.CreateMask(); 
    private static readonly int _shortcutsEnabled = BitVector32.CreateMask(_readOnly); 
    private static int[] _shortcutsToDisable; 

    private BitVector32 _textBoxFlags; 

    public override bool ShortcutsEnabled 
    { 
     get { return _textBoxFlags[_shortcutsEnabled]; } 
     set 
     { 
      if (_shortcutsToDisable == null) 
      { 
       _shortcutsToDisable = new int[] 
       { 
        (int) Shortcut.CtrlZ,(int) Shortcut.CtrlC, (int) Shortcut.CtrlX, 
        (int) Shortcut.CtrlV, (int) Shortcut.CtrlA, (int) Shortcut.CtrlL, (int) Shortcut.CtrlR, 
        (int) Shortcut.CtrlE, (int) Shortcut.CtrlY, (int) Keys.Control + (int) Keys.Back, 
        (int) Shortcut.CtrlDel, (int) Shortcut.ShiftDel, (int) Shortcut.ShiftIns, (int) Shortcut.CtrlJ 
       }; 
      } 
      _textBoxFlags[_shortcutsEnabled] = value; 

     } 
    } 
    protected override bool ProcessCmdKey(ref Message msg, Keys keyData) 
    { 
     if (_shortcutsToDisable == null) 
     { 
      return false; 
     } 
      var k = (int)keyData; 
     switch (k) 
     { 
      case (int)Shortcut.CtrlL: 
       TextAlign=HorizontalAlignment.Left; 
       break; 
      case (int)Shortcut.CtrlR: 
       TextAlign = HorizontalAlignment.Right; 
       break; 
      default: 
       return base.ProcessCmdKey(ref msg, keyData); 
     } 
     return true; 
    } 
} 
+0

很好的答案,但它拋出'Object reference not set在'return base.ProcessCmdKey(ref msg,keyData);' – NokhodSiah

+0

@NokhodSiah對象'異常的一個實例我編輯代碼,設置'ShortcutsEnabled'爲'true' – AliTheOne

+0

然後它是正常的文本框。 – NokhodSiah