gpt4 book ai didi

c# - ContexMenuStrip 奇怪的特定怪异行为

转载 作者:太空宇宙 更新时间:2023-11-03 12:24:21 25 4
gpt4 key购买 nike

我正在测试我在我的应用程序中遇到的一个奇怪的错误,最终能够创建一个简单的复制品:

using System;
using System.Windows.Forms;

static class Program
{
[STAThread]
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var notifyIcon1 = new NotifyIcon();
notifyIcon1.Icon = new Form().Icon;
notifyIcon1.Visible = true;
var contextMenuStrip1 = new ContextMenuStrip();
ToolStripMenuItem menu1 = new ToolStripMenuItem();
menu1.Text = "test";
contextMenuStrip1.Items.Add(menu1);
contextMenuStrip1.Items.Add("t1");
contextMenuStrip1.Items.Add("t2");

notifyIcon1.ContextMenuStrip = contextMenuStrip1;
var timer = new System.Timers.Timer();
timer.Interval = 3000;
timer.Elapsed += (sender, e) => /* Runs in a different thread from UI thread.*/
{
if (contextMenuStrip1.InvokeRequired)
contextMenuStrip1.Invoke(new Action(() =>
{
menu1.DropDownItems.Add(e.SignalTime.ToString() + "extra");
menu1.DropDownItems.Add(e.SignalTime.ToString());
}));
else
{
menu1.DropDownItems.Add(e.SignalTime.ToString() + "extra");
menu1.DropDownItems.Add(e.SignalTime.ToString());
}
};
timer.Start();
Application.Run();
}
}

请注意,上下文菜单不会打开,但执行以下任何操作都可以打开它:

  • 删除每次执行添加的“额外”下拉项。 (准确的说每次执行仅添加 0 或 1 个)
  • 删除 InvokeRequired == false 上的部分代码(这允许每次执行添加多个项目)
  • 删除 t1t2 元素。 (它仍然可以在没有根中的附加项目)

这是错误还是我做错了什么?

编辑:额外发现的条件(感谢@derape):

  • 如果您将 else 分支移动到单独的方法,它会起作用,但如果您在 InvokeRequired 分支中使用相同的方法,则不起作用。但是,使用具有不同名称和相同代码的 2 种方法是可行的。

可能的解决方法是在满月期间穿着虎皮跳舞。

最佳答案

如果你看InvokeRequired然后您将看到对 IsHandleCreated 的显式检查,它返回 false。该返回值并不意味着您不必调用,它只是意味着您不能调用。

让您更加困惑的是:您必须调用,但现在还不能。

如果尚未创建句柄,您可以决定不做任何事情(并且只是错过项目),或者组织单独的队列来存储项目直到句柄可用,类似于:

var items = new List<string>();
timer.Elapsed += (sender, e) =>
{
if (contextMenuStrip1.IsHandleCreated) // always invoke, but check for handle
contextMenuStrip1.Invoke(new Action(() =>
{

menu1.DropDownItems.Add(e.SignalTime.ToString() + "extra");
menu1.DropDownItems.Add(e.SignalTime.ToString());
contextMenuStrip1.Refresh();
}));
else
{
lock (items)
{
items.Add(e.SignalTime.ToString() + "extra");
items.Add(e.SignalTime.ToString());
}
}
};
contextMenuStrip1.HandleCreated += (s, e) =>
{
lock (items)
{
foreach (var item in items)
menu1.DropDownItems.Add(item);
contextMenuStrip1.Refresh();
}
items = null;
};

另一个注意事项:如果项目被添加到子菜单,您将需要调用 Refresh,当菜单打开时,子菜单还没有,winforms 的奇怪事情。

关于c# - ContexMenuStrip 奇怪的特定怪异行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45794502/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com