|
|
豪气的小摩托 · 3、导出的Android-Studio工程 ...· 1 年前 · |
|
|
冷冷的草稿本 · 请问这个JS代码怎么解释? - 知乎· 2 年前 · |
|
|
斯文的烤面包 · Linux和Windows创建指定大小文件方 ...· 2 年前 · |
我有一个C#.NET 2.0 WinForms应用程序。我的应用程序有一个控件,它是两个子控件的容器:一个标签和某种编辑控件。可以这样想,其中外部框是父控件:
+---------------------------------+
| [Label Control] [Edit Control] |
+---------------------------------+
当鼠标进入或离开父控件时,我试图做一些事情,但我不在乎鼠标是否移动到它的一个子控件中。我想要一个单独的标志来表示“鼠标在父或子控件的某个位置”和“鼠标已经移出父控件边界”。
我尝试过在父控件和两个子控件上处理MouseEnter和MouseLeave,但这意味着当鼠标在控件上移动时,操作会开始和结束多次。换句话说,我明白了:
Parent.OnMouseEnter (start doing something)
Parent.OnMouseLeave (stop)
Child.OnMouseEnter (start doing something)
Child.OnMouseLeave (stop)
Parent.OnMouseEnter (start doing something)
Parent.OnMouseLeave (stop)
中间的OnMouseLeave事件会导致一些不希望的效果,因为我正在做的事情开始后停止。。
经过更多的研究,使用此方法,我创建了鼠标钩子的.NET版本:
class MouseMessageFilter : IMessageFilter, IDisposable
public MouseMessageFilter()
public void Dispose()
StopFiltering();
#region IMessageFilter Members
public bool PreFilterMessage(ref Message m)
// Call the appropriate event
return false;
#endregion
#region Events
public class CancelMouseEventArgs : MouseEventArgs
{...}
public delegate void CancelMouseEventHandler(object source, CancelMouseEventArgs e);
public event CancelMouseEventHandler MouseMove;
public event CancelMouseEventHandler MouseDown;
public event CancelMouseEventHandler MouseUp;
public void StartFiltering()
StopFiltering();
Application.AddMessageFilter(this);
public void StopFiltering()
Application.RemoveMessageFilter(this);
}
然后,我可以在我的容器控件中处理MouseMove事件,检查鼠标是否在我的父控件中,并开始工作。
在我的表单类中,我创建并连接了过滤器:
public class MyForm : Form
MouseMessageFilter msgFilter;
public MyForm()
msgFilter = new MouseMessageFilter();
msgFilter.MouseDown += new MouseMessageFilter.CancelMouseEventHandler(msgFilter_MouseDown);
msgFilter.MouseMove += new MouseMessageFilter.CancelMouseEventHandler(msgFilter_MouseMove);
private void msgFilter_MouseMove(object source, MouseMessageFilter.CancelMouseEventArgs e)
if (CheckSomething(e.Control)
e.Cancel = true;
}
添加一个透明控件,该控件占用要接收MouseEnter和MouseLeave事件的容器的整个空间。
public class TranspCtrl : Control
public TranspCtrl()
SetStyle(ControlStyles.SupportsTransparentBackColor, true);
SetStyle(ControlStyles.Opaque, true);
this.BackColor = Color.Transparent;
protected override CreateParams CreateParams
CreateParams cp = base.CreateParams;
cp.ExStyle = cp.ExStyle | 0x20;
return cp;
}
示例用法:
public class ChangeBackgroundOnMouseEnterAndLeave
public Panel Container;
public Label FirstLabel;
public Label SecondLabel;
public ChangeBackgroundOnMouseEnterAndLeave()
Container = new Panel();
Container.Size = new Size(200, 60);
FirstLabel = new Label();
FirstLabel.Text = "First Label";
FirstLabel.Top = 5;
SecondLabel = new Label();
SecondLabel.Text = "Second Lable";
SecondLabel.Top = 30;
FirstLabel.Parent = Container;
SecondLabel.Parent = Container;
Container.BackColor = Color.Teal;
var transparentControl = new TranspCtrl();
transparentControl.Size = Container.Size;
transparentControl.MouseEnter += MouseEntered;
transparentControl.MouseLeave += MouseLeft;
transparentControl.Parent = Container;
transparentControl.BringToFront();
void MouseLeft(object sender, EventArgs e)
Container.BackColor = Color.Teal;
void MouseEntered(object sender, EventArgs e)
Container.BackColor = Color.Pink;
public partial class Form1 : Form
public Form1()
InitializeComponent();