C# 通过单击 NotifyIcon(任务栏图标)切换窗口
我的 C# 应用程序由一个任务栏图标 (NotifyIcon) 和一个最初隐藏的顶部窗口组成。我希望用户能够通过单击 NotifyIcon(左键单击)来切换窗口可见性。当失去焦点时,窗口也会被隐藏。
这是我到目前为止所拥有的,一个子类System.Windows.Forms.Form
:
初始化:
this.ControlBox = false;
this.ShowIcon = false;
this.ShowInTaskbar = false;
// Instance variables: bool allowVisible;
// System.Windows.Forms.NotifyIcon notifyIcon;
this.allowVisible = false;
this.notifyIcon = new NotifyIcon();
this.notifyIcon.MouseUp += new MouseEventHandler(NotifyIconClicked);
this.Deactivate += new EventHandler(HideOnEvent);
实例方法:
private void NotifyIconClicked(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
if (this.Visible)
this.Hide();
else
this.Show();
}
}
new public void Show()
{
this.allowVisible = true;
this.Visible = true;
this.Activate();
}
new public void Hide()
{
this.allowVisible = false;
this.Visible = false;
}
private void HideOnEvent(object sender, EventArgs e)
{
this.Hide();
}
protected override void SetVisibleCore(bool visible)
{
base.SetVisibleCore(this.allowVisible ? visible : this.allowVisible);
}
单击图标会显示应有的窗口。但是,只要按下鼠标,再次单击它就会隐藏它,然后将其重置为可见。
我的猜测是,鼠标按下事件窃取了窗口的焦点,因此它消失了。然后触发鼠标向上事件,显示隐藏的窗口。
我的下一个想法是读取鼠标按下事件时的窗口可见性,因此我测试了三个事件并记录了它们被调用时的 UNIX 时间:
notifyIcon.MouseDown
notifyIcon.MouseUp
this.LostFocus
结果非常奇怪:假设窗口是可见的。当我单击图标时会发生这种情况:立即调用焦点丢失。一旦我释放鼠标,鼠标按下就会被调用,就在鼠标弹起事件之前。
1312372231 focus lost
1312372235 mouse down
1312372235 mouse up
为什么鼠标按下事件会延迟?
如何切换窗口?
My C# application consists of a taskbar icon (NotifyIcon) and an overhead window initially hidden. I want the user to be able to toggle the window visibility by clicking on the NotifyIcon (left, single click). Also the window is being hidden when loosing focus.
This is what I have so far, a subclassed System.Windows.Forms.Form
:
Initialization:
this.ControlBox = false;
this.ShowIcon = false;
this.ShowInTaskbar = false;
// Instance variables: bool allowVisible;
// System.Windows.Forms.NotifyIcon notifyIcon;
this.allowVisible = false;
this.notifyIcon = new NotifyIcon();
this.notifyIcon.MouseUp += new MouseEventHandler(NotifyIconClicked);
this.Deactivate += new EventHandler(HideOnEvent);
Instance methods:
private void NotifyIconClicked(object sender, MouseEventArgs e)
{
if (e.Button == System.Windows.Forms.MouseButtons.Left)
{
if (this.Visible)
this.Hide();
else
this.Show();
}
}
new public void Show()
{
this.allowVisible = true;
this.Visible = true;
this.Activate();
}
new public void Hide()
{
this.allowVisible = false;
this.Visible = false;
}
private void HideOnEvent(object sender, EventArgs e)
{
this.Hide();
}
protected override void SetVisibleCore(bool visible)
{
base.SetVisibleCore(this.allowVisible ? visible : this.allowVisible);
}
Clicking the icon reveals the window like it should. But clicking it again hides it for as long as the mouse is being pressed, then resets it to visible.
My guess is that the mouse down event steals the focus from the window so it disappears. Then the mouse up event is triggered, showing the window as it is hidden.
My next idea was to read the window visibility at mouse down event, so I tested three events and logged the UNIX time as they are called:
notifyIcon.MouseDown
notifyIcon.MouseUp
this.LostFocus
The result is pretty weird: Let's say the window is visible. This happens when I click the icon: Focus lost is called immediately. Mouse down is called as soon as I release the mouse, right before the mouse up event.
1312372231 focus lost
1312372235 mouse down
1312372235 mouse up
Why is the mouse down event delayed?
How can I toggle the window?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我想这可能对你有用。
我发现一个专家交流帖子,其中包含一个类,该类提供了一种检查光标当前是否位于托盘上的方法。
NotifyIcon - 检测 MouseOut
使用此类我修改了您的 HideOnEvent 方法,例如所以:
这似乎可以满足您的需要。
我已经包含了以下课程:
这不是一个完美的解决方案,但我希望这会有所帮助。
I think this may work for you.
I found an expert exchange post which contains a class which provides a method for checking whether the cursor is currently over the tray.
NotifyIcon - Detect MouseOut
Using this class I modified your HideOnEvent method like so:
Which seems to do what you need.
I have included the class below:
It is not a perfect solution but I hope this helps.