[智能设备]SmartPhone开发常用类(三) 自定义菜单(ListView)

    技术2022-05-11  144

    转自微软的例子using System;using System.Windows.Forms;using System.Collections;using System.Drawing;using System.Data;using System.Reflection;

    using System.Drawing.Imaging;

    namespace SmartUI {     enum MailIcon {          unopened,          opened     }

         /// <summary>     /// Class used to store display score info     /// </summary>     class MailItem {          public MailIcon icon;          public string sender;          public string subject;

              public MailItem(MailIcon Icon, string Sender, string Subject)         {               this.icon = Icon;               this.sender = Sender;               this.subject = Subject;          }     }

         /// <summary>     /// Provide a 2 line listview     /// </summary>     class MyListView : OwnerDrawnList {      constint Column1Left  = 5;//条目位图X位置      const int Column2Left  = 25;//条目文字X位置

          public MyListView() {           // We need a total of 5 rows, so the height is 180/5=36           Graphics g = this.CreateGraphics();           Font font = new Font(this.Font.Name, 10, FontStyle.Bold);           // Calc line height to be height of letter A plus 10%           int fontHeight = (int)(g.MeasureString("A", font).Height*1.1);//计算当前字体的高度*1.1作为字体高度           this.ItemHeight = fontHeight*2; //每一条目为两行汉字,因此为字体高度*2           g.Dispose();      }

          //键盘处理流程。上/下键已由基类处理,这里只处理回车键      protected override void OnKeyDown(KeyEventArgs e) {           switch(e.KeyCode) {                case Keys.Return:                     MessageBox.Show("You selected item " + this.SelectedIndex.ToString(),                          "Item selected",                           MessageBoxButtons.OK,                          MessageBoxIcon.Asterisk,                          MessageBoxDefaultButton.Button1);                 break;           }

               base.OnKeyDown(e);      }

          /// <summary>      /// 自定义绘图事件。绘制ListView的条目      /// </summary>      /// <param name="e"></param>     protected override void OnPaint(PaintEventArgs e) {              // Declare vars           Font font;           Color fontColor;           string bmpName;              // 从控件位图中产生控件绘图区,注:控件位图为控件不含滚动条的可显示区域图像,即条目显示部分           Graphics gOffScreen = Graphics.FromImage(this.OffScreen);

               //以控件背景色填充绘图区           gOffScreen.FillRectangle(new SolidBrush(this.BackColor), this.ClientRectangle);

                      int itemTop = 0;//当前条目的Y坐标

               // 绘制可显示的条目,从滚动条当前位置绘制DrawCount个条目           for(int n = this.VScrollBar.Value; n <= this.VScrollBar.Value + DrawCount; n++)             {

                        //如果该条目为当前选中条目,则要高亮显示                if(n == this.SelectedIndex)                 {                    //用高亮色填出该条目区域                     gOffScreen.FillRectangle(new SolidBrush(SystemColors.Highlight),                          0,                          itemTop,                          //如果滚动条可显,则要减去滚动条的宽度                          this.ClientSize.Width - (this.VScrollBar.Visible ? this.VScrollBar.Width : 0),                          this.ItemHeight);                         //字体颜色为高亮色的对比色                         fontColor = CalcTextColor(SystemColors.Highlight);                }                else                     fontColor = this.ForeColor; //否则,字体颜色为控件前景色

                // 用灰色绘制分割线            gOffScreen.DrawLine(new Pen(Color.DarkGray),                  1,                  itemTop+this.ItemHeight,                  this.ClientSize.Width - (this.VScrollBar.Visible ? this.VScrollBar.Width : 2),                 itemTop+this.ItemHeight);

                // 取得当前条目            MailItem lvi = (MailItem)this.Items[n];

                // 设置字体和条目位图            if (lvi.icon == MailIcon.unopened) { //如果为未开状态,则设置为粗体字                 font = new Font(this.Font.Name, 10, FontStyle.Bold);                 bmpName = "SmartUI.unread.bmp";//位图的名称            }            else {                 font = new Font(this.Font.Name, 10, FontStyle.Regular);                 bmpName = "SmartUI.read.bmp";            }

                // Load image                Bitmap bmp = new Bitmap(Assembly.GetExecutingAssembly().GetManifestResourceStream(bmpName));                        //设置图片的透明颜色,在本实例中为红色                ImageAttributes ia = new ImageAttributes();                ia.SetColorKey(Color.Red, Color.Red);

                //设置位图绘图区域            Rectangle imgRect = new Rectangle(Column1Left, itemTop+3, bmp.Width, bmp.Height);

                // 绘制条目位图            gOffScreen.DrawImage(bmp, imgRect, 0, 0, bmp.Width, bmp.Height, GraphicsUnit.Pixel, ia);            // 绘制条目文字            gOffScreen.DrawString(lvi.sender, font, new SolidBrush(fontColor), Column2Left, itemTop);            // 绘制条目文字            gOffScreen.DrawString(lvi.subject, font, new SolidBrush(fontColor), Column2Left, itemTop + (ItemHeight/2));

                // 清理            font.Dispose();            bmp.Dispose();

                // 设置下一个条目的Y位置=当前条目的Y位置+条目高度            itemTop += this.ItemHeight;       }

           // 将整个绘图位图绘制到控件上       e.Graphics.DrawImage(this.OffScreen, 0, 0);

           gOffScreen.Dispose();      }

          // Draws the external border around the control.          protected override void OnPaintBackground(PaintEventArgs e) {       //   e.Graphics.DrawRectangle(new Pen(Color.Black), 0, 0, this.ClientSize.Width - 1, this.ClientSize.Height - 1);      }     }

        // 基类 OwnerDrawnList     class OwnerDrawnList : Control {          int scrollWidth;          int itemHeight         = -1;          int selectedIndex      = -1;

              Bitmap offScreen; //控件位图为控件不含滚动条的可显示区域图像,即条目显示部分          VScrollBar vs; //竖向滚动条          ArrayList items;//条目数组                  public OwnerDrawnList() {               this.vs = new VScrollBar(); //产生滚动条               scrollWidth = this.vs.Width; //设定滚动条宽度=控件默认宽度               this.vs.Parent      = this; //滚动条的父窗口为控件               this.vs.Visible     = false; //不可见               this.vs.SmallChange = 1; //最小变化量为1               this.vs.ValueChanged += new EventHandler(this.ScrollValueChanged);//设置滚动变化事件

                   // Items to draw               this.items = new ArrayList();//产生Item数组          }          /// <summary>          /// 条目数组          /// </summary>          public ArrayList Items {               get { return this.items;}          }        /// <summary>        /// 控件位图        /// </summary>          protected Bitmap OffScreen {               get {return this.offScreen;}          }          /// <summary>          /// 控件滚动条          /// </summary>          protected VScrollBar VScrollBar {               get {return this.vs;}          }          /// <summary>          /// 选中条目索引改变事件          /// </summary>          public event EventHandler SelectedIndexChanged;

              // Raise the SelectedIndexChanged event          protected virtual void OnSelectedIndexChanged(EventArgs e) {               if(this.SelectedIndexChanged != null) //如果设置了选中Item变化的事件,则执行                this.SelectedIndexChanged(this, e);          }

              // 获取或设置当前选中项目索引          public int SelectedIndex {               get {return this.selectedIndex;} //返回索引                            set {                        this.selectedIndex = value; //设置新索引值,并调用索引改变事件                        if (this.SelectedIndexChanged != null)                         this.SelectedIndexChanged(this, EventArgs.Empty);                   }          }

              protected void ScrollValueChanged(object o, EventArgs e) {               this.Refresh();          }

              protected virtual int ItemHeight {               get {return this.itemHeight;}               set {this.itemHeight = value;}          }

              // If the requested index is before the first visible index then set the          // first item to be the requested index. If it is after the last visible          // index, then set the last visible index to be the requested index.          public void EnsureVisible(int index) {//计算滚动条的当前位置               if(index < this.vs.Value) {//如果新位置<原有滚动条位置                    this.vs.Value = index;                    this.Refresh();               }               else if(index >= this.vs.Value + this.DrawCount) {                    this.vs.Value = index - this.DrawCount + 1;                    this.Refresh();               }          }

              // 键盘事件,处理上下键          protected override void OnKeyDown(KeyEventArgs e) {               switch(e.KeyCode) {                    case Keys.Down: //Down键时,如果当前选中索引<滚动条的最大值,则当前选中索引+1,并显示                         if(this.SelectedIndex < this.vs.Maximum) {                              EnsureVisible(++this.SelectedIndex);                              this.Refresh();                         }                         break;                    case Keys.Up://Up键时,如果当前选中索引>滚动条的最小值,则当前选中索引-1,并显示                         if(this.SelectedIndex > this.vs.Minimum) {                              EnsureVisible(--this.SelectedIndex);                              this.Refresh();                         }                         break;               }

                   base.OnKeyDown(e); //调用基类的键盘事件          }

              //计算实际需要绘制条目数量          protected int DrawCount {               get {                    if(this.vs.Value + this.vs.LargeChange > this.vs.Maximum)//如果从当前位置到最尾+可显示最大栏目数量>总栏目数量                         return this.vs.Maximum - this.vs.Value + 1; //返回实际栏目数量                    else                     return this.vs.LargeChange; //否则,返回可显示最大栏目数量               }          }        //控件尺寸调整事件         protected override void OnResize(EventArgs e) {               int viewableItemCount = this.ClientSize.Height / this.ItemHeight; //可显示栏目数量=控件高度/条目高度                                   this.vs.Bounds = new Rectangle(this.ClientSize.Width - scrollWidth,//重新调整滚动条大小                    0,                    scrollWidth,                    this.ClientSize.Height);

                    //重新计算控件位图的大小               //判断是否需要滚动条           if(this.items.Count > viewableItemCount) { //如果条目数大于可显示条目数,则显示滚动条,并把滚动条最大变化量设置为可显示条目数                    this.vs.Visible = true;                    this.vs.LargeChange = viewableItemCount;                    //产生一个控件可显示区位图                    //宽度=控件宽度-滚动条宽度                    //高度=控件高度                    this.offScreen = new Bitmap(this.ClientSize.Width - scrollWidth, this.ClientSize.Height);            }           else { //如果不需要滚动条                    this.vs.Visible = false;                    this.vs.LargeChange = this.items.Count;                    //产生一个控件可显示区位图                    this.offScreen = new Bitmap(this.ClientSize.Width, this.ClientSize.Height);           }

               this.vs.Maximum = this.items.Count - 1; //计算滚动条的最大值=条目个数-1      }

         //决定什么颜色作为高亮选中条目的字体颜色      protected Color CalcTextColor(Color backgroundColor) {           if(backgroundColor.Equals(Color.Empty))                 return Color.Black;  //如果背景颜色为空,则返回黑色

               int sum = backgroundColor.R + backgroundColor.G + backgroundColor.B;

               if(sum > 256) //如果红绿蓝颜色大于256,则返回黑色                return Color.Black;           else                return Color.White; //否则返回白色      }

         }}----------------------------------------------------------------------------------------------------------------------------------------------调用方法public CustomListView()  {   //   // Required for Windows Form Designer support   //   InitializeComponent();

       //   // TODO: Add any constructor code after InitializeComponent call   //      olv = new MyListView();   olv.Parent = this;   // Set the bounds of the listview.   olv.Bounds = new Rectangle(0,0, this.ClientSize.Width, this.ClientSize.Height);

       // Add data items to listview   for (int i=0; i<10; i++) {    olv.Items.Add(new MailItem(MailIcon.unopened, "James Pratt", "re: Custom ListView"));    olv.Items.Add(new MailItem(MailIcon.opened, "Chung Webster", "Custom ListView"));   }

       olv.SelectedIndex = 0;   olv.EnsureVisible(olv.SelectedIndex);     }


    最新回复(0)