解决方案:c#鼠标离开到子控件也触发MouseLeave事件的解决方法
2013-01-31 17:48
956 查看
最近做c#的UI开发,有个非常烦恼的问题,就是Panel的MouseLeave事件,当鼠标移动到Panel的子控件时也会触发MouseLeave事件,摸索了半天,终于发现了一个高效的方法。
该方法的思想是当Panel添加子控件时,为添加的子控件也添加鼠标离开事件,当子控件发生鼠标离开事件时,判断是否鼠标坐标在Panel的Rectangle内,如果在Panel内则不发生事件,否则就发生Panel的离开事件。当然,Panel也要重写鼠标离开事件,如果鼠标离开时是在本身的Rectangle内,则不发生离开事件,否则就正常发生了。以下SelfDefinePanel继承Panel类并重写OnMouseLeave方法和OnControlAdded方法。
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace Kingray.View.Component
{
/// <summary>
///
/// </summary>
public class SelfDefinePanel: Panel
{
public SelfDefinePanel()
{
SetStyle(ControlStyles.DoubleBuffer, true);//ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.UserPaint, true);
this.UpdateStyles();
}
/// <summary>
/// 重写OnControlAdded方法,为每个子控件添加MouseLeave事件
/// </summary>
/// <param name="e"></param>
protected override void OnControlAdded(ControlEventArgs e)
{
Control control = e.Control; // 获取添加的子控件
control.MouseLeave += this.SubControlLeave; // 当鼠标离开该子控件时判断是否是离开SelfDefinePanel
base.OnControlAdded(e);
}
/// <summary>
/// 重写OnMouseLeave事件,如果是离开本身的矩形区域则发生 base.OnMouseLeave(e);
/// </summary>
/// <param name="e"></param>
protected override void OnMouseLeave(EventArgs e)
{
//Console.WriteLine(" OnMouseLeave ClientRectangle ------------------ " + this.RectangleToScreen(this.ClientRectangle));
//判断鼠标是否还在本控件的矩形区域内
if (!this.RectangleToScreen(this.ClientRectangle).Contains(Control.MousePosition)) // this.RectangleToScreen(this.ClientRectangle) 映射为屏幕的矩形
{
base.OnMouseLeave(e);
//Console.WriteLine(" ------------------ SelfDefinePanel OnMouseLeave ------------------ ");
}
}
/// <summary>
/// 子控件鼠标离开时也要做相应的判断
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void SubControlLeave(Object sender, EventArgs e)
{
//Console.WriteLine(" SubControlLeave ClientRectangle ------------------ " + this.RectangleToScreen(this.ClientRectangle));
//判断鼠标是否还在本控件的矩形区域内
if (!this.RectangleToScreen(this.ClientRectangle).Contains(Control.MousePosition))
{
base.OnMouseLeave(e);
//Console.WriteLine(" ------------------ SubControlLeave ------------------ ");
}
}
}
}
该方法的思想是当Panel添加子控件时,为添加的子控件也添加鼠标离开事件,当子控件发生鼠标离开事件时,判断是否鼠标坐标在Panel的Rectangle内,如果在Panel内则不发生事件,否则就发生Panel的离开事件。当然,Panel也要重写鼠标离开事件,如果鼠标离开时是在本身的Rectangle内,则不发生离开事件,否则就正常发生了。以下SelfDefinePanel继承Panel类并重写OnMouseLeave方法和OnControlAdded方法。
using System;
using System.Collections.Generic;
using System.Collections;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
namespace Kingray.View.Component
{
/// <summary>
///
/// </summary>
public class SelfDefinePanel: Panel
{
public SelfDefinePanel()
{
SetStyle(ControlStyles.DoubleBuffer, true);//ControlStyles.OptimizedDoubleBuffer | ControlStyles.AllPaintingInWmPaint | ControlStyles.UserPaint
SetStyle(ControlStyles.OptimizedDoubleBuffer, true);
SetStyle(ControlStyles.AllPaintingInWmPaint, true);
SetStyle(ControlStyles.UserPaint, true);
this.UpdateStyles();
}
/// <summary>
/// 重写OnControlAdded方法,为每个子控件添加MouseLeave事件
/// </summary>
/// <param name="e"></param>
protected override void OnControlAdded(ControlEventArgs e)
{
Control control = e.Control; // 获取添加的子控件
control.MouseLeave += this.SubControlLeave; // 当鼠标离开该子控件时判断是否是离开SelfDefinePanel
base.OnControlAdded(e);
}
/// <summary>
/// 重写OnMouseLeave事件,如果是离开本身的矩形区域则发生 base.OnMouseLeave(e);
/// </summary>
/// <param name="e"></param>
protected override void OnMouseLeave(EventArgs e)
{
//Console.WriteLine(" OnMouseLeave ClientRectangle ------------------ " + this.RectangleToScreen(this.ClientRectangle));
//判断鼠标是否还在本控件的矩形区域内
if (!this.RectangleToScreen(this.ClientRectangle).Contains(Control.MousePosition)) // this.RectangleToScreen(this.ClientRectangle) 映射为屏幕的矩形
{
base.OnMouseLeave(e);
//Console.WriteLine(" ------------------ SelfDefinePanel OnMouseLeave ------------------ ");
}
}
/// <summary>
/// 子控件鼠标离开时也要做相应的判断
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
public void SubControlLeave(Object sender, EventArgs e)
{
//Console.WriteLine(" SubControlLeave ClientRectangle ------------------ " + this.RectangleToScreen(this.ClientRectangle));
//判断鼠标是否还在本控件的矩形区域内
if (!this.RectangleToScreen(this.ClientRectangle).Contains(Control.MousePosition))
{
base.OnMouseLeave(e);
//Console.WriteLine(" ------------------ SubControlLeave ------------------ ");
}
}
}
}
相关文章推荐
- 快速移动鼠标触发问题及解决方法(ECharts外部调用保存为图片操作及工作流接线mouseenter和mouseleave)
- C# 001 --- 正确的删除一个控件的事件函数 --- 解决错误: “A”不包含“B”的定义,并且找不到可接受类型为“A”的第一个参数的扩展方法“B”(是否缺少 using 指令或程序集引用?)
- layer弹出框覆盖在触发mouseenter 和 mouseleave事件元素上的一种解决方法
- C#动态代码生成控件后其他事件不能获取该控件值的解决方法
- easyui datebox控件点击今天按钮不触发onSelect事件的解决方法
- C# winform datagridview 内嵌控件值改变后立即触发事件,而不需要离开该单元格时才触发,此时需要用到dgv_CurrentCellDirtyStateChanged事件
- html select控件移动到option标签时就触发mouseleave()解决方法
- 【WPF开发备忘】使用MVVM模式开发中列表控件内的按钮事件无法触发解决方法
- C#中winform实现自动触发鼠标、键盘事件的方法
- 史上最全的CSS hack方式一览 jQuery 图片轮播的代码分离 JQuery中的动画 C#中Trim()、TrimStart()、TrimEnd()的用法 marquee 标签的使用详情 js鼠标事件 js添加遮罩层 页面上通过地址栏传值时出现乱码的两种解决方法 ref和out的区别在c#中 总结
- C# 之 FileSystemWatcher事件多次触发的解决方法
- 【DevExpress】老版TreeList和GridControl 中控件 MouseWheel事件禁用解决方法
- 解决C#获取鼠标相对当前窗口坐标的实现方法
- C#调用OCX控件Catastrophic failure解决方法
- 在有TabHost控件的页面,解决onKeyDown方法不能拦截KeyEvent.KEYCODE_BACK事件
- c# ListView控件的常用屬性、方法及事件
- 关于input的file框onchange事件触发一次失效的新的解决方法
- C#中使用TeeChart控件出现 不支持无窗口的Active控件 的解决方法
- c++ builder里四种处理“鼠标离开窗体”事件的方法
- 线程间操作无效: 从不是创建控件“”的线程访问它~~~的解决方法~ 线程间操作无效: 从不是创建控件“Control Name'”的线程访问它问题的解决方案及原理分析