2011-07-24 34 views
1

我打算實現一個按鈕,它有一個下拉菜單,當選中時,這個菜單沒有選中時消失。我的問題是,當它或其菜單失去焦點時,我無法取消選中該複選框。複選框按鈕和ContextMenuStrip的下拉菜單

複選框的外觀模式是按鈕。

enter image description here

我的代碼:

private void cbSettings_CheckedChanged(object sender, EventArgs e) 
{ 
    if (cbSettings.Checked) {cmsSettings.Show(cbSettings, 0, cbSettings.Height);} 
    else {cmsSettings.Hide();} 
} 

我試圖取消對的ContextMenuStrip的VisibleChanged /關閉事件的複選框,但是這引起了菜單不隱藏(或隱藏,並立即顯示)。

回答

1

下面的例子當然不包括您需要交換CheckBox的BackGroundImage來指示CheckState的代碼。 「接線」事件應該是顯而易見的。希望這是有幫助的。

// tested in VS 2010 Pro, .NET 4.0 FrameWork Client Profile 
// uses: 
// CheckBox named 'checkBox1 
// ContextMenuStrip named 'contextMenuStrip1 
// TextBox named 'cMenuSelectionInfo for run-time checking of results 

    // used to position the ContextMenuStrip  
    private Point cPoint; 

    // context click ? dubious assumption that 'right' = context click 
    private bool cmOpenedRight; 

    // the clicked ToolStripMenuItem 
    private ToolStripMenuItem tsMIClicked; 

    private void checkBox1_MouseDown(object sender, MouseEventArgs e) 
    { 
     cmOpenedRight = e.Button == MouseButtons.Right; 
    } 

    private void checkBox1_CheckedChanged(object sender, EventArgs e) 
    { 
     // positioning the CheckBox like this 
     // is something in a 'real-world' example 
     // you'd want to do in the Form.Load event ! 
     // unless, of course, you'd made the CheckBox movable 
     if(checkBox1.Checked) 
     { 
      contextMenuStrip1.Show(); 
      cPoint = PointToScreen(new Point(checkBox1.Left, checkBox1.Top + checkBox1.Height)); 
      contextMenuStrip1.Location = cPoint; 
     } 
     else 
     { 
      contextMenuStrip1.Hide(); 
     } 
    } 

    private void contextMenuStrip1_ItemClicked(object sender, ToolStripItemClickedEventArgs e) 
    { 
     // assume you do not have to check for null here ? 
     tsMIClicked = e.ClickedItem as ToolStripMenuItem; 

     tbCbMenuSelectionInfo.Text = tsMIClicked + " : " + ! (tsMIClicked.Checked); 
    } 

    private void contextMenuStrip1_Closing(object sender, ToolStripDropDownClosingEventArgs e) 
    { 
     e.Cancel = checkBox1.Checked; 
    } 

    private void contextMenuStrip1_Closed(object sender, ToolStripDropDownClosedEventArgs e) 
    { 
     if (cmOpenedRight) 
     { 
      tbCbMenuSelectionInfo.Text += " : closed because : " + e.CloseReason.ToString(); 
     } 
    } 
+0

它正在工作,但它有一個錯誤。如果按下按鈕並拖放窗口,則菜單將保留在屏幕上的相同位置。 –

+0

介紹一個全新的規範:你可以通過點擊拖動一個按鈕拖拉一個窗口(我必須說一個非常奇怪的規範),並期望ContextMenu隨它移動:需要一個全新的解決方案。最好,比爾 – BillW

+0

我的意思是當菜單可見時,如果移動主窗口菜單保持在同一位置。通常菜單移動。 –

1

我覺得你不選中上下文菜單中的關閉事件的複選框的方法是一個很好的,你需要的是一點點「事件取消邏輯」(C),像這樣:

private void OnContextClosing(object sender, EventArgs e) 
{ 
    _cancel = true; 
    cbSettings.Checked = false; 
    _cancel = false; 
} 

private void cbSettings_CheckedChanged(object sender, EventArgs e) 
{ 
    if(_cancel) 
     return; 

    if (cbSettings.Checked) {cmsSettings.Show(cbSettings, 0, cbSettings.Height);} 
    else {cmsSettings.Hide();} 
} 

這將使您的CheckChanged事件不再檢查您的複選框。

+0

不,對不起,這是行不通的。 –

+0

結果如何? – CodingGorilla

+0

該按鈕在離開時取消選中,但當點擊兩次或更多按鈕時,contextmenustrip仍然可見。 –