Кнопка CheckBox и ContextMenuStrip для выпадающего меню - PullRequest
1 голос
/ 25 июля 2011

Я пытаюсь реализовать кнопку, у которой есть выпадающее меню при проверке, и это меню исчезает, когда не проверено.Моя проблема в том, что я не могу снять флажок, когда он или его меню потеряли фокус.

Режим появления флажка - кнопка.

enter image description here

Мой код:

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

Я пытался снять флажок checkBox в событии VisibleChanged / Closed из contextMenuStrip, но это привело к тому, что меню не скрылось (или сразу скрылось и отобразилось).

Ответы [ 2 ]

1 голос
/ 27 июля 2011

Приведенный ниже пример, конечно, не включает код, который вам понадобится для замены BackGroundImage CheckBox для указания 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();
        }
    }
1 голос
/ 25 июля 2011

Я думаю, что ваш подход к снятию флажка в закрытом событии контекстного меню - это хороший вариант, вам нужно немного «логики отмены событий» (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 повторно проверить ваш флажок.

...