This message was discovered on microsoft.public.dotnet.languages.vb.
Responses highlighted in red are from those people who are likely to be able to contribute good, authoratitive information to this discussion. They include Microsoft employees, MVP's and others who IMHO contribute well to these kinds of discussions.
| James Radke |
Hello,
I am creating an owner draw listbox for a windows application. It is all working, except the performance is significantly slower than the standard listbox. Basically what I have done is added two new properties (full source below):
ChangeBackgroundMember = a bound data field which contains a boolean as to whether this record should get a special background color ChangeBackgroundColor = the color to use when the above mentioned flag is set to true
Can someone tell me what I can do to improve the performance of this modified databound listbox?
Thanks!
======================================== source code ====================================================================
Imports System.Drawing Imports System.Drawing.Drawing2D
Public Class ColoredListBox Inherits ListBox
Private _ChangeBackgroundMember As String Private _ChangeBackgroundColor As Color
Public Property ChangeBackgroundMember() As String Get Return _ChangeBackgroundMember End Get Set(ByVal Value As String) _ChangeBackgroundMember = Value End Set End Property
Public Property ChangeBackgroundColor() As Color Get Return _ChangeBackgroundColor End Get Set(ByVal Value As Color) _ChangeBackgroundColor = Value End Set End Property
Private Sub ColoredListBox_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles MyBase.DrawItem Dim brush As Brush Dim selected As Boolean Dim displayText As String
' Get the current data row in the bound datatable Dim myRow As DataRowView = CType(sender.items(e.Index), DataRowView)
' The following method should generally be called before drawing. ' It is actually superfluous here, since the subsequent drawing ' will completely cover the area of interest. e.DrawBackground()
'Declare backcolor and forecolor temporary variables Dim myBackColor As Color Dim myForeColor As Color
' if the item is selected, then show it as darkblue background with white text If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then myBackColor = Color.DarkBlue myForeColor = Color.White Else ' if the field indicated by the properties is true, then set the background color to ' the specified color, otherwise use the default background and foreground colors If myRow(ChangeBackgroundMember) Then myBackColor = ChangeBackgroundColor myForeColor = Color.Black Else myBackColor = Me.BackColor myForeColor = Me.ForeColor End If End If ' Create a brush of the background color, and fill the field area brush = New SolidBrush(myBackColor) e.Graphics.FillRectangle(brush, e.Bounds)
' Create a brush of the foreground color and draw the text using the value of the display field brush = New SolidBrush(myForeColor) e.Graphics.DrawString(myRow(Me.DisplayMember), Me.Font, brush, e.Bounds.X, e.Bounds.Y)
e.DrawFocusRectangle()
myRow = Nothing End Sub End Class
|
|
|
| |
|
| |
| |
| Peter Huang (VIP) |
Hi James,
I tested your code on my machine with the Orders table in the Northwind database. The performance is just one second on my machine similar with the ListBox.
Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load Dim o As DateTime o = Now Dim lstbx As ColoredListBox SqlDataAdapter1.Fill(Me.DataSet31) lstbx = New ColoredListBox lstbx.DrawMode = DrawMode.OwnerDrawFixed Me.Controls.Add(lstbx) lstbx.DataSource = Me.DataSet31.Orders lstbx.DisplayMember = "ShipName" lstbx.ChangeBackgroundMember = "ShipVia" lstbx.ChangeBackgroundColor = Color.Red Dim ts As New TimeSpan(Now.Ticks - o.Ticks) MsgBox(ts.Ticks) MsgBox(ts.Seconds) End Sub
In the ColoredListBox, I just change one code line to adapt my test table(Orders)
If myRow(ChangeBackgroundMember) >= 1 Then
and this will cause the ColoredListBox render about 800 rows of data in ColoredListBox.
You may create a new project and try my code to see if the problem persist. My test environment is PIII733, 512MB RAM. If you have any concern on this issue, please post here.
Regards, Peter Huang Microsoft Online Partner Support Get Secure! www.microsoft.com/security This posting is provided "as is" with no warranties and confers no rights.
|
|
|
| |
|
|
| |
| |
| James Radke |
Good Morning Peter,
On my application, I am using the listbox on a sub-form (i.e. modal pop-up). When the pop up is loaded using the standard listbox, as soon as the page appears, all data is already showing in the listbox (very fast load). When I use the ColoredListbox in the pop up in place of the Listbox, the time is very close using your measuring method to show the pop-up screen; however, when the page is rendered the listbox does not have any data in it yet, and it seems to take a couple seconds 3-4 before the data slowly gets rendered in the listbox and the items appear.
Once it has been created, it appears that the scrolling using the scroll bars is about the same as the listbox.
What could be causing the delay between when the ColoredListbox is first presented empty, and the slow actual rendering of the items in the listbox? Is there another override that I missed that I need to do in my class?
Thanks!
Jim
"Peter Huang" <Click here to reveal e-mail address> wrote in message news:Click here to reveal e-mail address... [Original message clipped]
|
|
|
| |
|
|
| |
| |
| Peter Huang (VIP) |
Hi James,
It seems that the performance hit occurs in the ownerdraw function. You may try to change your code as follows.
Dim brush As SolidBrush Public Sub New() MyBase.New() brush = New SolidBrush(Color.Black) End Sub
Private Sub ColoredListBox_DrawItem(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawItemEventArgs) Handles MyBase.DrawItem Dim selected As Boolean Dim displayText As String ' Get the current data row in the bound datatable Dim myRow As DataRowView = CType(sender.items(e.Index), DataRowView) ' The following method should generally be called before drawing. ' It is actually superfluous here, since the subsequent drawing ' will completely cover the area of interest. e.DrawBackground() 'Declare backcolor and forecolor temporary variables Dim myBackColor As Color Dim myForeColor As Color ' if the item is selected, then show it as darkblue background with white(Text) If (e.State And DrawItemState.Selected) = DrawItemState.Selected Then myBackColor = Color.DarkBlue myForeColor = Color.White Else ' if the field indicated by the properties is true, then set the background color to ' the specified color, otherwise use the default background and foreground(colors) If myRow(ChangeBackgroundMember) >= 1 Then myBackColor = ChangeBackgroundColor myForeColor = Color.Black Else myBackColor = Me.BackColor myForeColor = Me.ForeColor End If End If ' Create a brush of the background color, and fill the field area brush.Color = myBackColor e.Graphics.FillRectangle(brush, e.Bounds) ' Create a brush of the foreground color and draw the text using the value of the display field brush.Color = myForeColor e.Graphics.DrawString(myRow(Me.DisplayMember), Me.Font, brush, e.Bounds.X, e.Bounds.Y) e.DrawFocusRectangle() myRow = Nothing End Sub
You may also try to test with fewer datarow in your coloredlistbox to see if the problem persists. I have also tested with a popup form, the render will complete less than one second after the form is show on about 8000 rows data. Did the problem occurs when you popup your form with coloredlistbox on the second time? (i.e. you click a button will popup the form with coloredlistbox , close the form and popup it again) If you have any concern on this issue, please post here.
Regards, Peter Huang Microsoft Online Partner Support Get Secure! www.microsoft.com/security This posting is provided "as is" with no warranties and confers no rights.
|
|
|
| |
|
|
| |
|
| |
| James Radke |
Peter,
The application is working fine now. It seems like if I recompiled the application as Release versus Debug, many of the performance issues went away. This type of performance change between release and debug was not something that I had experienced before.
So, for now, I would say that this is fine!
Thanks for the help!
Jim
"James Radke" <Click here to reveal e-mail address> wrote in message news:Click here to reveal e-mail address... [Original message clipped]
|
|
|
| |
|
| |
|
|
|
|
|
|
|