• 在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后我会对这个控件做进一步处理的。要代码的给我留言吧。

  • 相关阅读:
    【Nginx】ngx_event_core_module模块
    ELMAH--Using HTTP Modules and Handlers to Create Pluggable ASP.NET Components 77 out of 90 rated th
    nyist oj 214 单调递增子序列(二) (动态规划经典)
    java 入门书籍(java7)
    ARCGIS将WGS84坐标投影到高斯平面
    【linux】linux下对java程序生成dump文件,并使用IBM Heap Analyzer进行分析,查找定位内存泄漏的问题代码
    【springboot】【socket】spring boot整合socket,实现服务器端两种消息推送
    【linux】linux修改open file 大小
    【docker】docker限制日志文件大小的方法+查看日志文件的方法
    【docker】docker部署spring boot服务,但是docker logs查看容器输出控制台日志,没有日志打印,日志未打印,docker logs不打印容器日志
  • 原文地址:https://www.cnblogs.com/nevermad/p/1621756.html
Copyright © 2020-2023  润新知