在mobile5.0上实现滑动效果控件

最近一直忙于IM的设计,很久没有更新我的博客。今天有点时间,我把以前做的一个mobile5滑动效果放上来与大家分享,希望能对初学者有一点帮助。

用过mobile的朋友都知道微软的联系人这个软件很不好用,采用的是pc那种方式,右边一个滚动条,而这个滚动条又太细,我的拇指经常性的点不中,所以萌发了写个类似Iphone那种滑动效果的控件。

控件是用C#和GDI+写的,内部有一个简单的状态机制,没有什么技术含量。我也不打算仔细给大家讲解了,看代码吧。

代码
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using System.Threading;
namespace SmartDeviceControlLibrary
{
    public struct FlashUserInformation
    {
        public int Position;
        public string Name;
        public string Value;
        public Column ColumnName;
    }
    public struct UserSearched
    {
        public UserInfomation User;
        public int Position;
    }
    public enum UserState { ByGroup, ByCapital }
    /// 
<summary>
    /// 控件绘制状态


    /// 
</summary>
    public enum DrawState { Initial, DrawControl, Drawing, Rolling, NothingChange, NeedRedrawLabs, SingleLab, SingleUser }
    /// 
<summary>
    /// panel绘制状态


    /// 
</summary>
    public enum DrawPanelState { Drawfirst, DrawJointsSecondToFirst, DrawJointsFirstToSecond, OutFront, OutEnding, NotDecided }
    public partial class QQListControl : UserControl
    {
        /// 
<summary>
        /// 初始化控件
        /// 
</summary>
        bool IsInitailControls = false;
        /// 
<summary>
        /// 闪烁模式,false绘制背景,true绘制图片
        /// 
</summary>
        bool FlashMode = false;
        /// 
<summary>
        /// 背景图
        /// 
</summary>
        List
<FlashUserInformation> FlashUser = new List<FlashUserInformation>();
        public ImageList BackGroundImage;
        private Image _BGImage;
        public bool IsDefaultLabAllow = true;

        public Image BackgroundImage
        {
            get
            {
                if (_BGImage != null)
                    return _BGImage;
                else
                    return null;
            }
            set { _BGImage = value; rectBackGroudImage = new Rectangle(0, 0, value.Width, value.Height); }
        }
        /// 
<summary>
        /// 用户区单个Item绘制的高度
        /// 
</summary>
        public int ItemHeight
        {
            set { _UserControlHeight = value; }
            get { return _UserControlHeight; }
        }
        /// 
<summary>
        /// 背景图的byte数组
        /// 
</summary>
        //private byte[] BackPixelValues;

        //private int iBytes;
        //private IntPtr iPtrfront;
        //private byte[] FrontPixelValues

        ImageAttributes imgattr = new ImageAttributes();
        //单击事件
        public delegate void DelegateClickUser(UserInfomation user);
        public event DelegateClickUser OnClickUser;

        //双击事件
        public delegate void DelegateDoubleClickUser(UserInfomation user);
        public event DelegateDoubleClickUser OnDoubleClickUser;
        /// 
<summary>
        /// 点击次数,用于判断双击事件
        /// 
</summary>
        int Clicks = 0;
        //是否拼音查找状态

        bool IsSearching = false;
        /// 
<summary>
        /// 鼠标弹起时候判断按下的时候是否是Lab
        /// 
</summary>
        bool IsClickLab = false;
        /// 
<summary>
        /// 绘图状态


        /// 
</summary>
        DrawState PaintState = DrawState.Initial;
        /// 
<summary>
        /// Panel区数据源
        /// 
</summary>
        UserState LabUserDate;
        /// 
<summary>
        /// 用于判断是普通状态还是查找状态,区别使用thiPanelUser_ForSearch还是thiPanelUser来定位用户

        /// 
</summary>
        DrawState LabState = DrawState.Initial;
        /// 
<summary>
        /// 系统头像
        /// 
</summary>
        public ImageList Images;
        /// 
<summary>
        /// 用户信息
        /// 
</summary>
        public List
<UserInfomation> Users = new List<UserInfomation>();
        /// 
<summary>
        /// 如何绘制用户信息
        /// 
</summary>
        public List
<Column> Columns = new List<Column>();
        /// 
<summary>
        /// Panel区的用户
        /// 
</summary>
        private List
<UserInfomation> thiPanelUser;
        /// 
<summary>
        /// 查找后的用户
        /// 
</summary>
        private List
<UserInfomation> thiPanelUser_ForSearch;

        /// 
<summary>
        /// 标签表


        /// 
</summary>
        List
<ListLab> InnerListLab = new List<ListLab>();
        /// 
<summary>
        /// Panel区大小
        /// 
</summary>
        Rectangle rectPanel;
        /// 
<summary>
        /// 背景图大小
        /// 
</summary>
        Rectangle rectBackGroudImage;
        /// 
<summary>
        /// Panel区路径


        /// 
</summary>
        Region rectRegionPanel;
        /// 
<summary>
        /// 控件区大小

        /// 
</summary>
        Rectangle rectControl;
        /// 
<summary>
        /// 控件区路径

        /// 
</summary>
        Region RegionControl;
        /// 
<summary>
        /// Panel填充色


        /// 
</summary>
        private SolidBrush PanelBrush;
        /// 
<summary>
        /// 
<summary>
        /// Panel字体颜色
        /// 
</summary>
        private SolidBrush FontBrush;
        /// 
<summary>
        /// 字体大小
        /// 
</summary>
        private SizeF Fontsize;
        /// 
<summary>
        /// Panel缓冲
        /// 
</summary>
        Bitmap PanelMap = null;
        /// 
<summary>
        /// 整个控件的图像缓冲Graphics
        /// 
</summary>
        Graphics DoubleG;
        /// 
<summary>
        ///控件区的图像缓冲Graphics
        /// 
</summary>
        Graphics DoubleGPanel;

        /// 
<summary>
        /// 整个控件的图像缓冲

        /// 
</summary>
        Bitmap ControlMap = null;
        /// 
<summary>
        /// Panel高度
        /// 
</summary>
        int PanelHeight = 0;
        /// 
<summary>
        /// Panel位置
        /// 
</summary>
        int PanelPosition = 0;
        /// 
<summary>
        /// 当前PanelLab
        /// 
</summary>
        ListLab PanelLab = null;
        /// 
<summary>
        /// Panel缓冲的起始位置


        /// 
</summary>
        int PanelMapPosition = 0;
        /// 
<summary>
        /// Panel缓冲的起始位置,恒定不变
        /// 
</summary>
        int _PanelMapPosition = 0;
        /// 
<summary>
        /// Panel区绘制的人员数量
        /// 
</summary>
        int DisplayUserCount;
        /// 
<summary>
        /// 鼠标按下时候的Y值


        /// 
</summary>
        int MouseDownY;
        /// 
<summary>
        /// 鼠标按下时候的时间,毫秒


