Sections in repeater

J

Jakob Lithner

I have a usercontrol where I intend to list all responsibilities a person has
for the coming weeks. In the section I will write the day, date and month. In
the row I will write a description of the responsibility.

<asp:Repeater ID="repResponsibility" runat="server">
<ItemTemplate>
<div class="adSection"><asp:Literal id="litSection"
runat="server"></asp:Literal></div>
<div class="adRow"><asp:Literal id="litRow"
runat="server"></asp:Literal></div>
</ItemTemplate>
</asp:Repeater>

Section and Row are formatted with an appropriate CSS-class.
To the Repeater I connect a collection and pick the values:

Protected Sub repResponsibility_ItemDataBound(ByVal sender As Object,
ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles
repResponsibility.ItemDataBound
Dim r As Responsibility

Dim litSection As Literal
Dim litRow As Literal

Select Case e.Item.ItemType
Case ListItemType.Item
r = CType(e.Item.DataItem, Responsibility)

'Point out controls
litSection = CType(e.Item.FindControl("litSection"), Literal)
litRow = CType(e.Item.FindControl("litRow"), Literal)

'Set values
litSection.Text = r.ActivityStart.Value.ToString("dddd d
MMMM kl.HH")
litRow.Text = String.Format("{0}, {1}", r.Person,
r.ResponsibilityTypeName)
End Select
End Sub


All works fine. But it would be much nicer if I could group all
responsibilities that belongs to the same date under ONE section heading.
Do I really need to have two collections and two nested repeaters to
accomplish this, or is there a better alternative?
 
W

Walter Wang [MSFT]

Hi,

I'm not aware of any built-in controls can do that grouping for you, I'm
afraid you'll have to do that manually such as using nested repeaters. Let
me know if you need help on this.

By the way, you might also need to include ListItemType.AlternatingItem in
the Select Case check.

Sincerely,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications. If you are using Outlook Express, please make sure you clear the
check box "Tools/Options/Read: Get 300 headers at a time" to see your reply
promptly.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jakob Lithner

I see. Thanks for the advice.
Two nested repeaters and collections really seems like overkill .....
Maybe it is possible to check for repeated identical sections and in that
case hide them? I think I will have a try with that.
 
W

Walter Wang [MSFT]

Hi,

That's a good idea to hide the sections after the data binding is
completed. You just need to enumerate the repeater item and check if the
section text is identical to previous one. Since Repeater doesn't have an
event called DataBound, I think this can be done right after you called
Repeater.DataBind().

Let me know if you need more info on this.

Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 
J

Jakob Lithner

I am not sure I got your idea, to do the hiding AFTER the data binding ....?

I find it more natural to keep doing it in the ItemDataBound event, where I
have all the information needed.

The biggest problem was to find a way to hide/collapse the section.
In my initial example I did the line breaks by using <DIV>-tags, but the
problem with them is that they will occupy space even when they have no
InnerHTML. And I was not able to get hold of them to change attributes from
code. Is it possible?

Next I tried TextBox control. It is easy to get hold of from code and I was
able to hide border and set ReadOnly. So I had clean VB-code, but I was not
able to get rid of all visual padding .... It kept looking strange, despite
my efforts.

So my final solution was to switch to Label-controls. Setting "display:
block" will give the Label a similar block behaviour as the previous
<DIV>-tag. By changing the CSS-style I was able to hide it from code
depending on data values.

I am not perfectly happy about dragging CSS-layout into the code, but it
works fine and looks nice!

Suggestion on improvements are welcome.



CSS-template
============================
..gadgetSection
{
display: block;
font-weight: bold;
margin-top: 10px;
}
..gadgetLine
{
display: block;
}



ASP-code
============================
<asp:Repeater ID="repLista" runat="server">
<ItemTemplate>
<asp:Label ID="lblSection" CssClass="gadgetSection"
runat="server"></asp:Label>
<asp:Label ID="lblLine" CssClass="gadgetLine"
runat="server"></asp:Label>
</ItemTemplate>
</asp:Repeater>





Code-behind
============================
Protected Sub repLista_ItemDataBound(ByVal sender As Object, ByVal e As
System.Web.UI.WebControls.RepeaterItemEventArgs) Handles
repLista.ItemDataBound
Dim lblSection As Label
Dim lblLine As Label
Dim dv As System.Data.DataRowView
Dim c As dsNorthwind.CustomersRow
Static lastCity As String = ""

Select Case e.Item.ItemType
Case ListItemType.Item, ListItemType.AlternatingItem

'Grab the data
dv = DirectCast(e.Item.DataItem, System.Data.DataRowView)
c = CType(dv.Row, dsNorthwind.CustomersRow)

'Find the controls
lblSection = DirectCast(e.Item.FindControl("lblSection"),
Label)
lblLine = DirectCast(e.Item.FindControl("lblLine"), Label)

'Display data
lblLine.Text = c.CompanyName
If lastCity = c.City Then
lblSection.Style.Add("display", "none")
Else
lblSection.Text = c.City
End If

'Remember value for comparison
lastCity = c.City
End Select
End Sub
 
W

Walter Wang [MSFT]

Hi,

Your solution is fine.

What I meant to do the grouping after the databinding is completed is
demonstrated using following code:

This is the business object:
====================

Public Class Responsibility
Private m_activityStart As DateTime
Public Property ActivityStart() As DateTime
Get
Return m_activityStart
End Get
Set(ByVal value As DateTime)
m_activityStart = value
End Set
End Property
Private m_person As String
Public Property Person() As String
Get
Return m_person
End Get
Set(ByVal value As String)
m_person = value
End Set
End Property
Private m_responsibilityTypeName As String
Public Property ResponsibilityTypeName() As String
Get
Return m_responsibilityTypeName
End Get
Set(ByVal value As String)
m_responsibilityTypeName = value
End Set
End Property

Public Sub New(ByVal activityStart As DateTime, ByVal person As String,
ByVal responsibilityTypeName As String)
m_activityStart = activityStart
m_person = person
m_responsibilityTypeName = responsibilityTypeName
End Sub

End Class


This is the web form:
================

<form id="form1" runat="server">
<div>
<asp:Repeater ID="repResponsibility" runat="server">
<ItemTemplate>
<div class="adSection">
<asp:Literal ID="litSection"
runat="server"></asp:Literal></div>
<div class="adRow">
<asp:Literal ID="litRow"
runat="server"></asp:Literal></div>
</ItemTemplate>
</asp:Repeater>
</div>
</form>


This is the code-behind of the web form:
===============================

Protected Sub repResponsibility_ItemDataBound(ByVal sender As Object,
ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles
repResponsibility.ItemDataBound
Dim r As Responsibility

Dim litSection As Literal
Dim litRow As Literal

Select Case e.Item.ItemType
Case ListItemType.Item, ListItemType.AlternatingItem
r = CType(e.Item.DataItem, Responsibility)

'Point out controls
litSection = CType(e.Item.FindControl("litSection"),
Literal)
litRow = CType(e.Item.FindControl("litRow"), Literal)

'Set values
litSection.Text = r.ActivityStart.ToString("dddd d MMMM")
litRow.Text = String.Format("{0}, {1}", r.Person,
r.ResponsibilityTypeName)
End Select
End Sub

Private Sub GroupBySections()
Dim litSection As Literal
Dim litRow As Literal

Dim prevSection As String = String.Empty
Dim currentSection As String

For Each ri As RepeaterItem In Me.repResponsibility.Items
If (ri.ItemType = ListItemType.AlternatingItem Or ri.ItemType =
ListItemType.Item) Then
litSection = CType(ri.FindControl("litSection"), Literal)
litRow = CType(ri.FindControl("litRow"), Literal)

currentSection = litSection.Text
If currentSection <> prevSection Then
prevSection = currentSection
Else
litSection.Visible = False
End If
End If
Next
End Sub

Protected Sub Page_Load(ByVal sender As Object, ByVal e As
System.EventArgs) Handles Me.Load
Dim list As New List(Of Responsibility)
Dim dt1 As DateTime = DateTime.Now
list.Add(New Responsibility(dt1, "test1", "test"))
list.Add(New Responsibility(dt1, "test2", "test"))
Dim dt2 As DateTime = dt1.AddDays(1)
list.Add(New Responsibility(dt2, "test3", "test"))
list.Add(New Responsibility(dt2, "test4", "test"))
Me.repResponsibility.DataSource = list
Me.repResponsibility.DataBind()

GroupBySections()
End Sub



As you can see from above code, actually we only need to set the literal's
Visible property to False to exclude it from the output. You can verify
that the <div> of the hidden section doesn't exists in the html source.

Anyway, I believe this is only two different approach to the same objective.

Let me know if you need further information on this. Thanks.

Regards,
Walter Wang ([email protected], remove 'online.')
Microsoft Online Community Support

==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================

This posting is provided "AS IS" with no warranties, and confers no rights.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,744
Messages
2,569,482
Members
44,901
Latest member
Noble71S45

Latest Threads

Top