现在的位置: 首页 > 综合 > 正文

C#仿QQ皮肤-Label与ListBox 控件实现—-寻求滚动条的解决方案

2013年10月29日 ⁄ 综合 ⁄ 共 14363字 ⁄ 字号 评论关闭

C#仿QQ皮肤-实现原理系列文章导航
                                                              http://www.cnblogs.com/sufei/archive/2010/03/10/1682847.html 

       

大家还是先来看看效果吧

 

 

这次之所以一次写两个控件,其实主要是因为Label控件实在是太简单了没有必要放放一个文章里写,所以就一次性来了。

Label控件我就不再多说了,我直接把代码贴一下吧因为就几行代码,相信大家一眼就能看明白了。

 

代码

using System;
using System.Collections.Generic;

using System.Text;

namespace CRD.WinUI.Misc
{
  
public  class Label:System.Windows.Forms.Label
    {
      
public Label()
          : 
base()
      {
          
this.BackColor = System.Drawing.Color.Transparent;
      }
    }
}

 

 

ListBox实现

 


 

咱们从第一行代码就要吧看出来是继承自系统控件而来的。

  public class ListBox : System.Windows.Forms.ListBox

所以本身就具备了系统的ListBox的一些特性。老方法我们先来看看WndProc方法的实现

 

 

代码

  protected override void WndProc(ref System.Windows.Forms.Message m)
        {
            IntPtr hDC 
= IntPtr.Zero;
            Graphics gdc 
= null;

            switch (m.Msg)
            {
                
case 133:
                    hDC 
= Win32.GetWindowDC(m.HWnd);
                    gdc 
= Graphics.FromHdc(hDC);
                    Win32.SendMessage(
this.Handle, WM_ERASEBKGND, hDC.ToInt32(), 0);
                    SendPrintClientMsg();
                    Win32.SendMessage(
this.Handle, WM_PAINT, 00);
                    OverrideControlBorder(gdc);
                    m.Result 
= (IntPtr)1;
                    Win32.ReleaseDC(m.HWnd, hDC);
                    gdc.Dispose();
                    
break;
                
case WM_PAINT:
                    
base.WndProc(ref m);
                    hDC 
= Win32.GetWindowDC(m.HWnd);
                    gdc 
= Graphics.FromHdc(hDC);
                    OverrideControlBorder(gdc);
                    Win32.ReleaseDC(m.HWnd, hDC);
                    gdc.Dispose();
                    
break;
                
default:
                    
base.WndProc(ref m);
                    
break;
            }
        }

 

这边的实现方法基本上和之前的控件一个样,所以我就不再多说原理了,大家随便看一下前几次的文章就明白了。

下面我们来看一下怎么样换皮肤的事件

也就是说在换皮肤的时候我们应该做那些工作

 

 

代码

  protected override void OnDrawItem(DrawItemEventArgs e)
        {
            Graphics g 
= e.Graphics;
            
//绘制区域
            Rectangle r = e.Bounds;

            Font fn = null;
            
if (e.Index >= 0)
            {
                
if (e.State == DrawItemState.None)
                {
                    
//设置字体、字符串格式、对齐方式
                    fn = e.Font;
                    
string s = (string)this.Items[e.Index];
                    StringFormat sf 
= new StringFormat();
                    sf.Alignment 
= StringAlignment.Near;
                    
//根据不同的状态用不同的颜色表示
                    if (e.State == (DrawItemState.NoAccelerator | DrawItemState.NoFocusRect))
                    {
                        e.Graphics.FillRectangle(
new SolidBrush(Color.Red), r);
                        e.Graphics.DrawString(s, fn, 
new SolidBrush(Color.Black), r, sf);
                        e.DrawFocusRectangle();
                    }
                    
else
                    {
                        e.Graphics.FillRectangle(
new SolidBrush(Color.White), r);
                        e.Graphics.DrawString(s, fn, 
new SolidBrush(Shared.FontColor), r, sf);
                        e.DrawFocusRectangle();
                    }
                }
                
else
                {
                    fn 
= e.Font;
                    StringFormat sf 
= new StringFormat();
                    sf.Alignment 
= StringAlignment.Near;
                    
string s = (string)this.Items[e.Index];
                    e.Graphics.FillRectangle(
new SolidBrush(Shared.ControlBackColor), r);
                    e.Graphics.DrawString(s, fn, 
new SolidBrush(Shared.FontColor), r, sf);
                }  
            } 
        }

 

      其实这些都不是今天要说的重点,这个控件的实现基础跟之前的一些控件基本上是一样的,像Textbox就和这个差不多,

唯一我想说的是滚动条的实现,不多说了下面开始吧

 

滚动条的实现

 


 

如上面的图片大家已经看到了,图片在我的源代码里都有,我在这里就不多说了,一起来看是怎么实现 的吧,先说说思路,

     第一步,先制做一个自己的滚动条,随便做只要自己感觉漂亮就可以,第二步就是,利用Api把Listbox现有的滚动条用现在的滚动条代替,第三步,让现有的滚动条和系统的滚动条实现同步即可。

    我实现滚动条的代码,大家也可以自己写这里只是一个参考吧