        /// 
</summary>
        Int64 MouseDownTime;
        /// 
<summary>
        /// 鼠标按下时候的时间,毫秒,用于双击事件
        /// 
</summary>
        Int64 MouseDoubleDownTime;
        /// 
<summary>
        /// 滑动加速度
        /// 
</summary>
        float F_M = 0.96f;
        /// 
<summary>
        /// 滑动位移
        /// 
</summary>
        float Distance = 0;
        /// 
<summary>
        /// 滑动方向
        /// 
</summary>
        int _direction;
        /// 
<summary>
        /// 滑动定时器
        private Color OnClickColor;
        /// 
<summary>
        /// 间隔线颜色
        /// 
</summary>
        private Color _LineColor;
        /// 
<summary>
        /// Item间隔线的颜色
        /// 
</summary>
        public Color LineColor
        {
            set { _LineColor = value; }
            get { return _LineColor; }
        }
        /// 
<summary>
        /// 点击Item的背景色
        /// 
</summary>
        public Color ItemClickBackGroundColor
        {
            set { OnClickColor = value; }
            get { return OnClickColor; }
        }
        /// Panel字体颜色
        /// 
</summary>
        private SolidBrush OnClickColorBrush;
        /// 
<summary>
        /// 保存点击的用户位置
        /// 
</summary>
        private int LastOnClickUser = -1, LastOnClickUserPage = -1;
        /// 
<summary>
        /// 闪烁图片定时器
        /// 
</summary>
        private System.Windows.Forms.Timer FlashTime = new System.Windows.Forms.Timer();

        /// 
<summary>
        /// 滚动定时器
        /// 
</summary>
        private System.Windows.Forms.Timer RollTime = new System.Windows.Forms.Timer();
        /// 
<summary>
        /// 单个Lab定时器
        /// 
</summary>
        private System.Windows.Forms.Timer SingleLabTime = new System.Windows.Forms.Timer();
        /// 
<summary>
        /// 滚动次数
        /// 
</summary>
        int RollCount = 0;

        /// 
<summary>
        /// 人员绘制结束位置完毕
        /// 
</summary>
        bool OutEnd = false;
        /// 
<summary>
        /// 用户绘制的第一页  
        /// 
</summary>
        int PageOne;
        /// 
<summary>
        ///  用户绘制的第二页  
        /// 
</summary>
        int PageSecond;
        /// 
<summary>
        /// 结束用户位置
        /// 
</summary>
        int _UserEndPosition;
        /// 
<summary>
        /// 结束的用户页位置
        /// 
</summary>
        int _UserEndPage;
        /// 
<summary>
        /// 绘制用户区的分割线

        /// 
</summary>
        Pen LinePen;
        /// 
<summary>
        /// 单个用户绘制区的高度
        /// 
</summary>
        int _UserControlHeight = 25;
        /// 
<summary>
        /// 单个标签绘制区的高度
        /// 
</summary>
        int _LabControlHeight
        {
            get { return ListLab._Height; }
        }

        [DllImport("\\windows\\coredll.dll", EntryPoint = "GetTickCount")]
        public static extern int GetTickCount();

        public QQListControl()
        {

            InitializeComponent();



        }
        /// 
<summary>
        /// 初始化控件
        /// 
</summary>
        private void InitailControls()
        {
            if (!IsInitailControls)
            {
                IsInitailControls = true;
                PanelBrush = new SolidBrush(this.BackColor);
                if (OnClickColor.IsEmpty)
                    OnClickColor = Color.Gold;
                OnClickColorBrush = new SolidBrush(OnClickColor);

                FontBrush = new SolidBrush(this.ForeColor);

                if (LineColor.IsEmpty)
                    LineColor = Color.Black;

                LinePen = new Pen(LineColor);


                if (IsDefaultLabAllow)
                {
                    ListLab AllLab = new ListLab();
                    AllLab._Position = 0;
                    AllLab.Text = "所有";
                    AllLab.IsExpand = true;
                    AllLab.BackColor = Color.CornflowerBlue;
                    InnerListLab.Insert(0, AllLab);
                }
                ListLab x = InnerListLab.Find(delegate(ListLab v) { return v.IsExpand == true; });
                if (x == null)
                    InnerListLab[0].IsExpand = true;

                rectControl = new Rectangle(0, 0, Width, Height);
                RegionControl = new Region(rectControl);
                ///设置背景色为透明色
                imgattr.SetColorKey(this.BackColor, this.BackColor);





                ControlMap = new Bitmap(this.Width, this.Height);
                DoubleG = Graphics.FromImage(ControlMap);
                DoubleGPanel = Graphics.FromImage(ControlMap);


                // Graphics g = e.Graphics;
                //启动Name转换成拼音的线程

                Thread PinyThread = new Thread(new ThreadStart(PinyThreadProc));
                PinyThread.IsBackground = true;
              //  PinyThread.Start();

                thiPanelUser = Users;

                //    break;
                //case DrawState.DrawControl://重绘所有标签、Panel
                PaintState = DrawState.Drawing;
                DrawControl();
                //一段时间后自动变成单个Lab
                SingleLabTime.Interval = 3000;
                SingleLabTime.Tick += new EventHandler(SingleLabTime_Tick);
                SingleLabTime.Enabled = true;
                //从缓冲区绘制

                //PaintState = DrawState.DrawControl;
                //this.Invalidate();
            }
        }
        /// 
<summary>
        /// 汉字转拼音的后台进程
        /// 
</summary>
        private void PinyThreadProc()
        {
            //while (true)
            //{
            foreach (UserInfomation User in Users)
            {
                if (User.Pinyin == null)
                    User.Pinyin = Hz2Py.Convert(User.Name);
            }
            //    Thread.Sleep(2000);
            //}
        }
        protected override void OnPaintBackground(PaintEventArgs paintg)
        {
            //不绘制背景


        }

        /// 
<summary>
        /// 调整控件位置
        /// 
</summary>
        private void AdjustControls()
        {


        }
        /// 
<summary>
        /// 进入搜索状态

        /// 
</summary>
        public void Search()
        {
            thiPanelUser_ForSearch = new List
<UserInfomation>(thiPanelUser);

            PaintState = DrawState.SingleLab;
            this.Invalidate();
        }

        /// 
<summary>
        /// 通过拼音字母来查找用户

        /// 
</summary>
        /// 
<param name="Capital"></param>
        public void SearchByCapital(string Input)
        {
            if (!IsSearching)
            {
                IsSearching = true;
                //thiPanelUser_ForSearch = new List
<UserInfomation>(thiPanelUser);

                if (Input.Length > 0)

                    ///全拼查找
                    thiPanelUser_ForSearch = thiPanelUser.FindAll(delegate(UserInfomation v) { return Capital.GetAllLike(ref v.Pinyin, ref Input); });

                //  this.Cursor = Cursors.Default;

                PaintState = DrawState.SingleLab;
                LabUserDate = UserState.ByCapital;

                this.Invalidate();
                IsSearching = false;
            }
        }
        /// 
<summary>
        /// 添加绘制用户的方法
        /// 
</summary>
        /// 
<param name="Columns"></param>
        public void AddColumn(Column DrawColumn)
        {
            Columns.Add(DrawColumn);
        }
        /// 
<summary>
        /// 添加用户
        /// 
</summary>
        /// 
<param name="User"></param>
        public bool AddUser(UserInfomation User)
        {
            UserInfomation UserHas = Users.Find(delegate(UserInfomation v) { return v.Name == User.Name; });

            if (UserHas == null)
            {
                this.Users.Add(User);
                return true;
            }
            return false;
        }
        /// 
<summary>
        /// 添加标签
        /// 
</summary>
        /// 
<param name="Lab"></param>
        public void AddListLab(ListLab Lab)
        {
            ListLab LabHas = InnerListLab.Find(delegate(ListLab v) { return v.Text == Lab.Text; });

            if (LabHas == null)
            {
                if (Lab.IsExpand)//如果新Lab是展开状态,则关闭其他所有Lab的展开状态,因为同一时刻只有一个lab展开
                {
                    foreach (ListLab _Lab in InnerListLab)// (int i = 0; i 
< InnerListLab.Count;i++ )
                    {
                        _Lab.IsExpand 
= false;

                    
}

                }
                //if (Lab.BackColor.IsEmpty)
                //    Lab.BackColor 
= Color.CornflowerBlue;
                
InnerListLab.Add(Lab);
                Lab._Position 
= InnerListLab.Count - 1;
            }
            //调整所有控件位置


