C# 下拉菜单的复选框按钮和上下文菜单提示
我试图实现一个按钮,当选中时,它有一个下拉菜单,当不选中时,这个菜单就消失了。我的问题是,当复选框或其菜单失去焦点时,我无法取消选中复选框 复选框的外观模式为“按钮” 我的代码:C# 下拉菜单的复选框按钮和上下文菜单提示,c#,winforms,checkbox,contextmenu,contextmenustrip,C#,Winforms,Checkbox,Contextmenu,Contextmenustrip,我试图实现一个按钮,当选中时,它有一个下拉菜单,当不选中时,这个菜单就消失了。我的问题是,当复选框或其菜单失去焦点时,我无法取消选中复选框 复选框的外观模式为“按钮” 我的代码: private void cbSettings_CheckedChanged(object sender, EventArgs e) { if (cbSettings.Checked) {cmsSettings.Show(cbSettings, 0, cbSettings.Height);} else
private void cbSettings_CheckedChanged(object sender, EventArgs e)
{
if (cbSettings.Checked) {cmsSettings.Show(cbSettings, 0, cbSettings.Height);}
else {cmsSettings.Hide();}
}
我曾尝试取消选中contextMenuStrip的VisibleChanged/Closed事件上的复选框,但这导致菜单无法隐藏(或立即隐藏并显示)。我认为您取消选中上下文菜单的Closed事件上的复选框的方法是一种很好的方法,您需要的是一点“事件取消逻辑”(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事件重新检查您的复选框。下面的示例当然不包括交换复选框背景图像以指示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();
}
}
按钮在左侧取消选中,但当按钮被单击两次或两次以上时,contextmenustrip仍然可见。您可能需要在其他事件中放置类似的逻辑来尝试和管理所有其他事件,其想法是,当您在打开或关闭上下文菜单的过程中,您会取消任何其他进入的事件。或者,有很多第三方下拉按钮控件,你可能想调查其中一个。它正在工作,但有一个bug。如果您按下按钮,然后拖放窗口,菜单将保持在屏幕上的相同位置。引入一个全新的规范:您可以通过单击拖动按钮来拖放窗口(我必须说,这是一个非常奇怪的规范),并期望ContextMenu随之移动:需要一个全新的解决方案。最棒的是,BillI的意思是,如果你移动主窗口,菜单将保持在相同的位置,那么当菜单可见时。通常,菜单会移动。