看一下效果

看一下代码吧,具体的素材大家到我源代码里面找吧,呵呵

 

代码

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;

using System.Text;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Diagnostics;

namespace CRD.WinUI.Misc
{
    [Designer(
typeof(ScrollbarControlDesigner))]
    
public partial class CustomScrollbar : UserControl
    {

        protected Color moChannelColor = Color.Empty;
        
protected Image moUpArrowImage = null;//上箭头
        
//protected Image moUpArrowImage_Over = null;
        
//protected Image moUpArrowImage_Down = null;
        protected Image moDownArrowImage = null;//下箭头
        
//protected Image moDownArrowImage_Over = null;
        
//protected Image moDownArrowImage_Down = null;
        protected Image moThumbArrowImage = null;

        protected Image moThumbTopImage = null;
        
protected Image moThumbTopSpanImage = null;
        
protected Image moThumbBottomImage = null;
        
protected Image moThumbBottomSpanImage = null;
        
protected Image moThumbMiddleImage = null;

        protected int moLargeChange = 10;
        
protected int moSmallChange = 1;
        
protected int moMinimum = 0;
        
protected int moMaximum = 100;
        
protected int moValue = 0;
        
private int nClickPoint;

        protected int moThumbTop = 0;

        protected bool moAutoSize = false;

        private bool moThumbDown = false;
        
private bool moThumbDragging = false;

        public new event EventHandler Scroll = null;
        
public event EventHandler ValueChanged = null;

        private int GetThumbHeight()
        {
            
int nTrackHeight = (this.Height - (UpArrowImage.Height + DownArrowImage.Height));
            
float fThumbHeight = ((float)LargeChange / (float)Maximum) * nTrackHeight;
            
int nThumbHeight = (int)fThumbHeight;

            if (nThumbHeight > nTrackHeight)
            {
                nThumbHeight 
= nTrackHeight;
                fThumbHeight 
= nTrackHeight;
            }
            
if (nThumbHeight < 56)
            {
                nThumbHeight 
= 56;
                fThumbHeight 
= 56;
            }

            return nThumbHeight;
        }

        public CustomScrollbar()
        {

            InitializeComponent();
            SetStyle(ControlStyles.ResizeRedraw, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, 
true);
            SetStyle(ControlStyles.DoubleBuffer, 
true);

            moChannelColor = Color.FromArgb(511663);
            UpArrowImage 
= Bitmap.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.scroll.uparrow.png"), truefalse);// BASSSkin.uparrow;//上箭头
            DownArrowImage = Bitmap.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.scroll.downarrow.png"), truefalse);// BASSSkin.downarrow;//下肩头
            ThumbBottomImage = Bitmap.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.scroll.ThumbBottom.png"), truefalse);//  BASSSkin.ThumbBottom;
            ThumbMiddleImage = Bitmap.FromStream(Shared.AssemblyWinUI.GetManifestResourceStream("CRD.WinUI.Resources.Common.scroll.ThumbMiddle.png"), truefalse);//  BASSSkin.ThumbMiddle;

            
this.Width = UpArrowImage.Width;//18px
            base.MinimumSize = new Size(UpArrowImage.Width, UpArrowImage.Height + DownArrowImage.Height + GetThumbHeight());
        }

