拒绝单色调,重写Label控件

在WinForm中,微软提供的Label中文字只能是一种颜色:要么全是黑色,要么全是红色或者其它颜色。当我们为了强调某些文字,让它用红色显示时只能新建一个Lable对象,设置它FontColor为红色。但是如果在一行文字内嵌三个红色,那岂不是要拼接六个Label控件?坑爹啊,这么麻烦,我们还不如自己重写一下Label控件,让它支持多颜色的文字呢。

OK。Let's do it.

要让不同的文字显示不同的显示,我们必须告诉Label控件哪些文字对应哪种颜色。在这里,我们定义一个字典来存储。

        /// <summary>
        ///KeyValuePair中 string存储文字,Color为对应的颜色
        /// </summary>
        private Dictionary<string, KeyValuePair<string, Color>> strColorDic = new Dictionary<string, KeyValuePair<string, Color>>();

设置对应的公共属性:

 public Dictionary<string, KeyValuePair<string, Color>> StrColorDic
        {
            get { return strColorDic; }
            set { strColorDic = value; }
        }

接下来就是最重要的重写OnPaint事件了。在这里如果我们定义的strColorDic中有值,就用g.DrawString将strColorDic中的文本写到Label控件上。如果strColorDic中没有值,就调用base.OnPaint(e)将Text属性中的文字写到Label控件上。

注意绘制时起点的X轴要作相应的变动。

 /// <summary>
        /// 重写OnPaint,如果strColorDic不为空,就将strColorDic中文本
        /// 绘制到Label中
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPaint(PaintEventArgs e)
        {    
            Graphics g = e.Graphics;
            float X = 0.0F;
            //如果字典中的键>0
            if (strColorDic.Keys.Count > 0)
            {
                foreach (string key in strColorDic.Keys)
                {
                    //根据Color获取对应的Brush
                    Brush brush = new SolidBrush(strColorDic[key].Value);
                    g.DrawString(strColorDic[key].Key, this.Font, brush, new PointF(X, 0.0F));
                    //绘制的X轴坐标要做相应的移动
                    X += (strColorDic[key].Key.Length) * Font.Height - Font.Size;
                    this.Text += strColorDic[key].Key;
                } 
            }
            else if(this.Text!="")
            {
                base.OnPaint(e);
            } 
        }

大功告成,很简单吧。我们新建一个WinForm窗体来测试一下。在Form1_Load中添加下面代码:

  Dictionary<string, KeyValuePair<string, Color>> dic = new Dictionary<string, KeyValuePair<string, Color>>();
            dic.Add("1",new KeyValuePair<string,Color>("我是红色",Color.Red));
            dic.Add("2", new KeyValuePair<string, Color>("我是蓝色", Color.Blue));
            dic.Add("3", new KeyValuePair<string, Color>("我是黄色", Color.Yellow));
            this.myLabel1.StrColorDic = dic;

可以看到运行效果:

 

 不过还有一个Bug,如果this.myLabel1.Text(myLabel1即为我们的自定义控件)的值为空的话,它不会触发我们重写的OnPaint事件。我们在代码中给它赋的值也就显示不出来。

 其实我们可以在给myLabel1赋Dic时随便给myLabel1.Text赋个值就行了,如:

 Dictionary<string, KeyValuePair<string, Color>> dic = new Dictionary<string, KeyValuePair<string, Color>>();
            dic.Add("1", new KeyValuePair<string, Color>("我是红色", Color.Red));
            dic.Add("2", new KeyValuePair<string, Color>("我是蓝色", Color.Blue));
            dic.Add("3", new KeyValuePair<string, Color>("我是黄色", Color.Yellow));
            //myLabel1.Text不能为空,否则无法触发 OnPaint事件
            this.myLabel1.Text = "  ";
            this.myLabel1.StrColorDic = dic;

代码下载:点我

 

posted @ 2012-05-29 09:07  Gyoung  阅读(3739)  评论(13编辑  收藏  举报