            // AdjustControls();

        }

        /// <summary
>
        /// 添加标签到指定位置


        /// 
</summary>
        /// 
<param name="Lab"></param>
        /// 
<param name="Position"></param>
        public void AddListLab(ListLab Lab, int Position)
        {
            InnerListLab.Insert(Position, Lab);


        }
        /// 
<summary>
        /// 移除标签
        /// 
</summary>
        /// 
<param name="Lab"></param>
        public void RemoveListLab(ListLab Lab)
        {
            InnerListLab.Remove(Lab);
        }
        /// 
<summary>
        /// 移除指定位置标签
        /// 
</summary>
        /// 
<param name="Lab"></param>
        /// 
<param name="Position"></param>
        public void RemoveListLab(int Position)
        {
            InnerListLab.RemoveAt(Position);
        }
        /// 
<summary>
        /// 移除所有标签
        /// 
</summary>
        public void RemoveAll()
        {
            InnerListLab.Clear();
            Users.Clear();
        }
        private void QQListControl_Load(object sender, EventArgs e)
        {

            //this.Controls.a
        }
        /// 
<summary>
        /// 重新绘制控件的Panel区
        /// 
</summary>
        public void RedrawPanel()
        {
            if (!IsInitailControls)
                InitailControls();
            //绘制背景
            if (_BGImage != null)
            {
                //DoubleG.DrawImage(_BGImage,,rectPanel, 0, _PanelMapPosition,_BGImage.Width,_BGImage.Height,GraphicsUnit.Pixel,new ImageAttributes());
                DoubleG.DrawImage(_BGImage, rectControl, rectBackGroudImage, GraphicsUnit.Pixel);
            }
            else
            {
                DoubleG.FillRectangle(PanelBrush, rectPanel);

            }
            DrawUser();
            switch (LabState)
            {
                case DrawState.DrawControl:
                    DrawLabs(DoubleG);
                    break;
                case DrawState.SingleLab:
                    DrawSingleLab(DoubleG);
                    break;
            }
            PaintState = DrawState.NothingChange;
            this.Invalidate();
        }
        /// 
<summary>
        /// 重新绘制控件
        /// 
</summary>
        public void Redraw()
        {
            if (!IsInitailControls)
                InitailControls();
            PaintState = DrawState.DrawControl;
            this.Invalidate();
        }
        /// 
<summary>
        /// 控件绘制
        /// 
</summary>
        /// 
<param name="e"></param>
        private void DrawControl()
        {
            LabState = DrawState.DrawControl;
            OutEnd = false;

            _UserEndPosition = 0;
            LastOnClickUserPage = -1;
            LastOnClickUser = -1;





            DrawLabs(DoubleG);
            ///绘制用户信息

            DrawPanel(DoubleG, PanelPosition, PanelHeight, PanelLab, UserState.ByGroup);

            //  g.Dispose();
        }
        /// 
<summary>
        /// 控件绘制,单个Lab
        /// 
</summary>
        /// 
<param name="e"></param>
        private void SingleLab(PaintEventArgs e)
        {
            LabState = DrawState.SingleLab;


            ///双缓冲


            if (ControlMap == null)
            {
                ControlMap = new Bitmap(this.Width, this.Height);
                DoubleG = Graphics.FromImage(ControlMap);
            }
            // Graphics g = e.Graphics;
            DrawSingleLab(DoubleG);
            ///绘制用户信息

            DrawPanel(DoubleG, PanelPosition, PanelHeight, PanelLab, LabUserDate);
            //从缓冲区绘制
            e.Graphics.DrawImage(ControlMap, 0, 0);

            //List
<UserInfomation> Temp = new List<UserInfomation>(thiPanelUser_ForSearch);
            //thiPanelUser_ForSearch = thiPanelUser;

            //thiPanelUser = Temp;
            //e.Graphics.Dispose();
        }
        /// 
<summary>
        /// 窗口重绘
        /// 
</summary>
        /// 
<param name="sender"></param>
        /// 
<param name="e"></param>
        private void QQListControl_Paint(object sender, PaintEventArgs e)
        {
            switch (PaintState)
            {
                case DrawState.Initial:
                    InitailControls();

                    e.Graphics.DrawImage(ControlMap, 0, 0);


                    PaintState = DrawState.NothingChange;
                    break;
                case DrawState.DrawControl://重绘所有标签、Panel
                    PaintState = DrawState.Drawing;
                    DrawControl();
                    //一段时间后自动变成单个Lab
                    SingleLabTime.Interval = 3000;
                    SingleLabTime.Tick += new EventHandler(SingleLabTime_Tick);
                    SingleLabTime.Enabled = true;
                    PaintState = DrawState.NothingChange;
                    e.Graphics.DrawImage(ControlMap, 0, 0);

                    break;
                case DrawState.NothingChange://无动作、重绘缓冲区
                    PaintState = DrawState.Drawing;
                    e.Graphics.DrawImage(ControlMap, 0, 0);
                    PaintState = DrawState.NothingChange;
                    break;
                case DrawState.Drawing://绘制过程中


                    break;
                case DrawState.Rolling://滚动过程中


                    Rolling(e);
                    //PaintState = DrawState.NeedRedrawLabs;
                    PaintState = DrawState.NothingChange;

                    break;
                case DrawState.NeedRedrawLabs://需要重绘标签
                    PaintState = DrawState.Drawing;
                    DrawLabs(DoubleG);
                    e.Graphics.DrawImage(ControlMap, 0, 0);
                    PaintState = DrawState.NothingChange;
                    break;
                case DrawState.SingleLab://绘制单独标签
                    PaintState = DrawState.Drawing;
                    SingleLab(e);
                    PaintState = DrawState.NothingChange;
                    break;
                case DrawState.SingleUser:
                    PaintState = DrawState.Drawing;
                    switch (LabState)
                    {
                        case DrawState.DrawControl:
                            DrawLabs(DoubleG);
                            break;
                        case DrawState.SingleLab:
                            DrawSingleLab(DoubleG);
                            break;
                    }

                    e.Graphics.DrawImage(ControlMap, 0, 0);
                    PaintState = DrawState.NothingChange;
                    break;
            }

        }
        /// 
<summary>
        /// 绘制标签
        /// 
</summary>
        /// 
<param name="g"></param>
        private void DrawSingleLab(Graphics g)
        {
            //最后添加控件的位置
            int LastPosition = 0;
            // SolidBrush FontBrush = new SolidBrush(Color.Black);


            foreach (ListLab Lab in InnerListLab)
            {
                if (Lab.IsExpand)
                {
                    //绘制标签
                    Rectangle rect = new Rectangle(0, LastPosition, this.Width - 1, _LabControlHeight);
                    Lab.Rect = rect;

                    if (ListLab.BackGroudImage == null)
                    {
                        Brush LabColorBrush = new SolidBrush(Lab.BackColor);

                        g.DrawRectangle(LinePen, rect);
                        g.FillRectangle(LabColorBrush, rect);

                        //g.DrawLine(LinePen, 0, LastPosition, Width, LastPosition);
                        //g.DrawLine(LinePen, 0, _LabControlHeight + LastPosition, Width, _LabControlHeight + LastPosition);

                        LabColorBrush.Dispose();
                    }
                    else //绘制背景图标签
                    {
                        g.DrawImage(ListLab.BackGroudImage, rect, Lab.BackGroundImageRect, GraphicsUnit.Pixel);
                    }
                    ///绘制标准名称
                    // Font this.Font = new Font("SystemFont", 9, FontStyle.Regular);
                    Fontsize = g.MeasureString(Lab.Text, this.Font);
                    g.DrawString(Lab.Text, this.Font, FontBrush, (Width - Fontsize.Width) / 2, LastPosition + (_LabControlHeight - Fontsize.Height) / 2);
                    int x = Convert.ToInt32((Width - Fontsize.Width) / 2 + Fontsize.Width + 5);
                    int y = LastPosition + (_LabControlHeight - 9) / 2 + 3;

                    ///画一个倒置的等边三角形
                    Point[] Tri = new Point[3];
                    Tri[0] = new Point(x, y);
                    Tri[1] = new Point(x + 9, y);
                    Tri[2] = new Point(x + 4, y + 7);
                    g.FillPolygon(FontBrush, Tri);

                    LastPosition += _LabControlHeight + 1;


                    PanelHeight = this.Size.Height - (_LabControlHeight);
                    PanelPosition = LastPosition;
                    LastPosition += PanelHeight;
                    PanelLab = Lab;
                }

            }
        }

