How to Change Appearance of all DataRepeater Items at Run Time
DataRepeater control is one of the most important controls in Visual Basic PowerPacks. John Chen has recently posted a great blog about this control’s background and usage. As a complement, I want to talk about how to customize DataRepeater item appearance here.
Generally speaking, you could change appearance of DataRepeater items in approaches below:
1. To set appearance of all items
a. At design time
Select DataRepeater’s ItemTemplate, and set its appearance-related properties in Property Window, like the snapshot below shows. These properties will be copied and applied to all items at run time.
b. At run time
At run time, you could reset properties of DataRepeater’s ItemTemplate. New properties will overwrite corresponding properties you set at design time, and apply to all items, no matter whether the item has been scrolled into view or not.
2. To set appearance of an individual item
a. At design time
Not surprisingly, there is no way to do this. Because all items are dynamically created from ItemTemplate at run time, they do not exist at design time at all.
b. At run time
You could handle DrawItem event to change appearance of an individual item when it is scrolled into view.
In this article, I want to talk about how to set appearance of all items at run time, because users tend to forget to put their ItemTemplate-modifying code block between BeginResetItemTemplate and EndResetItemTemplate methods, which causes the appearance of DataRepeater items unpredictable.
What the code should be like
Suppose you have a DataRepeater control named dataRepeater1, and you want to modify its ItemTemplate properties at run time, then the code should be like:
[VB]
Me.DataRepeater1.BeginResetItemTemplate()
' Code to change appearance properties of ItemTemplate and its child controls
Me.DataRepeater1.ItemTemplate.BackColor = Color.Blue
Me.DataRepeater1.ItemTemplate.Controls("textBox1").Visible = False
......
Me.DataRepeater1.EndResetItemTemplate()
[C#]
this .dataRepeater1.BeginResetItemTemplate();
// Code to change appearance properties of ItemTemplate and its child controls
this.dataRepeater1.ItemTemplate.BackColor = Color.Blue;
this.dataRepeater1.ItemTemplate.Controls["textBox"].Visible = false;
......
this.dataRepeater1.EndResetItemTemplate();
Why need to call BeginResetItemTemplate and EndResetItemTemplate method
About the reason, I want to talk a little about the underlying implementation of DataRepeater. The implementation I’m going to talk about is current design of DataRepeater (also simplified to make it more understandable), and is possible to change in the future.
For performance reasons, DataRepeater does NOT create one DataRepeaterItem UI object for each data item. Instead, it just creates a few DataRepeaterItem instances (by cloning ItemTemplate), re-uses them, and creates some new ones on demand. These instances are stored in two Queues, let’s call them DisplayItemsQueue and SpareItemsQueue. DisplayItemsQueue holds real DataRepeaterItem objects for all visible data items, i.e. items that are located within visible area of DataRepeater control. When a new data item is scrolled into view, DataRepeater tries to retrieve a DataRepeaterItem object from SpareItemsQueue, binds it to the data item, raises DrawItem event for it so that user has a chance to customize its appearance, puts it to DisplayItemQueue and displays it; when a data item is scrolled out of view, its DataRepeateritem object is revoked, and is put into SpareItemsQueue for future re-use. When DataRepeater tries to retrieve a DataRepeateritem object from SpareItemsQueue and if this Queue is empty, a new DataRepeateritem object will be created from ItemTemplate and directly returned.
So, what happens when you change ItemTemplate’s properties? Take the VB code for example.
1 Without calling BeginResetItemTemplate and EndResetItemTemplate:
// Before updating ItemTemplate properties, DataRepeater has already created some DataRepeaterItem objects for visible items. These DataRepeaterItem objects’ properties will NOT be affected by code below.
Me.DataRepeater1.ItemTemplate.BackColor = Color.Blue
Me.DataRepeater1.ItemTemplate.Controls("textBox1").Visible = False
;
......
// The updated properties only apply to new DataRepeaterItem objects that are created on demand later.
2 When calling BeginResetItemTemplate and EndResetItemTemplate:
// When calling BeginResetItemTemplate, all already-created DataRepeaterItem objects are removed from the Queue and discarded.
Me.DataRepeater1.BeginResetItemTemplate()
Me.DataRepeater1.ItemTemplate.BackColor = Color.Blue
Me.DataRepeater1.ItemTemplate.Controls("textBox1").Visible = False
......
Me.DataRepeater1.EndResetItemTemplate()
// After calling EndResetItemTemplate(), all DataRepeaterItem objects are re-created from the updated ItemTemplate and the updated changes will be applied.
Comments
Anonymous
September 04, 2009
The comment has been removedAnonymous
September 07, 2009
I'm sorry but there's not an easy way to do so. DataRepeater doesn't provide the API to change the color of the seperator, and since it is drawn in the non-client area, it's hard for .NET developers to do so. For more information, please see: http://msdn.microsoft.com/en-us/library/dd162743(VS.85).aspxAnonymous
June 02, 2010
Is It possible to do content wrapping similar to FlowLayoutPanel?Anonymous
June 02, 2010
Is it possible to do content wrapping for Datarepeater control like in FlowLayoutPanel control? For Example, (with vertical layout)
|1|2|3|4| | _________ | _________ | _________ | _________ | | | | | | | | | | | | | | | |Picturebox| | |Picturebox| | |Picturebox| | |Picturebox| | | || | || | || | || | ||||| |5|6|7|8| | _________ | _________ | _________ | _________ | | | | | | | | | | | | | | | |Picturebox| | |Picturebox| | |Picturebox| | |Picturebox| | | || | || | || | || | ||||| |9|_10|_11|_12| | _________ | _________ | _________ | _________ | | | | | | | | | | | | | | | |Picturebox| | |Picturebox| | |Picturebox| | |Picturebox| | | || | || | || | || | |||||