        [EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Behavior"), Description("LargeChange")]
        
public int LargeChange
        {
            
get { return moLargeChange; }
            
set
            {
                moLargeChange 
= value;
                Invalidate();
            }
        }

        [EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Behavior"), Description("SmallChange")]
        
public int SmallChange
        {
            
get { return moSmallChange; }
            
set
            {
                moSmallChange 
= value;
                Invalidate();
            }
        }

        [EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Behavior"), Description("Minimum")]
        
public int Minimum
        {
            
get { return moMinimum; }
            
set
            {
                moMinimum 
= value;
                Invalidate();
            }
        }

        [EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Behavior"), Description("Maximum")]
        
public int Maximum
        {
            
get { return moMaximum; }
            
set
            {
                moMaximum 
= value;
                Invalidate();
            }
        }

        [EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Behavior"), Description("Value")]
        
public int Value
        {
            
get { return moValue; }
            
set
            {
                moValue 
= value;

                int nTrackHeight = (this.Height - (UpArrowImage.Height + DownArrowImage.Height));
                
float fThumbHeight = ((float)LargeChange / (float)Maximum) * nTrackHeight;
                
int nThumbHeight = (int)fThumbHeight;

                if (nThumbHeight > nTrackHeight)
                {
                    nThumbHeight 
= nTrackHeight;
                    fThumbHeight 
= nTrackHeight;
                }
                
if (nThumbHeight < 56)
                {
                    nThumbHeight 
= 56;
                    fThumbHeight 
= 56;
                }

                //figure out value
                int nPixelRange = nTrackHeight - nThumbHeight;
                
int nRealRange = (Maximum - Minimum) - LargeChange;
                
float fPerc = 0.0f;
                
if (nRealRange != 0)
                {
                    fPerc 
= (float)moValue / (float)nRealRange;

                }

                float fTop = fPerc * nPixelRange;
                moThumbTop 
= (int)fTop;

                Invalidate();
            }
        }

        [EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Skin"), Description("Channel Color")]
        
public Color ChannelColor
        {
            
get { return moChannelColor; }
            
set { moChannelColor = value; }
        }

        [EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Skin"), Description("Up Arrow Graphic")]
        
public Image UpArrowImage
        {
            
get { return moUpArrowImage; }
            
set { moUpArrowImage = value; }
        }

        [EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Skin"), Description("Up Arrow Graphic")]
        
public Image DownArrowImage
        {
            
get { return moDownArrowImage; }
            
set { moDownArrowImage = value; }
        }

        [EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Skin"), Description("Up Arrow Graphic")]
        
public Image ThumbBottomImage
        {
            
get { return moThumbBottomImage; }
            
set { moThumbBottomImage = value; }
        }

        [EditorBrowsable(EditorBrowsableState.Always), Browsable(true), DefaultValue(false), Category("Skin"), Description("Up Arrow Graphic")]
        
public Image ThumbMiddleImage
        {
            
get { return moThumbMiddleImage; }
            
set { moThumbMiddleImage = value; }
        }

        protected override void OnPaint(PaintEventArgs e)
        {

            e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;

            if (UpArrowImage != null)
            {
                e.Graphics.DrawImage(UpArrowImage, 
new Rectangle(new Point(00), new Size(this.Width, UpArrowImage.Height)));
            }

            Brush oBrush = new SolidBrush(moChannelColor);
            Brush oWhiteBrush 
= new SolidBrush(Color.FromArgb(255255255));
            
//          函数名: rectangle 
            
//功 能: 画一个矩形 
            
//用 法: void far rectangle(int left, int top, int right, int bottom); 

            //draw channel left and right border colors
            e.Graphics.FillRectangle(oWhiteBrush, new Rectangle(0, UpArrowImage.Height, 1, (this.Height - DownArrowImage.Height)));
            e.Graphics.FillRectangle(oWhiteBrush, 
new Rectangle(this.Width - 1, UpArrowImage.Height, 1, (this.Height - DownArrowImage.Height)));

            //draw channel
            
//e.Graphics.FillRectangle(oBrush, new Rectangle(1, UpArrowImage.Height, this.Width-2, (this.Height-DownArrowImage.Height)));
            e.Graphics.DrawImage(ThumbBottomImage, new Rectangle(0, UpArrowImage.Height, this.Width, (this.Height - DownArrowImage.Height)));
            
//draw thumb
            int nTrackHeight = (this.Height - (UpArrowImage.Height + DownArrowImage.Height));
            
float fThumbHeight = ((float)LargeChange / (float)Maximum) * nTrackHeight;
            
int nThumbHeight = (int)fThumbHeight;

            if (nThumbHeight > nTrackHeight)
            {
                nThumbHeight 
= nTrackHeight;
                fThumbHeight 
= nTrackHeight;
            }
            
//MessageBox.Show(nThumbHeight.ToString());
            if (nThumbHeight < 56)
            {
                nThumbHeight 
= 56;
                fThumbHeight 
= 56;
            }

            //Debug.WriteLine(nThumbHeight.ToString());

            //float fSpanHeight = (fThumbHeight - (ThumbMiddleImage.Height + ThumbTopImage.Height + ThumbBottomImage.Height)) / 2.0f;
            
//int nSpanHeight = (int)fSpanHeight;

            
int nTop = moThumbTop;//0
            nTop += UpArrowImage.Height;//9px

            //draw top画上面的按钮
            
//e.Graphics.DrawImage(ThumbTopImage, new Rectangle(0, nTop, this.Width, ThumbTopImage.Height));

            //nTop += ThumbTopImage.Height;//10px
            
//draw top span
            
//Rectangle rect = new Rectangle(1, nTop, this.Width - 2, nSpanHeight);

            //e.Graphics.DrawImage(ThumbTopSpanImage, 1.0f,(float)nTop, (float)this.Width-2.0f, (float) fSpanHeight*2);

            // nTop += nSpanHeight;//11px
            
//draw middle
            e.Graphics.DrawImage(ThumbMiddleImage, new Rectangle(0, nTop, this.Width, ThumbMiddleImage.Height));

            //nTop += ThumbMiddleImage.Height;
            
//draw top span
            
//rect = new Rectangle(1, nTop, this.Width - 2, nSpanHeight*2);
            
//e.Graphics.DrawImage(ThumbBottomSpanImage, rect);

            //nTop += nSpanHeight;
            
//draw bottom
            
//e.Graphics.DrawImage(Thu

抱歉!评论已关闭.