        /// 
<summary>
        /// 绘制标签
        /// 
</summary>
        /// 
<param name="g"></param>
        private void DrawLabs(Graphics g)
        {
            //最后添加控件的位置
            int LastPosition = 0;
            //SolidBrush FontBrush = new SolidBrush(Color.Black);


            foreach (ListLab Lab in InnerListLab)
            {
                //绘制背景色标签
                Rectangle rect = new Rectangle(0, LastPosition, this.Width - 1, _LabControlHeight);
                Lab.Rect = rect;

                if (ListLab.BackGroudImage == null)
                {
                    Brush LabColorBrush = new SolidBrush(Lab.BackColor);

                    g.FillRectangle(LabColorBrush, rect);
                    g.DrawRectangle(LinePen, rect);
                    LastPosition += _LabControlHeight + 1;
                    Fontsize = g.MeasureString(Lab.Text, this.Font);
                    g.DrawString(Lab.Text, this.Font, FontBrush, (Width - Fontsize.Width) / 2, LastPosition + (_LabControlHeight - Fontsize.Height) / 2);

                    //g.DrawLine(LinePen, 0, LastPosition, Width, LastPosition);
                    //g.DrawLine(LinePen, 0, _LabControlHeight + LastPosition, Width, _LabControlHeight + LastPosition);

                    LabColorBrush.Dispose();
                }
                else //绘制背景图标签
                {
                    g.DrawImage(ListLab.BackGroudImage, rect, Lab.BackGroundImageRect, GraphicsUnit.Pixel);
                    Fontsize = g.MeasureString(Lab.Text, this.Font);
                    g.DrawString(Lab.Text, this.Font, FontBrush, (Width - Fontsize.Width) / 2, LastPosition + (_LabControlHeight - Fontsize.Height) / 2);
                    LastPosition += _LabControlHeight;

                }
                ///绘制标准名称
                //Font this.Font = new Font("SystemFont", 9, FontStyle.Regular);


                if (Lab.IsExpand)
                {
                    PanelHeight = this.Size.Height - (InnerListLab.Count * _LabControlHeight);
                    PanelPosition = LastPosition;
                    LastPosition += PanelHeight;
                    PanelLab = Lab;
                }

            }

        }
        /// 
<summary>
        /// 绘制用户Panel区
        /// Panel区是由两个略微大于Panel的bitmap轮流滚动绘制而成的
        /// 
</summary>
        /// 
<param name="LastPosition">起始高度</param>
        /// 
<param name="PanelHeight">Panel高度</param>
        private void DrawPanel(Graphics g, int LastPosition, int PanelHeight, ListLab Lab, UserState Type)
        {

            //重新计算出Panel的绘图区域

            PanelMapPosition = 0;
            _PanelMapPosition = LastPosition;

            rectPanel = new Rectangle(0, LastPosition, this.Width, PanelHeight);
            rectRegionPanel = new Region(rectPanel);

            g.Clip = rectRegionPanel;
            DoubleGPanel.Clip = rectRegionPanel;
            //查找用户组名和当前标签名相同的用户


            switch (Type)
            {
                case UserState.ByGroup:
                    if (Lab._Position > 0)
                        thiPanelUser = Users.FindAll(delegate(UserInfomation v) { return v.Group == Lab.Text; });
                    else
                        thiPanelUser = Users;
                    break;
                case UserState.ByCapital:
                    //
                    thiPanelUser = thiPanelUser_ForSearch;

                    break;
            }



            ///计算出需要绘制的用户个数
            //DisplayUserCount = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(rectPanel.Height) / _UserControlHeight + 2));
            DisplayUserCount = rectPanel.Height / _UserControlHeight + 2;


            DrawUser();


            //DoubleG.DrawImage(BackGroundImage.Images[0], new Rectangle(0, 0, Width, Height), 0, 0, Width, Height, GraphicsUnit.Pixel, imgattr);

            //g.DrawImage(PanelMap, 0, LastPosition);
            //g.DrawImage(PanelMap_second, 0, PanelMap.Height);
            //g.DrawImage(PanelMap, new Rectangle(0, LastPosition, Width, PanelMap.Height), 0, 0, Width, PanelMap.Height, GraphicsUnit.Pixel, imgattr);
            //g.DrawImage(PanelMap_second, new Rectangle(0, PanelMap.Height, Width, PanelMap.Height), 0, 0, Width, PanelMap.Height, GraphicsUnit.Pixel, imgattr);


            g.Clip = RegionControl;
            //PanelState = DrawPanelState.Drawfirst;
            //OutEnd = false;

        }
        /// 
<summary>
        /// 混合背景
        /// 
</summary>
        /// 
<param name="rectPanel"></param>
        private void Transparent()
        {


            //先确定背景
            if (_BGImage != null)
            {
                //DoubleG.DrawImage(_BGImage,,rectPanel, 0, _PanelMapPosition,_BGImage.Width,_BGImage.Height,GraphicsUnit.Pixel,new ImageAttributes());
                DoubleG.DrawImage(_BGImage, rectControl, rectBackGroudImage, GraphicsUnit.Pixel);
            }
            else
            {
                DoubleG.FillRectangle(PanelBrush, rectPanel);

            }
        }
        /// 
<summary>
        /// 绘制用户
        /// 
</summary>
        /// 
<param name="_DoubleG"></param>
        /// 
<param name="DrawPosition"></param>
        private void DrawUser()
        {




            int UserIndex = PanelMapPosition * -1 / _UserControlHeight;
            int DrawStartY = PanelMapPosition % _UserControlHeight + _PanelMapPosition;
            int Length = DisplayUserCount + UserIndex;
            for (int i = UserIndex; i 
< Length; i++)
            {

                if (i 
>= thiPanelUser.Count || i < 0)
                {
                    return;
                }
                else
                {
                    if (i 
== LastOnClickUser)//绘制单击选中项的底色
                    {

                        DoubleGPanel.FillRectangle(OnClickColorBrush, new Rectangle(0, (i - UserIndex) * _UserControlHeight + DrawStartY, Width, _UserControlHeight - 1));

                    }
                    foreach (Column _Column in Columns)
                    {

                        if (_Column.Image 
== null)
                        {
                            if (_Column.FormatString 
== null)
                                DoubleGPanel.DrawString(thiPanelUser[i][_Column.ElementName].ToString(), this.Font, FontBrush, _Column.X, (i - UserIndex) * _UserControlHeight + DrawStartY + _Column.Y);
                            else//格式化输出
                                if (thiPanelUser[i][_Column.ElementName] !
= null)
                                    
DoubleGPanel.DrawString(String.Format(_Column.FormatString, thiPanelUser[i][_Column.ElementName].ToString()), this.Font, FontBrush, _Column.X, (i - UserIndex) * _UserControlHeight + DrawStartY + _Column.Y);
                                else
                                    DoubleGPanel.DrawString(String.Format(_Column.FormatString, ""), this.Font, FontBrush, _Column.X, (i - UserIndex) * _UserControlHeight + DrawStartY + _Column.Y);

                        }
                        else//图片输出
                        {
                            if (thiPanelUser[i].IsColor)
                                DoubleGPanel.DrawImage(_Column.Image.Images[Convert.ToInt32(thiPanelUser[i][_Column.ElementName])], _Column.X, (i - UserIndex) * _UserControlHeight + DrawStartY + _Column.Y);
                            else
                                DoubleGPanel.DrawImage(this.RGBToGray(new Bitmap(_Column.Image.Images[Convert.ToInt32(thiPanelUser[i][_Column.ElementName])])), _Column.X, (i - UserIndex) * _UserControlHeight + DrawStartY + _Column.Y);

                        }
                    }
                }

                ///绘制分隔线的Y坐标
                int LineH 
= (i - UserIndex) * _UserControlHeight + DrawStartY + _UserControlHeight - 1;
                DoubleGPanel.DrawLine(LinePen, 0, LineH, Width, LineH);


            }
        }
        /// <summary
>
        /// 绘制用户
        /// 
</summary>
        /// 
<param name="DoubleG"></param>
        /// 
<param name="UserPosition">起始用户位置,页数</param>
        /// 
<param name="DrawPosition">起始绘制位置</param>
        private void DrawUser(Graphics _DoubleG, int Page, int DrawPosition)
        {

            ///绘制分隔线的Y坐标
            int LineH = 0;


            //开始绘制

            int i;
            for (i = 0; i 
< DisplayUserCount; i++)
            {
                if (DisplayUserCount * Page + i < thiPanelUser.Count)
                {
                    foreach (Column _Column in Columns)
                    {
                        if (_Column.Image 
== null)
                        {
                            if (_Column.FormatString 
== null)
                                _DoubleG.DrawString(thiPanelUser[DisplayUserCount * Page + i][_Column.ElementName].ToString(), this.Font, FontBrush, _Column.X, i * _UserControlHeight + _Column.Y);
                            else
                                _DoubleG.DrawString(String.Format(_Column.FormatString, thiPanelUser[DisplayUserCount * Page + i][_Column.ElementName].ToString()), this.Font, FontBrush, _Column.X, i * _UserControlHeight + _Column.Y);

                        }
                        else
                        {
                            _DoubleG.DrawImage(_Column.Image.Images[Convert.ToInt32(thiPanelUser[DisplayUserCount * Page + i][_Column.ElementName])], _Column.X, i * _UserControlHeight + _Column.Y);
                        }
                    }
                    //_DoubleG.DrawString(thiPanelUser[DisplayUserCount * Page + i].Name, this.Font, FontBrush, 5, i * _UserControlHeight + 5);
                    //_DoubleG.DrawString(thiPanelUser[DisplayUserCount * Page + i].Number, this.Font, FontBrush, 80, i * _UserControlHeight + 5);
                    LineH 
= i * _UserControlHeight + _UserControlHeight - 1;
                    _DoubleG.DrawLine(LinePen, 0, LineH, Width, LineH);

                }
                else
                {
                    OutEnd 
= true;
                    
break;

                }
            }
            _UserEndPosition 
= i;


        
}
        /// <summary
>
        /// 用户区滚动
       /// 
</summary>
        private void Rolling(PaintEventArgs e)
        {
            Distance = Distance * F_M;
            if (Distance > 1)//继续滚动
            {
                PanelMapPosition += Convert.ToInt32(Distance * _direction);
                if (PanelMapPosition > 0)//滚动到头
                {
                    PanelMapPosition = 0;
                    RollCount = 0;
                    RollTime.Enabled = false;
                }
                ///滚动到末尾
                if (PanelMapPosition + thiPanelUser.Count * _UserControlHeight - rectPanel.Height 
< 0)
                {
                    if (thiPanelUser.Count 
> DisplayUserCount - 2)

                        PanelMapPosition = rectPanel.Height - thiPanelUser.Count * _UserControlHeight;
                    else
                        PanelMapPosition = 0;
                    RollCount = 0;
                    RollTime.Enabled = false;
                }
                //绘制背景
                if (_BGImage != null)
                {
                    //DoubleG.DrawImage(_BGImage,,rectPanel, 0, _PanelMapPosition,_BGImage.Width,_BGImage.Height,GraphicsUnit.Pixel,new ImageAttributes());
                    DoubleGPanel.DrawImage(_BGImage, rectPanel, rectPanel, GraphicsUnit.Pixel);
                }
                else
                {
                    DoubleGPanel.FillRectangle(PanelBrush, rectPanel);

                }
                DrawUser();

            }
            else//停止滚动
            {
                RollCount = 0;
                RollTime.Enabled = false;
            }

            switch (LabState)
            {
                case DrawState.DrawControl:
                    DrawLabs(DoubleG);
                    break;
                case DrawState.SingleLab:
                    DrawSingleLab(DoubleG);
                    break;
            }
        private void ChangePanelMap(int _direction, int Position)
        {

            Rectangle rect = new Rectangle(0, 0, PanelMap.Width - 10, PanelMap.Height - 10);
            System.Drawing.Imaging.BitmapData bmpData = PanelMap.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            IntPtr iPtr = bmpData.Scan0;

            int iBytes = PanelMap.Width * PanelMap.Height * 3;
            byte[] PixelValues = new byte[iBytes];
            System.Runtime.InteropServices.Marshal.Copy(iPtr, PixelValues, 0, iBytes);



            int _W = (PanelMap.Width) * 3;
            if (_direction > 0)//下滑
            {
                for (int j = Position; j 
< PanelMap.Height; j++)
                {
                    for (int i 
= 0; i < PanelMap.Width; i++)
                    {

                        PixelValues[(j - Position) * _W + i * 3] 
= PixelValues[j * _W + i * 3];
                        PixelValues[(j - Position) * _W + i * 3 + 1] 
= PixelValues[j * _W + i * 3 + 1];
                        PixelValues[(j - Position) * _W + i * 3 + 2] 
= PixelValues[j * _W + i * 3 + 2];

                    }

                }
                System.Runtime.InteropServices.Marshal.Copy(PixelValues, 0, iPtr, iBytes);
                PanelMap.UnlockBits(bmpData);
                Graphics DoubleG 
= Graphics.FromImage(PanelMap);



            
}



        }
        private void QQListControl_MouseUp(object sender, MouseEventArgs e)
        {


            if (!IsClickLab)
            {

                double S 
= e.Y - MouseDownY;
                //鼠标按下和弹起的位置在很小的范围内,视作单击了Panel中的某个用户

                if (Math.Abs(S) < 3)
                {
                    int i 
= Convert.ToInt32(Math.Ceiling(Convert.ToDouble(Math.Abs(e.Y - _PanelMapPosition - PanelMapPosition) / _UserControlHeight)));

                    if (++Clicks 
>= 2)//双击事件
                    {
                        Int64 now = GetTickCount();
                        if (now - MouseDoubleDownTime 
< 800)
                        {
                            if (OnDoubleClickUser !
= null)
                                
switch (LabState)
                                {
                                    case DrawState.DrawControl:
                                        if (i < thiPanelUser.Count)
                                            OnDoubleClickUser(this.thiPanelUser[i]);
                                        break;
                                    case DrawState.SingleLab:
                                        switch (LabUserDate)
                                        {
                                            case UserState.ByCapital:

                                                if (i < thiPanelUser_ForSearch.Count)
                                                    OnDoubleClickUser(this.thiPanelUser_ForSearch[i]);
                                                break;
                                            case UserState.ByGroup:
                                                if (i < thiPanelUser.Count)
                                                    OnDoubleClickUser(this.thiPanelUser[i]);
                                                break;
                                        }
                                        break;
                                }


                        }
                        else//单击事件
                        {
                            if (OnClickUser !
= null)
                                
switch (LabState)
                                {
                                    case DrawState.DrawControl:
                                        if (i < thiPanelUser.Count)
                                            OnClickUser(this.thiPanelUser[i]);
                                        break;
                                    case DrawState.SingleLab:
                                        switch (LabUserDate)
                                        {
                                            case UserState.ByCapital:

                                                if (i < thiPanelUser_ForSearch.Count)
                                                    OnClickUser(this.thiPanelUser_ForSearch[i]);
                                                break;
                                            case UserState.ByGroup:
                                                if (i < thiPanelUser.Count)
                                                    OnClickUser(this.thiPanelUser[i]);
                                                break;
                                        }
                                        break;
                                }
                            Clicks 
= 1;
                            
MouseDoubleDownTime = GetTickCount();
                        
}

                        return;
                    }
                    else//单击事件
                    {
                        MouseDoubleDownTime 
= GetTickCount();
                        
if (OnClickUser != null)
                            
switch (LabState)
                            {
                                case DrawState.DrawControl:
                                    if (i < thiPanelUser.Count)
                                        OnClickUser(this.thiPanelUser[i]);
                                    break;
                                case DrawState.SingleLab:
                                    switch (LabUserDate)
                                    {
                                        case UserState.ByCapital:

                                            if (i < thiPanelUser_ForSearch.Count)
                                                OnClickUser(this.thiPanelUser_ForSearch[i]);
                                            break;
                                        case UserState.ByGroup:
                                            if (i < thiPanelUser.Count)
                                                OnClickUser(this.thiPanelUser[i]);
                                            break;
                                    }
                                    break;
                            }
                    }


                }
                else//滚动
                {
                    //  int i 
= Convert.ToInt32(Math.Ceiling(Math.Abs(e.Y - _PanelMapPosition - PanelMapPosition) / _UserControlHeight));


                    S 
= e.Y - MouseDownY;
                    double T 
= GetTickCount() - MouseDownTime;

                    if (S 
> 0)
                        _direction = 1;
                    else
                        _direction = -1;

                    Distance = Convert.ToInt32(Math.Abs(S / T) * 18);

                    PaintState = DrawState.Rolling;

                    MouseDownTime = 0;
                    ///
                    RollTime.Interval = 30;
                    RollTime.Tick += new EventHandler(RollTime_Tick);
                    RollTime.Enabled = true;
                    return;
                    //System.Threading.Timer MoveTimer = new System.Threading.Timer(new System.Threading.TimerCallback(RollTime), null, 0, 55);
                }

            }
            IsClickLab = false;

        }
        /// 
<summary>
        /// 一段时间后自动变成SingleLab
        /// 
</summary>
        /// 
<param name="sender"></param>
        /// 
<param name="e"></param>
        void SingleLabTime_Tick(object sender, EventArgs e)
        {
            PaintState = DrawState.SingleLab;
            LabUserDate = UserState.ByGroup;
            SingleLabTime.Enabled = false;
            this.Invalidate();
        }
        /// 
<summary>
        /// Panel滑动定时器

        /// 
</summary>
        /// 
<param name="sender"></param>
        /// 
<param name="e"></param>
        void RollTime_Tick(object sender, EventArgs e)
        {
            PaintState = DrawState.Rolling;

            this.Invalidate();
        }

        private void QQListControl_MouseDown(object sender, MouseEventArgs e)
        {
            foreach (ListLab Lab in InnerListLab)
            {
                if (LabState == DrawState.DrawControl)//多Lab模式下需要判断多个Lab点击
                {
                    if (Lab.Rect.Contains(e.X, e.Y))
                    {
                        //按下标签,设置当前标签为展开状态
                        foreach (ListLab LabIn in InnerListLab)
                        {
                            LabIn.IsExpand = false;
                        }
                        Lab.IsExpand = !Lab.IsExpand;
                        PaintState = DrawState.DrawControl;
                        IsClickLab = true;
                        this.Invalidate();
                        return;
                    }
                }
                else//单Lab模式下只判断IsExpand==true的Lab是否被点击
                {
                    if (Lab.IsExpand)
                    {
                        if (Lab.Rect.Contains(e.X, e.Y))
                        {
                            PaintState = DrawState.DrawControl;
                            IsClickLab = true;
                            this.Invalidate();
                            return;
                        }
                    }
                }
            }

            MouseDownY = e.Y;
            MouseDownTime = GetTickCount();
            int i = Convert.ToInt32(Math.Ceiling(Convert.ToDouble(Math.Abs(e.Y - _PanelMapPosition - PanelMapPosition) / _UserControlHeight)));
            DrawSingleUser(i);
            //if(i
<DisplayUserCount)//点击的是第一页

        }
        private Bitmap RGBToGray(Bitmap Source)
        {

            try
            {
                int iWidth 
= Source.Width;
                
int iHeight = Source.Height;

                
Rectangle rect = new Rectangle(0, 0, iWidth, iHeight);
                System.Drawing.Imaging.BitmapData bmpData 
= Source.LockBits(rect, System.Drawing.Imaging.ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
                IntPtr iPtr 
= bmpData.Scan0;

                
int iBytes = iWidth * iHeight * 3;
                byte[] PixelValues 
= new byte[iBytes];
                System.Runtime.InteropServices.Marshal.Copy(iPtr, PixelValues, 0, iBytes);


                // 注意这个地方图像的两维方向与数组两维的方向是转置的关系 

                //R 
= new int[iHeight, iWidth];
                //G 
= new int[iHeight, iWidth];
                //B 
= new int[iHeight, iWidth];
                //Gray 
= new int[iHeight, iWidth];
                int iPoint 
= 0;

                
for (int i = 0; i < iHeight; i++)
                {
                    for (int j 
= 0; j < iWidth; j++)
                    {
                        byte b 
= PixelValues[iPoint];
                        
byte g = PixelValues[iPoint + 1];
                        byte r 
= PixelValues[iPoint + 2];
                        byte gray 
= Convert.ToByte((b + g + r) / 3);
                        PixelValues[iPoint++] 
= gray;
                        
PixelValues[iPoint++] = gray;
                        
PixelValues[iPoint++] = gray;
                        
//for (int k = 0; k < 3; k++)
                        //{
                        //    byte gray 
= (byte)(PixelValues[i*iHeight*3+(j*3)+k] - PixelValues[(i+1)*iHeight*3]+((j+1)*3)+k);

                        //    if (gray 
> 255)
                        //        gray = 255;
                        //    else if (gray 
< 0)
                        //        gray 
= 0;
                        
//    PixelValues[i * iHeight * 3 + (j * 3) + k] = gray;

                        
//}
                        //// 注意,Windows 中三基色的排列顺序是 BGR 而不是 RGB! 
                        //PixelValues[iPoint]
=PixelValues[iPoint]-PixelValues[iPoint+3]
                        
//B[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
                        
//G[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
                        
//R[i, j] = Convert.ToInt32(PixelValues[iPoint++]);
                        
////Gray[i, j] = (9798 * Convert.ToInt32(PixelValues[iPoint++]) + 19235 * Convert.ToInt32(PixelValues[iPoint++]) + 3735 * Convert.ToInt32(PixelValues[iPoint++])) / 32768;
                    }
                }
                System.Runtime.InteropServices.Marshal.Copy(PixelValues, 0, iPtr, iBytes);


                Source.UnlockBits(bmpData);
                return Source;

                // return FromGray(Gray);
            }
            catch (Exception)
            {
                //R 
= null;
                
//G = null;
                
//B = null;

                
return null;
            }
        }
        /// <summary
