“控件设置ContextMenuStrip属性后,第一次右击不显示菜单”解决方法

今天写一小软件的时候,遇到如标题所述问题,具体如下:

这软件有个“选项”对话框,我在主界面中的“选项”菜单Click事件中创建并显示该对话框,代码如下:

private void ToolStripMenuItem_Options_Click(object sender, EventArgs e)
{    
	Form1 form = new Form1();    
	form.ShowDialog(this);
}

在这个选项对话框中,有个Panel,我为其关联一个上下文菜单,即设置了其ContextMenuStrip属性,大致代码如下(代码是生成器生成的,这里只贴出关键部分):

ContextMenuStrip contextMenuStrip1 = new ContextMenuStrip(this.components);
//...添加一些ToolStripMenuItem.
panel1.ContextMenuStrip = this.contextMenuStrip1;


如此简单之代码,何况又是用VS的界面编辑器生成的,不料出现灰常郁闷之现象:点击“选项”菜单跳出对话框后,第一次右击panel1,居然并没有弹出菜单,之后右击则正常。


经过各种尝试,发现:ToolStripMenuItem的Click事件处理函数中创建对话框并处理子对话框的ToolStripMenuItem的Click事件,存在第一个事件捕获不到的问题。解决方法是:通过在ToolStripMenuItem的Click事件中另启线程来创建并显示对话框,就没问题了,代码如下:

private void ToolStripMenuItem_Options_Click(object sender, EventArgs e)
{
	Thread thread = new Thread(() =>
	{
		Form1 form = new Form1();
		form.ShowDialog(this);
	});
	thread.Start();
}

虽然问题得已解决,不过我并不清楚其中的原因。如果说原来在click中创建模态对话框,影响事件传递也不对,因为我改成非模态对话框也不行。且button的click也是模态,可是却没问题。只能说对话框在新线程中创建,与在ToolStripMenuItem的Click事件处理线程中创建,对其后的事件传递,有一定的影响。俺的拙见就是这样,大家若有何高见,欢迎回复。
  • 3
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
要实现失去焦点仍然高亮显示,可以在TreeView件的DrawMode属性中选择OwnerDrawAll,然后在DrawNode事件中自定义节点的绘制方式,包括选中和非选中状态的绘制。具体实现可以参考以下代码: ``` private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e) { // 绘制背景色 Color bgColor = e.Node.IsSelected ? SystemColors.Highlight : SystemColors.Window; using (SolidBrush brush = new SolidBrush(bgColor)) { e.Graphics.FillRectangle(brush, e.Bounds); } // 绘制文本 TextRenderer.DrawText(e.Graphics, e.Node.Text, Font, e.Bounds, SystemColors.WindowText, TextFormatFlags.Left | TextFormatFlags.VerticalCenter | TextFormatFlags.SingleLine); // 绘制焦点框 if (e.Node.IsSelected) { ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds); } } ``` 要实现节点时才弹出菜单,可以在TreeView件的MouseDown事件中判断鼠标点的位置是否在节点上,如果是则显示菜单。具体实现可以参考以下代码: ``` private void treeView1_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { TreeNode clickedNode = treeView1.GetNodeAt(e.Location); if (clickedNode != null && clickedNode.Bounds.Contains(e.Location)) { contextMenuStrip1.Show(treeView1, e.Location); } } } ``` 要实现空白处不弹出菜单,可以在TreeView件的MouseDown事件中判断鼠标点的位置是否在节点上,如果不是则取消菜单显示。具体实现可以参考以下代码: ``` private void treeView1_MouseDown(object sender, MouseEventArgs e) { if (e.Button == MouseButtons.Right) { TreeNode clickedNode = treeView1.GetNodeAt(e.Location); if (clickedNode != null && clickedNode.Bounds.Contains(e.Location)) { contextMenuStrip1.Show(treeView1, e.Location); } else { e.Cancel = true; } } } ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值