R
Rick
I'm in the process of creating an "owner drawn" list control. Each
item displays a 50 x 50 icon and a brief text description. There is a
scroll bar that's not part of the control, when used, it sets the
scrolltop property of the list, which triggers a repaint. Each icon
is 2-3k each and getting a fairly significant flicker when scrolling.
Is there another method I should be using to implement this, or is it
just a PPC limitation?
Public Class DrawnObjectList
Inherits Windows.Forms.Control
Private m_Objects As
MWG.PocketBirds.Model.Collections.IdItObjectsCollection
Private m_ScrollTop As Integer
Private strat As DrawingStrategy
Public Sub New()
Me.strat = New ObjectIconDrawingStrategy()
End Sub
Public Property ScrollTop() As Integer
Get
Return m_ScrollTop
End Get
Set(ByVal value As Integer)
m_ScrollTop = value
' force repaint
Me.Invalidate()
End Set
End Property
''' <summary>
''' List of objects to bind to
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property Objects() As
MWG.PocketBirds.Model.Collections.IdItObjectsCollection
Get
' If the list hasn't been set, return an empty collection
If m_Objects Is Nothing Then
m_Objects = New
MWG.PocketBirds.Model.Collections.IdItObjectsCollection
End If
Return m_Objects
End Get
Set(ByVal value As
MWG.PocketBirds.Model.Collections.IdItObjectsCollection)
m_Objects = value
End Set
End Property
Protected Overrides Sub OnPaint(ByVal e As
System.Windows.Forms.PaintEventArgs)
If Objects.Count = 0 Then Exit Sub
Dim itemsPerPage As Integer
Dim FirstIndex As Integer
Dim LastIndex As Integer
Dim obj As MWG.PocketBirds.Model.Database.IdItObject
Me.strat.MaxHeight = Me.Height
Me.strat.MaxWidth = Me.Width
' Number of items that will be in view( or partially )
itemsPerPage = Me.strat.ItemsPerPage
' Index of first item to display
FirstIndex = strat.FirstIndex(Me.m_ScrollTop)
' Index of first item to display
LastIndex = strat.LastIndex(Me.m_ScrollTop)
' Draw all of the items
For i As Integer = FirstIndex To LastIndex
If i > Objects.Count - 1 Then Exit For
obj = Objects(i)
strat.DrawItem(e.Graphics, obj, m_ScrollTop, i)
Next
End Sub
End Class
Public Class ObjectIconDrawingStrategy
Inherits DrawingStrategy
Public Overrides ReadOnly Property ItemsPerPage() As Integer
Get
Return CType(Math.Ceiling(m_MaxHeight / ItemHeight) * 2, Integer) +
2
End Get
End Property
Public Overrides ReadOnly Property FirstIndex(ByVal scroll As
Integer) As Integer
Get
Return CType(Math.Floor(scroll / ItemHeight) * 2, Integer)
End Get
End Property
Public Overrides ReadOnly Property LastIndex(ByVal scroll As Integer)
As Integer
Get
Return FirstIndex(scroll) + ItemsPerPage - 1
End Get
End Property
Public Sub New()
Me.m_ItemHeight = 86
Me.m_ItemWidth = 66
m_Icons = New Hashtable
End Sub
Private m_Icons As Hashtable
Public Overrides Sub DrawItem(ByVal gfx As System.Drawing.Graphics,
ByVal entity As MWG.PocketBirds.Model.Database.IdItEntity, ByVal
scroll As Integer, ByVal index As Integer)
Dim bm As Bitmap
Dim itemRect As Rectangle
Dim brush As New System.Drawing.SolidBrush(Color.Black)
Dim top As Integer
' Get the icon from either cache or file system
If Not m_Icons.ContainsKey("O" + entity.id.ToString()) Then
bm = New Bitmap(Globals.Model.GetBinary("O" + entity.id.ToString(),
True))
m_Icons.Add("O" + entity.id.ToString(), bm)
Else
bm = CType(m_Icons("O" + entity.id.ToString()), Bitmap)
End If
If index Mod 2 = 0 Then ' Even items
top = CType(((index / 2) * Me.m_ItemHeight), Integer) - scroll
' Draw the icon
gfx.DrawImage(bm, 2, top + 2)
' Rectangle for bird name
itemRect = New Rectangle(2, top + 50 + 2, ItemWidth, 9)
' Write bird name
' TODO: Center and wrap string
gfx.DrawString(entity.ToString(), New
System.Drawing.Font(System.Drawing.FontFamily.GenericSansSerif, 5,
FontStyle.Regular), brush, itemRect)
Else ' Odd Items
top = CType((((index - 1) / 2) * Me.m_ItemHeight), Integer) -
scroll
' Draw the icon
gfx.DrawImage(bm, 68, top + 2) ' itemRect, 0, 0, bm.Width,
bm.Height, GraphicsUnit.Pixel, New
System.Drawing.Imaging.ImageAttributes())
' Rectangle for bird name
itemRect = New Rectangle(68, top + 50 + 2, ItemWidth, 9)
' Write bird name
gfx.DrawString(entity.ToString(), New
System.Drawing.Font(System.Drawing.FontFamily.GenericSansSerif, 5,
FontStyle.Regular), brush, itemRect)
End If
End Sub
End Class
item displays a 50 x 50 icon and a brief text description. There is a
scroll bar that's not part of the control, when used, it sets the
scrolltop property of the list, which triggers a repaint. Each icon
is 2-3k each and getting a fairly significant flicker when scrolling.
Is there another method I should be using to implement this, or is it
just a PPC limitation?
Public Class DrawnObjectList
Inherits Windows.Forms.Control
Private m_Objects As
MWG.PocketBirds.Model.Collections.IdItObjectsCollection
Private m_ScrollTop As Integer
Private strat As DrawingStrategy
Public Sub New()
Me.strat = New ObjectIconDrawingStrategy()
End Sub
Public Property ScrollTop() As Integer
Get
Return m_ScrollTop
End Get
Set(ByVal value As Integer)
m_ScrollTop = value
' force repaint
Me.Invalidate()
End Set
End Property
''' <summary>
''' List of objects to bind to
''' </summary>
''' <value></value>
''' <returns></returns>
''' <remarks></remarks>
Public Property Objects() As
MWG.PocketBirds.Model.Collections.IdItObjectsCollection
Get
' If the list hasn't been set, return an empty collection
If m_Objects Is Nothing Then
m_Objects = New
MWG.PocketBirds.Model.Collections.IdItObjectsCollection
End If
Return m_Objects
End Get
Set(ByVal value As
MWG.PocketBirds.Model.Collections.IdItObjectsCollection)
m_Objects = value
End Set
End Property
Protected Overrides Sub OnPaint(ByVal e As
System.Windows.Forms.PaintEventArgs)
If Objects.Count = 0 Then Exit Sub
Dim itemsPerPage As Integer
Dim FirstIndex As Integer
Dim LastIndex As Integer
Dim obj As MWG.PocketBirds.Model.Database.IdItObject
Me.strat.MaxHeight = Me.Height
Me.strat.MaxWidth = Me.Width
' Number of items that will be in view( or partially )
itemsPerPage = Me.strat.ItemsPerPage
' Index of first item to display
FirstIndex = strat.FirstIndex(Me.m_ScrollTop)
' Index of first item to display
LastIndex = strat.LastIndex(Me.m_ScrollTop)
' Draw all of the items
For i As Integer = FirstIndex To LastIndex
If i > Objects.Count - 1 Then Exit For
obj = Objects(i)
strat.DrawItem(e.Graphics, obj, m_ScrollTop, i)
Next
End Sub
End Class
Public Class ObjectIconDrawingStrategy
Inherits DrawingStrategy
Public Overrides ReadOnly Property ItemsPerPage() As Integer
Get
Return CType(Math.Ceiling(m_MaxHeight / ItemHeight) * 2, Integer) +
2
End Get
End Property
Public Overrides ReadOnly Property FirstIndex(ByVal scroll As
Integer) As Integer
Get
Return CType(Math.Floor(scroll / ItemHeight) * 2, Integer)
End Get
End Property
Public Overrides ReadOnly Property LastIndex(ByVal scroll As Integer)
As Integer
Get
Return FirstIndex(scroll) + ItemsPerPage - 1
End Get
End Property
Public Sub New()
Me.m_ItemHeight = 86
Me.m_ItemWidth = 66
m_Icons = New Hashtable
End Sub
Private m_Icons As Hashtable
Public Overrides Sub DrawItem(ByVal gfx As System.Drawing.Graphics,
ByVal entity As MWG.PocketBirds.Model.Database.IdItEntity, ByVal
scroll As Integer, ByVal index As Integer)
Dim bm As Bitmap
Dim itemRect As Rectangle
Dim brush As New System.Drawing.SolidBrush(Color.Black)
Dim top As Integer
' Get the icon from either cache or file system
If Not m_Icons.ContainsKey("O" + entity.id.ToString()) Then
bm = New Bitmap(Globals.Model.GetBinary("O" + entity.id.ToString(),
True))
m_Icons.Add("O" + entity.id.ToString(), bm)
Else
bm = CType(m_Icons("O" + entity.id.ToString()), Bitmap)
End If
If index Mod 2 = 0 Then ' Even items
top = CType(((index / 2) * Me.m_ItemHeight), Integer) - scroll
' Draw the icon
gfx.DrawImage(bm, 2, top + 2)
' Rectangle for bird name
itemRect = New Rectangle(2, top + 50 + 2, ItemWidth, 9)
' Write bird name
' TODO: Center and wrap string
gfx.DrawString(entity.ToString(), New
System.Drawing.Font(System.Drawing.FontFamily.GenericSansSerif, 5,
FontStyle.Regular), brush, itemRect)
Else ' Odd Items
top = CType((((index - 1) / 2) * Me.m_ItemHeight), Integer) -
scroll
' Draw the icon
gfx.DrawImage(bm, 68, top + 2) ' itemRect, 0, 0, bm.Width,
bm.Height, GraphicsUnit.Pixel, New
System.Drawing.Imaging.ImageAttributes())
' Rectangle for bird name
itemRect = New Rectangle(68, top + 50 + 2, ItemWidth, 9)
' Write bird name
gfx.DrawString(entity.ToString(), New
System.Drawing.Font(System.Drawing.FontFamily.GenericSansSerif, 5,
FontStyle.Regular), brush, itemRect)
End If
End Sub
End Class