使用.net的反射对LinkLabel控件的小的修改(转)

版权声明:原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 、作者信息和本声明。否则将追究法律责任。 http://happyoldbear.blog.51cto.com/231048/42928
使用LinkLabel时发现鼠标移过去变颜色,居然还需要自己写代码。
而且即使用鼠标事件MouseEnter,也是不能完美解决问题的。
所以扩展了一个属性,并借鉴了xtreme中的控件的方法,写了这个控件。
 
大致思想:
使用反射获得了两个域
//get visualregion and linkfont by reflection
            Type type = typeof(LinkLabel.Link);
            _visualRegion = type.GetField("visualRegion", BindingFlags.Instance | BindingFlags.NonPublic);
            type = typeof(LinkLabel);
            _hoverLinkFont = type.GetField("hoverLinkFont", BindingFlags.Instance | BindingFlags.NonPublic);
 
利用鼠标事件,同时建立了一个时钟,检测鼠标是否离开了控件范围内。
mCheckHoverTimer = new Timer();
在以下事件中检查  CheckHoverLink();//check hover link index
OnMouseMove
CheckHoverTimer_Tick
 
最后重写OnPaint部分。
 
 
 
下面是源代码:
 
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Reflection;
using System.ComponentModel;
using System.Globalization;
namespace Hob.Toolbox.Controls
{
    /// <summary>
    /// 扩展的超链接控件,继承自LinkLabel
    /// 2007.08.21 扩展HoverActived属性
    /// 当鼠标移动控件上时,如果HoverActived=true,那么显示颜色ActiveLinkColor
    /// </summary>
    public class HyperLink : LinkLabel
    {
        /// <summary>
        /// constructor
        /// </summary>
        public HyperLink()
        {
            //init checkhover timer
            mCheckHoverTimer = new Timer();
            mCheckHoverTimer.Interval = 10;//10ms
            mCheckHoverTimer.Tick += CheckHoverTimer_Tick;
            //get visualregion and linkfont by reflection
            Type type = typeof(LinkLabel.Link);
            _visualRegion = type.GetField("visualRegion", BindingFlags.Instance | BindingFlags.NonPublic);
            type = typeof(LinkLabel);
            _hoverLinkFont = type.GetField("hoverLinkFont", BindingFlags.Instance | BindingFlags.NonPublic);
        }
        #region HoverActived field
        bool mHoverActived;
        /// <summary>
        /// mouse move hover link color
        /// </summary>
        [Category("Appearance"), Description("Be actived when mouse hover")]
        public bool HoverActived
        {
            get
            {
                return mHoverActived;
            }
            set
            {
                mHoverActived = value;
                Invalidate();
            }
        }
        #endregion
        Timer mCheckHoverTimer;//check hover timer
        //hover link and activeLink
        LinkLabel.Link mhoverLink = null;
        LinkLabel.Link mactiveLink = null;
        /// <summary>
        /// override OnMouseMove
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseMove(MouseEventArgs e)
        {
            base.OnMouseMove(e);//call base
            if (mhoverLink == null)
                CheckHoverLink(e.X, e.Y);//check hover link index
            else
                mCheckHoverTimer.Enabled = true;//start timer
        }
        /// <summary>
        /// override OnMouseDown
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            mactiveLink = PointInLink(e.X, e.Y);
        }
        /// <summary>
        /// override OnMouseUp
        /// </summary>
        /// <param name="e"></param>
        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            mactiveLink = null;
        }
        #region CheckHoverLink
        /// <summary>
        /// check hover link overload 1
        /// </summary>
        void CheckHoverLink()
        {
            //get mouse position
            Point point = MousePosition;
            point = this.PointToClient(point);
            CheckHoverLink(point.X, point.Y);
        }
        /// <summary>
        /// check hover link overload 2
        /// </summary>
        void CheckHoverLink(int x, int y)
        {
            LinkLabel.Link oldlink = mhoverLink;//save old hover index
            mhoverLink = PointInLink(x, y);
            if (mhoverLink == null)
                mCheckHoverTimer.Enabled = false;//stop timer
            if (oldlink != mhoverLink)//change
                Invalidate();//redraw
        }
        #endregion
        /// <summary>
        /// check hover timer tick
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        void CheckHoverTimer_Tick(Object sender, EventArgs e)
        {
            CheckHoverLink();//check hover link index
        }
        /// <summary>
        /// get link visual region
        /// </summary>
        FieldInfo _visualRegion;
        Region GetVisualRegion(LinkLabel.Link link)
        {
            object result = _visualRegion.GetValue(link);
            return (Region)result;
        }
        /// <summary>
        /// get hover link font
        /// </summary>
        FieldInfo _hoverLinkFont;
        Font GetHoverLinkFont()
        {
            object result = _hoverLinkFont.GetValue(this);
            return (Font)result;
        }
        /// <summary>
        /// get is one link
        /// </summary>
        /// <returns></returns>
        bool _IsOneLink()
        {
            if (((this.Links == null) || (this.Links.Count != 1)) || (this.Text == null))
            {
                return false;
            }
            StringInfo info = new StringInfo(this.Text);
            return ((this.LinkArea.Start == 0) && (this.LinkArea.Length == info.LengthInTextElements));
        }
        /// <summary>
        /// repaint
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {
            //call base
            base.OnPaint(e);
            if (Text.Length == 0 || !Enabled || mhoverLink == null
                     || mhoverLink == mactiveLink) return;//do nothing
            //draw hover link
            if (mHoverActived)
            {
                //get linkfont and visualregion
                Graphics dc = e.Graphics;
                bool bOne = _IsOneLink();
                Font linkFont = GetHoverLinkFont();
                if (linkFont != null)
                {
                    if (!bOne)
                        dc.Clip = GetVisualRegion(mhoverLink);
                    dc.DrawString(Text, linkFont, new SolidBrush(ActiveLinkColor),
                        ClientRectangle.Left, ClientRectangle.Top);
                }
            }
        }
    }
}
 
整个工程代码下载:
 

本文出自 “欢乐老熊” 博客,请务必保留此出处http://happyoldbear.blog.51cto.com/231048/42928

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值