>
        /// 查找指定字段相匹配的用户中的第一个
        /// 
</summary>
        /// 
<param name="Name"></param>
        /// 
<param name="Value"></param>
        /// 
<returns></returns>
        public int SearchByColumnFirst(string Name, string Value)
        {
            //UserSearched Us = new UserSearched();
            int i = 0;
            foreach (UserInfomation User in this.thiPanelUser)
            {
                if (User[Name] != null)
                {
                    if (User[Name].ToString() == Value)
                    {
                        //Us.User = User;
                        //Us.Position = i;
                        return i;
                    }
                }
                i++;
            }
            return -1;
        }
        /// 
<summary>
        /// 查找指定字段相匹配的用户
        /// 
</summary>
        /// 
<param name="Name"></param>
        /// 
<returns></returns>
        public List
<int> SearchByColumnAll(string Name, string Value)
        {
            List
<int> SearchUsers = new List<int>();
            //UserSearched Us=new UserSearched();
            int i = 0;
            foreach (UserInfomation User in this.thiPanelUser)
            {
                if (User[Name] != null)
                {
                    if (User[Name].ToString() == Value)
                    {
                        //Us.User=User;
                        //Us.Position=i;
                        SearchUsers.Add(i);
                    }
                }
                i++;
            }
            return SearchUsers;
        }
        /// 
