2017-07-11 58 views
0

在任何情況下都將顯示上下文菜單,但只有在鼠標位於選定文本上且不在richTextBox區域中的任何位置時才應啓用該菜單。只有當鼠標位置位於richTextBox中的選定文本上時,我如何才能啓用contextmenu菜單?

private void richTextBox1_MouseMove(object sender, MouseEventArgs e) 
     { 
      if (e.Button == System.Windows.Forms.MouseButtons.Left) 
      { 
       for (int i = 0; i < contextMenu.MenuItems.Count; i++) 
       { 
        if (richTextBox1.SelectedText != "") 
        { 
         contextMenu.MenuItems[i].Enabled = true; 
        } 
        else 
        { 
         contextMenu.MenuItems[i].Enabled = false; 
        } 
       } 
      } 
     } 

僅當選擇了文本時,才啓用菜單項。 現在我想添加另一個條件,如果鼠標位置在選定的文本上,則啓用true。

如果不啓用false。因此,如果選擇文本,則應該有兩個條件,如果鼠標位於所選文本的任何部分,則應該有兩個條件。還不確定如何使第二個條件。

更新

我現在嘗試:

private void richTextBox1_MouseMove(object sender, MouseEventArgs e) 
     { 
      if (e.Button == System.Windows.Forms.MouseButtons.Left) 
      { 
       int positionToSearch = richTextBox1.GetCharIndexFromPosition(e.Location); 
       bool isInSelectedText = positionToSearch >= richTextBox1.SelectionStart && positionToSearch < richTextBox1.SelectionStart + richTextBox1.SelectionLength; 
       for (int i = 0; i < contextMenu.MenuItems.Count; i++) 
       { 
        if (richTextBox1.SelectedText != "" && 
         isInSelectedText == true) 
        { 
         contextMenu.MenuItems[i].Enabled = true; 
        } 
        else 
        { 
         contextMenu.MenuItems[i].Enabled = false; 
        } 
       } 
      } 
     } 

但是,當我提出用鼠標右鍵單擊選中的文本就會使菜單但當時如果我在其他地方右鍵單擊RichTextBox的區域該菜單仍然處於啓用狀態,我希望僅在選定的文本上啓用該菜單。

如果沒有選中的文本,則啓用虛假菜單。

我在窗體加載事件添加上下文菜單一次:

private void Form1_Load(object sender, EventArgs e) 
     { 
      contextMenu = new System.Windows.Forms.ContextMenu(); 
      MenuItem menuItem = new MenuItem("Cut"); 
      menuItem.Click += new EventHandler(CutAction); 
      contextMenu.MenuItems.Add(menuItem); 
      menuItem = new MenuItem("Copy"); 
      menuItem.Click += new EventHandler(CopyAction); 
      contextMenu.MenuItems.Add(menuItem); 
      menuItem = new MenuItem("Paste"); 
      menuItem.Click += new EventHandler(PasteAction); 
      contextMenu.MenuItems.Add(menuItem); 
      richTextBox1.ContextMenu = contextMenu; 

      for (int i = 0; i < contextMenu.MenuItems.Count; i++) 
      { 
       contextMenu.MenuItems[i].Enabled = false; 
      } 
     } 
+1

你的意思是像懸停在選定的文本應該啓用菜單? –

+0

@Charles可能是的。 –

回答

1

您可以使用richTextBox.GetCharIndexFromPosition功能字符最接近來獲得(在RichTextBox的文本位置)的索引到檢查點。然後簡單地驗證,如果該索引是選擇

int positionToSearch = richTextBox1.GetCharIndexFromPosition(e.Location); 
bool isInSelectedText = positionToSearch >= richTextBox1.SelectionStart && positionToSearch < richTextBox1.SelectionStart + richTextBox1.SelectionLength 

的開始和結束時,如果在MouseMove按下左按鈕作爲在下面的行檢測用戶選擇的方式由於要檢查之間if(e.Button == System.Windows.Forms.MouseButtons.Left)

