none
重绘 ListBox显示效果后滚动条失败! RRS feed

  • 问题

  • 本来想重绘一个 ListBox,用来显示两行文字,可是继承 ListBox重写了OnPaint事件后,滚动条好像不起做用了,无论拉到哪里,都是从第一个向后显示。也就是说OnPaint好像有问题。

    代码如下:


    1 using System;  
    2 using System.Collections.Generic;  
    3 using System.Text;  
    4 using System.Windows.Forms;  
    5 using System.Drawing;  
    6 using System.Collections;  
    7  
    8  
    9 namespace HappyFarmDotNet  
    10 {  
    11     class ListBoxEx : System.Windows.Forms.ListBox  
    12     {  
    13         public ListBoxEx()  
    14         {  
    15             ItemHeight = 65;  
    16  
    17             this.SetStyle(ControlStyles.UserPaint, true);  
    18  
    19             Click += new EventHandler(OnClick);  
    20         }  
    21         protected override void OnPaint(PaintEventArgs e)  
    22         {  
    23  
    24             for (int i = 0; i < Items.Count; i++)  
    25             {  
    26                 if (SelectedIndex == i)  
    27                 {  
    28                     DrawSelectedItems(e, i);  
    29                 }  
    30                 else 
    31                 {  
    32                     DrawNomalItems(e,i);  
    33                 }  
    34             }  
    35             base.OnPaint(e);  
    36         }  
    37  
    38         private void OnClick(object sender, EventArgs e)  
    39         {  
    40             this.Refresh();  
    41         }  
    42         private void DrawNomalItems(PaintEventArgs e, int x)  
    43         {  
    44        //     e.Graphics.TranslateTransform(this.AutoScrollOffset.X, this.AutoScrollOffset.Y);  
    45             e.Graphics.DrawRectangle(Pens.Beige, 1, (x * 65 + 1), e.ClipRectangle.Width - 3, 45);  
    46             e.Graphics.DrawString(Items[x].ToString(), Font, Brushes.SkyBlue, 65, (x * 65) + 8);  
    47         }  
    48  
    49         private void DrawSelectedItems(PaintEventArgs e, int x)  
    50         {  
    51             //画边框  
    52             e.Graphics.DrawRectangle(Pens.Beige, 1, (x * 65 + 1), e.ClipRectangle.Width - 3, 45);  
    53             //填充选中Item背景  
    54             e.Graphics.FillRectangle(Brushes.RoyalBlue, 1 + 1, (x * 65 + 1 + 1), e.ClipRectangle.Width - 3 - 1, 45 - 1);  
    55             //定义虚线画笔并绘边框  
    56             Pen Line = new Pen(Color.Black, 1);  
    57             Line.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;  
    58  
    59             e.Graphics.DrawRectangle(Line, 1, (x * 65 + 1), e.ClipRectangle.Width - 3, 45);  
    60             //画文字  
    61             e.Graphics.DrawString(Items[x].ToString(), Font, Brushes.SkyBlue, 65, (x * 65) + 8);  
    62  
    63         }  
    64     }  
    65 }  
    66  

    请高手指点。谢谢 

    • 已移动 Sheng Jiang 蒋晟Moderator 2009年3月23日 22:17 Windows窗体类库问题 (从 Visual C# 移动到 .NET Framework 一般性问题讨论区)
    2009年3月23日 14:21

答案

  • 你好!
         这个属性可能引起了你的误解,他是指当listbox在窗体不可见的时候,窗体的自动滚动功能将listbox滚动到什么位置!默认是(0,0)
         关于你的问题,我刚才试了一下,感觉listBox本身很难获得滚动位置,没有找到这样的事件和属性,我还没有想到好的办法啊!

    周雪峰
    2009年3月24日 5:41
    版主

全部回复

  • 你好!
         你拖动滚动条的时候控件要重新绘制的,这是就会调用OnPaint方法了,所以每次都重头绘制了,看上去就想滚动条失效一样。
         你的OnPaint方法的实现需要考虑到这样的情况,你可以考虑加个字段用来记录滚动条的位置,可以在滚动条滚动事件中记录设置这个字段,然后在OnPaint中根据这个值绘图!

    周雪峰
    2009年3月23日 14:51
    版主
  • thanks.
    但是我在listbox裡面根本沒有發現滾動條的值,我該如何定議滾動條的值然後根據值去畫,

    請指點,如果給出原代碼更好,謝謝。 

    順便再問一下AutoScrollOffset的值為什麼一直是0,0?
    2009年3月24日 2:02
  • 你好!
         这个属性可能引起了你的误解,他是指当listbox在窗体不可见的时候,窗体的自动滚动功能将listbox滚动到什么位置!默认是(0,0)
         关于你的问题,我刚才试了一下,感觉listBox本身很难获得滚动位置,没有找到这样的事件和属性,我还没有想到好的办法啊!

    周雪峰
    2009年3月24日 5:41
    版主