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

  • 相关阅读:
    [ArcPy Tips5] 矢量版的Zonal Statistics As Table (仅面积)
    《当我们阅读时我们看到了什么》豆瓣:7.5
    linux10 /ubuntu系统常见问题
    scala.Predef$.refArrayOps([Ljava/lang/Object;)[Ljava/lang/Object; 错误原因分析
    docker换源/限制日志大小
    jQuery插件的开发
    Pretty Gmail GreasemonkeyScript
    Centos 8修改防火墙
    CentOS 安装Docker
    事务传播行为
  • 原文地址:https://www.cnblogs.com/nevermad/p/1621756.html
Copyright © 2020-2023  润新知