您的代碼不處理取消選擇以及以不同方式進行文本選擇(鍵盤) 通過連接到SelectionChangedEvent來檢測選擇,可以改進此操作。 關於從鍵盤啓動上下文菜單也可以這麼說。

處理這兩種情況下,您可以:

介紹兩個領域:

bool _isTextSelected = false; 
bool _isInSelectedText = false; 

提取代碼,以使上下文菜單中單獨的方法

private void EnableContextMenu() 
    { 
     for (int i = 0; i < contextMenu.MenuItems.Count; i++) 
     { 
      if (_isInSelectedText == true && _isTextSelected) 
      { 
       contextMenu.MenuItems[i].Enabled = true; 
      } 
      else 
      { 
       contextMenu.MenuItems[i].Enabled = false; 
      } 

     } 
    } 

調用此方法時,任何的這兩種狀態的變化

private void richTextBox1_SelectionChanged(object sender, EventArgs e) 
{ 
    _isTextSelected = richTextBox1.SelectedText != ""; 
    EnableContextMenu(); 
} 

private void richTextBox1_MouseMove(object sender, MouseEventArgs e) 
{ 
    int positionToSearch = richTextBox1.GetCharIndexFromPosition(e.Location); 
    _isInSelectedText = positionToSearch >= richTextBox1.SelectionStart && positionToSearch < richTextBox1.SelectionStart + richTextBox1.SelectionLength; 
    EnableContextMenu(); 
} 
+0

我試過並更新了我的問題,我是如何嘗試解決方案的,但在問題中解釋不好。也許我沒有在移動事件中的代碼中使用它。 –

+1

@testmantm你的代碼只在e.Button = System.Windows.Forms.MouseButtons.Left爲true時觸發。 – user6144226

+1

@testmantm我看你接受不論。我補充說明了爲什麼它的行爲如此。 – user6144226

1

以下是一張就可以了。在這個示例中,我不打開上下文菜單,而是在正確的位置單擊鼠標時將其附加到RichTextBox。

這段代碼需要一點工作才能生產,特別是在定義「fudgeFactored」區域的時候,但前提是有的。在下面的代碼中,我只關心文本選擇的起始位置,但如果我要將其作爲生產腳本,我會查看它開始的位置,結束位置,然後將fudgeFactor添加到它。

using System; 
using System.Drawing; 
using System.Windows.Forms; 

namespace ContextMenuOnRichText_45042370 
{ 
    public partial class Form1 : Form 
    { 
     public Form1() 
     { 
      InitializeComponent(); 
     } 


     private void doit(Point mouseClickedAtPosition) 
     { 
      if (txtbx_1.SelectedText != null) 
      { 
       //find out where the selected text is 
       Point selectionposition = txtbx_1.GetPositionFromCharIndex(txtbx_1.SelectionStart); 

       /* 
       * the user is not likely to click in the right spot every time, 
       * so let's make a fudgeFactor 
       */ 
       int fudgeFactor = 15; 


       if ((mouseClickedAtPosition.X <= selectionposition.X + fudgeFactor && mouseClickedAtPosition.X >= selectionposition.X - fudgeFactor) && (mouseClickedAtPosition.Y <= selectionposition.Y + fudgeFactor && mouseClickedAtPosition.Y >= selectionposition.Y - fudgeFactor)) 
       { 
        /* 
        * If the right click happened within the fudgeFactored area, then append to the box(open your menu) 
        */ 
        txtbx_1.AppendText("positions are matching"); 
       } 
       else 
       { 
        /* 
        * User did not right-click in the proper area 
        * don't show your menu 
        */ 
        txtbx_1.AppendText("not matching" + Environment.NewLine); 
       } 
      } 
     } 

     private void txtbx_1_MouseDown(object sender, MouseEventArgs e) 
     { 
      if (e.Button == MouseButtons.Right) 
      { 
       doit(e.Location); 
      } 
     } 
    } 
} 
+0

尋找方法來「正確地」測量一個RTF字符串之後,我確信一個fudgeFactor並不是一個好主意。 – user6144226

相關問題