C# MouseHover和MouseLeave事件控制

C# MouseHover和MouseLeave事件控制,c#,opacity,C#,Opacity,我正在构建一个简单的表单,有一个简单的效果——当鼠标不在表单上时,不透明度降低,当鼠标在表单上时,表单变得不透明。我目前遇到两个困难:- 首先,我这样做了- this.MouseHover += new EventHandler(Form1_MouseHover); this.MouseLeave += new EventHandler(Form1_MouseLeave); 但我的表单中也有一个richtextbox,当鼠标移过它时,表单再次失去了不透明度。我还要补充一点:- richT

我正在构建一个简单的表单,有一个简单的效果——当鼠标不在表单上时,不透明度降低,当鼠标在表单上时,表单变得不透明。我目前遇到两个困难:-

  • 首先,我这样做了-

     this.MouseHover += new EventHandler(Form1_MouseHover);
     this.MouseLeave += new EventHandler(Form1_MouseLeave);
    
    但我的表单中也有一个richtextbox,当鼠标移过它时,表单再次失去了不透明度。我还要补充一点:-

     richTextBox1.MouseHover+=new EventHandler(Form1_MouseHover);
     richTextBox1.MouseLeave+=new EventHandler(Form1_MouseLeave);
    
    想知道是否有更好的方法,因为richtextbox和表单边界之间仍然有一些间隙,并且当鼠标光标移动到那个里时表单会失去不透明度

  • 如果鼠标不在窗体上(最初假设),则窗体的不透明程度较低。现在,我希望当鼠标移到窗体上时,窗体立即变得不透明,但只有当鼠标在窗体上的移动完全停止时,才会发生这种情况。如果我一直在窗体上移动鼠标,它不会变得不透明。这是事件存储在消息队列中的方式的问题,还是我能够做些什么,因为我已经看到了我正在尝试实现的应用程序的效果


  • 我可能错了,但为什么要使用鼠标悬停事件?检测鼠标何时停止在窗体上移动,通常用于显示工具提示

    您要查找的事件与鼠标进入窗口的客户机矩形时的事件相反,并检测该事件

    在Leave事件中,只需检查光标位置是否在windowclient rect中,以了解它是否确实离开了窗体,或者它是否位于子控件的顶部

    Ofc如果使用区域,则必须修改代码

     private void Form1_MouseEnter(object sender, EventArgs e)
        {
            this.Opacity = 1;
        }
    
        private void Form1_MouseLeave(object sender, EventArgs e)
        {
    
            if (!this.ClientRectangle.Contains(this.PointToClient(Cursor.Position)))
            {
                this.Opacity = 0.5;
            }
        }
    

    MouseEnter/Leave事件太不可靠,无法执行此操作。最好的办法是使用一个计时器来检查鼠标是否还在窗口内。在表单上放置计时器,并使代码如下所示:

    public partial class Form1 : Form {
        public Form1() {
            InitializeComponent();
            this.Opacity = 0.99;
            timer1.Interval = 200;
            timer1.Enabled = true;
            timer1.Tick += timer1_Tick;
        }
        protected override void OnLoad(EventArgs e) {
            base.OnLoad(e);
            timer1_Tick(this, e);
        }
        private void timer1_Tick(object sender, EventArgs e) {
            this.Opacity = this.Bounds.Contains(this.PointToClient(Cursor.Position)) ? 0.99 : 0.20;
        }
    }
    

    顺便说一句:避免将不透明度增加到1.0,这会强制重新创建本机窗口,并且会产生很多副作用。使用0.99是最好的。

    添加一个计时器控件,然后在计时器的滴答声事件中使用下面的控件。如果表单中有自定义/用户控件,上述答案将不起作用。因此必须使用
    ClientRectangle

    this.Opacity = this.ClientRectangle.Contains(this.PointToClient(Cursor.Position)) ? 0.99 : 0.20;
    

    我忘了提到我尝试MouseHover作为MouseEnter本身的一个改变,我想这可能是为什么表单在richtextbox和表单之间时会失去不透明性的问题(通常情况下,当普通的东西不起作用时,你总是开始尝试愚蠢的东西:-D)每当鼠标进入richtextbox和Form boundry之间的细微间隙时,它仍然会丢失不透明度。此外,当我在标题栏上使用鼠标时,表单不会变得不透明。给你什么?是的。它没有按预期工作。我想我不明白什么。代码更新了。该错误是因为Cursor.Position返回鼠标在屏幕坐标中的位置,必须首先转换鼠标位置。至于标题栏,LeaveEvent仅在鼠标位于客户端矩形中时触发,而客户端矩形不包括标题栏。您可以修复此问题,但这将需要另一种API密集型方法。或者,您可以使用hack,将客户端矩形在顶部扩展5px。但不会每次都起作用。我不知道为什么它会显示我的第二个点(从“如果鼠标没有”开始)再次作为第一点。我尝试过编辑,它的标签是2。那里。无论如何……在编号列表开始之前,你需要留下一个空行。因为降价不允许你从2开始编号列表,它从1开始。我已经为你修复了它。谢谢,但EventHandler没有任何问题。第二个问题(由Icfseth解决)与触发事件的时间有关。第一个事件仍处于挂起状态。是什么使进入/离开事件不可靠?一个好的答案不适合评论框,你必须单击“提问”按钮。他发布了他的问题:还可以使用
    ClientRectangle
    查看哪个建议,而不是
    Bounds
    this.Opacity = this.ClientRectangle.Contains(this.PointToClient(Cursor.Position)) ? 0.99 : 0.20;