<summary>
        /// 停止闪动
        /// 
</summary>
        /// 
<param name="UserSearchPosition"></param>
        /// 
<param name="Name"></param>
        /// 
<param name="Value"></param>
        /// 
<param name="PicColumn"></param>
        public void FlashStop(int UserSearchPosition, string Name, string Value, Column PicColumn)
        {


            FlashUserInformation User = FlashUser.Find(delegate(FlashUserInformation v) { return v.Value == Value; });
            if (User.Value != null)
            {
                int Position = User.Position * _UserControlHeight + PanelMapPosition + _PanelMapPosition;

                FlashUser.Remove(User);
                DoubleGPanel.DrawImage(User.ColumnName.Image.Images[Convert.ToInt32(thiPanelUser[User.Position][User.ColumnName.ElementName])], User.ColumnName.X, Position + User.ColumnName.Y);

                ///如果闪烁过慢,可以更改此处,使其不刷新整个页面,而是只刷新修改部分
                PaintState = DrawState.NothingChange;
                this.Invalidate();
            }
        }
        /// 
<summary>
        /// 闪烁指定用户的指定图片字段
        /// 
</summary>
        /// 
<param name="User"></param>
        /// 
<param name="PicColumn"></param>
        public void Flash(int UserSearchPosition, string Name, string Value, Column PicColumn)
        {
            //this.f
            {
                FlashUserInformation User = new FlashUserInformation();
                User.Position = UserSearchPosition;
                User.Name = Name;
                User.Value = Value;
                User.ColumnName = PicColumn;
                FlashUser.Add(User);
                if (!FlashTime.Enabled)
                {
                    FlashTime.Enabled = true;
                    FlashTime.Interval = 400;
                    FlashTime.Tick += new EventHandler(FlashTime_Tick);

                }
            }
        }
        /// 
