我有一个继承自System.Windows.Forms.Control的自定义控件,我在MouseEnter和MouseLeave事件上更改了BackColor属性。我用它来创建一个自定义按钮类。一切都很好,除了一个按钮,其点击处理程序最小化包含所有按钮的主窗体。当通过单击此按钮最小化表单时,该按钮的MouseLeave事件永远不会触发(MouseUp,Click,其他人仍然会这样做)。
当我将应用程序恢复到正常窗口状态时,问题就开始了。如果我将鼠标放在我的自定义最小化按钮上,则没有MouseEnter事件。如果我离开按钮(没有点击),那么我终于得到一个MouseLeave。它基本上似乎是因为原始MouseLeave在主窗体最小化时从未触发过,所以它并不认为MouseEnter应该是可能的。因此,在你再次进入和退出之前,一切都基本上已经破裂了。
我尝试让我的点击处理程序手动调用OnMouseLeave并且没有改变任何内容,但我没有在EventArgs参数中特别指定任何内容,如果它是关键部分。
关于我缺少什么才能让它发挥作用的任何想法?
编辑:这是完整的项目:
https://dl.dropboxusercontent.com/u/32742882/Button.zip
事实证明,问题与最小化至notifyIcon有关,并未显示正常的最小化。
编辑:添加代码......
public class IconButton : Control
{
public bool pressed;
static readonly public bool boundingBox = false;
static readonly Color darkGray = Color.FromArgb(255, 112, 112, 112);
static readonly Color mediumGray = Color.FromArgb(255, 145, 145, 145);
static readonly Color lightGray = Color.FromArgb(255, 178, 178, 178);
static readonly Color hoverColor = Color.FromArgb(255, 209, 226, 242);
static readonly Color backgroundColor = boundingBox ? Color.FromArgb(255, 227, 227, 227) : SystemColors.Control;
static readonly Color pressColor = Color.FromArgb(255, 180, 212, 244);
static readonly Color enabledTextColor = Color.Black;
static readonly Color disabledTextColor = mediumGray;
public IconButton()
{
this.BackColor = backgroundColor;
this.DoubleBuffered = true;
this.Margin = new Padding(2);
}
protected override void OnMouseEnter(EventArgs e)
{
if (Enabled)
{
this.BackColor = hoverColor;
}
base.OnMouseEnter(e);
}
protected override void OnMouseLeave(EventArgs e)
{
this.BackColor = backgroundColor;
base.OnMouseLeave(e);
}
protected override void OnMouseDown(MouseEventArgs e)
{
if (Enabled)
{
this.BackColor = pressColor;
}
base.OnMouseDown(e);
}
protected override void OnMouseUp(MouseEventArgs e)
{
if (Enabled)
{
if (this.ClientRectangle.Contains(e.Location))
{
this.BackColor = hoverColor;
}
else
{
this.BackColor = backgroundColor;
}
}
base.OnMouseUp(e);
}
}
最终编辑:
所以问题与直接在MainForm_SizeChanged处理程序中调用ShowInTaskbar = false有关。这似乎阻止了事件处理的轨道并导致问题。所以相反,我现在这行延迟250毫秒,一切似乎都很好。我打算提出如何使这个更干净的建议......
private void Form1_SizeChanged(object sender, EventArgs e)
{
if (WindowState == FormWindowState.Minimized)
{
notifyIcon.Visible = true;
notifyIcon.BalloonTipText = "We got minimized";
notifyIcon.Text = "Minimized";
notifyIcon.ShowBalloonTip(1000);
TaskScheduler scheduler = TaskScheduler.FromCurrentSynchronizationContext();
Task.Delay(250).ContinueWith(_ => {
this.ShowInTaskbar = false;
}, CancellationToken.None, TaskContinuationOptions.None, scheduler);
}
else if (WindowState == FormWindowState.Normal)
{
ShowInTaskbar = true;
notifyIcon.Visible = false;
}
}
答案 0 :(得分:1)
因为您将ShowInTaskbar设置为false,所以意图实际上是隐藏表单,而不是最小化它。为此,您需要intercept the minimizing event,因此请尝试将代码更改为以下内容:
private void ToggleView() {
if (this.Visible) {
this.Hide();
notifyIcon.Visible = true;
notifyIcon.BalloonTipText = "We got minimized";
notifyIcon.Text = "Minimized";
notifyIcon.ShowBalloonTip(1000);
} else {
this.Show();
notifyIcon.Visible = false;
}
}
protected override void WndProc(ref Message m) {
const int WM_SYSCOMMAND = 0x0112;
const int SC_MINIMIZE = 0xf020;
if (m.Msg == WM_SYSCOMMAND) {
if (m.WParam.ToInt32() == SC_MINIMIZE) {
m.Result = IntPtr.Zero;
ToggleView();
return;
}
}
base.WndProc(ref m);
}
public void button_click(object sender, EventArgs e) {
ToggleView();
}
private void notifyIcon_MouseClick(object sender, MouseEventArgs e) {
ToggleView();
}
请注意,我删除了Form1_SizeChanged事件。
答案 1 :(得分:-1)
private void Form1_Resize ( object sender , EventArgs e )
{
if ( WindowState == FormWindowState.Minimized )
{
// code on minimized
}
else if(WindowsState == FormWindowState.Maximized)
{
// code on maximized
}
}