<summary>
        /// 执行闪烁图片的操作
        /// 
</summary>
        /// 
<param name="sender"></param>
        /// 
<param name="e"></param>
        private void FlashTime_Tick(object sender, EventArgs e)
        {
            int Position;

            foreach (FlashUserInformation User in FlashUser)
            {
                ///刷新前判断一下是否是正确的用户,因为多个Panel共享thiPanelUser
                if (User.Value == thiPanelUser[User.Position][User.Name].ToString())
                {
                    Position = User.Position * _UserControlHeight + PanelMapPosition + _PanelMapPosition;
                    if (FlashMode)///绘制图片
                    {
                        DoubleGPanel.DrawImage(User.ColumnName.Image.Images[Convert.ToInt32(thiPanelUser[User.Position][User.ColumnName.ElementName])], User.ColumnName.X, Position + User.ColumnName.Y);

                    }
                    else///绘制背景
                    {
                        Rectangle PicRect = new Rectangle(User.ColumnName.X, Position + User.ColumnName.Y, User.ColumnName.Width, User.ColumnName.Height);
                        if (_BGImage != null)
                        {
                            //DoubleG.DrawImage(_BGImage,,rectPanel, 0, _PanelMapPosition,_BGImage.Width,_BGImage.Height,GraphicsUnit.Pixel,new ImageAttributes());
                            DoubleG.DrawImage(_BGImage, PicRect, rectBackGroudImage, GraphicsUnit.Pixel);
                        }
                        else
                        {
                            DoubleG.FillRectangle(PanelBrush, PicRect);

                        }

                    }
                }
            }

            FlashMode = !FlashMode;
            ///如果闪烁过慢,可以更改此处,使其不刷新整个页面,而是只刷新修改部分
            PaintState = DrawState.NothingChange;
            this.Invalidate();
        }
        /// 
<summary>
        /// 用反色绘制单个被点击的用户
        /// 
</summary>
        /// 
<param name="i"></param>
        private void DrawSingleUser(int i)
        {
            if (thiPanelUser.Count > i)
            {
                //清除上次的点击
                if (LastOnClickUser >= 0)
                {


                    int PositionLast = LastOnClickUser * _UserControlHeight + PanelMapPosition + _PanelMapPosition;
                    Rectangle OldRec = new Rectangle(0, PositionLast, Width, _UserControlHeight - 1);
                    DoubleGPanel.DrawImage(_BGImage, OldRec, OldRec, GraphicsUnit.Pixel);
                    foreach (Column _Column in Columns)
                    {
                        if (_Column.Image == null)
                        {
                            if (_Column.FormatString == null)

                                DoubleGPanel.DrawString(thiPanelUser[LastOnClickUser][_Column.ElementName].ToString(), this.Font, FontBrush, _Column.X, PositionLast + _Column.Y);
                            else
                                //  DoubleGPanel.DrawString(String.Format(_Column.FormatString, thiPanelUser[LastOnClickUser][_Column.ElementName].ToString()), this.Font, FontBrush, _Column.X, PositionLast + _Column.Y);
                                if (thiPanelUser[i][_Column.ElementName] != null)
                                    DoubleGPanel.DrawString(String.Format(_Column.FormatString, thiPanelUser[LastOnClickUser][_Column.ElementName].ToString()), this.Font, FontBrush, _Column.X, PositionLast + _Column.Y);
                                else
                                    DoubleGPanel.DrawString(String.Format(_Column.FormatString, ""), this.Font, FontBrush, _Column.X, PositionLast + _Column.Y);


                        }
                        else
                        {
                            if (thiPanelUser[i].IsColor)
                                DoubleGPanel.DrawImage(_Column.Image.Images[Convert.ToInt32(thiPanelUser[LastOnClickUser][_Column.ElementName])], _Column.X, PositionLast + _Column.Y);
                            else

                                DoubleGPanel.DrawImage(this.RGBToGray(new Bitmap(_Column.Image.Images[Convert.ToInt32(thiPanelUser[LastOnClickUser][_Column.ElementName])])), _Column.X, PositionLast + _Column.Y);

                        }
                    }
                }


                LastOnClickUser = i;
                int Position = i * _UserControlHeight + PanelMapPosition + _PanelMapPosition;
                DoubleGPanel.FillRectangle(OnClickColorBrush, new Rectangle(0, Position, Width, _UserControlHeight - 1));
                foreach (Column _Column in Columns)
                {
                    if (_Column.Image == null)
                    {
                        if (_Column.FormatString == null)

                            DoubleGPanel.DrawString(thiPanelUser[i][_Column.ElementName].ToString(), this.Font, FontBrush, _Column.X, Position + _Column.Y);
                        else
                            if (thiPanelUser[i][_Column.ElementName] != null)

                                DoubleGPanel.DrawString(String.Format(_Column.FormatString, thiPanelUser[i][_Column.ElementName].ToString()), this.Font, FontBrush, _Column.X, Position + _Column.Y);
                            else
                                DoubleGPanel.DrawString(String.Format(_Column.FormatString, ""), this.Font, FontBrush, _Column.X, Position + _Column.Y);


                    }
                    else
                    {
                        if (thiPanelUser[i].IsColor)
                            DoubleGPanel.DrawImage(_Column.Image.Images[Convert.ToInt32(thiPanelUser[i][_Column.ElementName])], _Column.X, Position + _Column.Y);
                        else
                            DoubleGPanel.DrawImage(this.RGBToGray(new Bitmap(_Column.Image.Images[Convert.ToInt32(thiPanelUser[i][_Column.ElementName])])), _Column.X, Position + _Column.Y);


                    }
                }
                PaintState = DrawState.SingleUser;
                this.Invalidate(rectPanel);

            }
        }
    }
    /// 
<summary>
    /// 指示QQListControl控件如何绘制内容
    /// 
</summary>
    public class Column
    {
        /// 
<summary>
        /// 格式化输出
        /// 
</summary>
        public string FormatString = null;
        /// 
<summary>
        /// 指向UserInfomation的列位置
        /// 
</summary>
        public string ElementName;
        /// 
<summary>
        /// 显示起始X位置
        /// 
</summary>
        public int X;
        /// 
<summary>
        /// 显示起始Y坐标
        /// 
</summary>
        public int Y;
        /// 
<summary>
        /// ImageList对象不为空,绘制图形
        /// 
</summary>
        public ImageList Image;
        /// 
<summary>
        /// 图像宽度
        /// 
</summary>
        public int Width;
        /// 
<summary>
        /// 图像高度
        /// 
</summary>
        public int Height;

    }
    /// 
<summary>
    /// 标签类    
    /// 
</summary>
    public class ListLab
    {
        static Rectangle _BackGroundImageRect;
        public static int _Height = 15;
        static Color _staticBackColor;
        /// 
<summary>
        /// 指向QQlistControl的Imagelist位置
        /// 
</summary>
        public int BGIndexer = -1;
        static Image _BackImage;
        /// 
<summary>
        /// 标签名字
        /// 
</summary>
        public string Text;

        /// 
<summary>
        /// 背景图
        /// 
</summary>
        public static Image BackGroudImage
        {
            set { _BackImage = value; _Height = value.Height; _BackGroundImageRect = new Rectangle(0, 0, value.Width, value.Height); }
            get { return _BackImage; }
        }
        /// 
<summary>
        /// 背景图的Rectangle
        /// 
</summary>
        public Rectangle BackGroundImageRect
        {
            get { return _BackGroundImageRect; }
        }
        /// 
<summary>
        /// 标签高度,静态变量
        /// 
</summary>
        public int Height
        {
            get { return _Height; }
            set { _Height = value; }
        }
        /// 
<summary>
        /// 背景色,静态变量        
        /// 
</summary>
        public Color BackColor
        {
            set { _staticBackColor = value; }
            get { return _staticBackColor; }
        }
        /// 
<summary>
        /// 是否展开
        /// 
</summary>
        public bool IsExpand = false;
        /// 
<summary>
        /// QQListControl类使用


        /// 
</summary>
        public Label _Label;
        /// 
<summary>
        /// QQListControl类使用


        /// 
</summary>
        public Panel _Panel;
        /// 
<summary>
        /// QQListControl类使用
        /// QQListControl类使用


        /// 
</summary>
        public Rectangle Rect;
        public int _Position;

    }

}

代码主要有三个类:

 1.QQListControl : 继承与UserControl,是个用户控件。

 2.Column:控件列名,支持自定义列。

 3.ListLab:分组标签。考虑到手机屏幕大小,分组标签一段时间后会自动折叠,仅显示当前标签。

典型是用代码如下:

代码
 #region//控件1的初始化
            
                #region //添加用户
                for (int i = 0; i 
< 200; i++)
                {
                    UserInfomation Users 
= new UserInfomation();
                    switch (i % 4)
                    {
                        case 0:

                            Users.Name 
= "同学" + i.ToString();
                            Users["Name"] 
= Users.Name;
                            
Users["Number"] = "130000000" + i.ToString();
                            Users.Group 
= "同学";
                            break;
                        case 1:

                            Users.Name 
= "同事" + i.ToString();
                            Users["Name"] 
= Users.Name;
                            
Users["Number"] = "130000000" + i.ToString();
                            Users.Group 
= "同事";
                            break;
                        case 2:

                            Users.Name 
= "朋友" + i.ToString();
                            Users["Name"] 
= Users.Name;
                            
Users["Number"] = "130000000" + i.ToString();
                            Users.Group 
= "朋友";
                            break;
                        case 3:

                            Users.Name 
= "家人" + i.ToString();
                            Users["Name"] 
= Users.Name;
                            
Users["Number"] = "130000000" + i.ToString();
                            Users.Group 
= "家人";
                            break;

                    }
                    qqListControl1.Users.Add(Users);
                }
                #endregion
                #region//添加标签
                ListLab Labs1 
= new ListLab();
                Labs1.Text 
= "同学";

                ListLab Labs2 
= new ListLab();
                Labs2.Text 
= "同事";

                ListLab Labs3 
= new ListLab();

                Labs3.Text 
= "朋友";
                ListLab Labs4 
= new ListLab();
                Labs4.Text 
= "家人";
                qqListControl1.AddListLab(Labs1);
                qqListControl1.AddListLab(Labs2);
                qqListControl1.AddListLab(Labs3);
                qqListControl1.AddListLab(Labs4);

                #endregion
                #region //添加绘制字段
                Column Columns1 
= new Column();
                Column Columns2 
= new Column();
                Columns1.ElementName 
= "Name";
                Columns1.X 
= 10;
                
Columns1.Y = 2;
                
qqListControl1.AddColumn(Columns1);

                Columns2.ElementName 
= "Number";
                Columns2.X 
= 100;
                
Columns2.Y = 2;
                
qqListControl1.AddColumn(Columns2);
                #endregion
                #region //鼠标事件
                qqListControl1.OnClickUser+
=new QQListControl.DelegateClickUser(qqListControl1_OnClickUser);
                qqListControl1.OnDoubleClickUser+
=new QQListControl.DelegateDoubleClickUser(qqListControl1_OnDoubleClickUser);
                #endregion

显示效果如下:

代码很乱,界面很一般,功能也不完善,忙完IM后我会对这个控件做进一步处理的。要代码的给我留言吧。

原文地址:https://www.cnblogs.com/nevermad/p/1621756.html