Beginner's question about binding/formatting a repeater

B

B. Chernick

I'm doing a web app in VB/Dot Net 2.0. I'm probably a bit rusty and I have
no experience using the repeater control.

I have a user control I've created with multiple properties. I've created a
test page and I've managed to bind the usercontrol to a repeater and display
some data in the following fashion:
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="ObjectDataSource1">
<ItemTemplate >
<uc1:AUserControl runat="server" SomeField='<%# Eval("SomeField") %>' />
</ItemTemplate>
</asp:Repeater>

This works but I get a single line of controls down the left hand of the
window. Also these controls are unevenly grouped by a key field. In other
words, what I would like to see is something like this, a 2 dimensional
formatting:

AAAAAAA
AAA
BBB
CCCCCC
D

and so on.

Is there a way to format a repeater in this style?

(What I would really like is something equivalent to Winform's
FlowLayoutPanel but I would settle for a scheme that permitted a fixed number
of controls per row.)
 
C

Cowboy \(Gregory A. Beamer\)

When you first start using the Repeater, it sometimes helps to lay out how
you want it to look and work backwards. All a repeater does is repeat HTML
for each record. So, if you know what you want it to look like, you can look
at the HTML and find where it repeats.

In your case, you end up with the repeater doing something like:

<td><uc1:AUserControl runat="server" SomeField='<%# Eval("SomeField") %>'
/></td>

You also want it to end after 7 repeats, so you have to use the row
databinding and do something like this:

//lineCount is something you set
if((lineCount%7) == 0)
{
//write out </tr><tr>
}

NOTE: You will have to create lineCount as a member field, as you can get
some info from event args, but not all.

You will also have to figure, in the same event, if you just switched
control types, because you will want to pad out the row with additional
<td>&nbsp;</td> bits. Something like:

//controlType is a variable you set, like lineCount
if(row.ControlType != controlType)
{
//pad row with enough <td>&nbsp;</td> blocks to fill row to 7
}

Hope this helps!
 
B

B. Chernick

I'm afraid I'm still a bit confused. At first I thought you were writing
javascript but it looks like what you are suggesting is outputting HTML
components in Dot Net code. (And you're using C#.) Right?

Given that, what do you mean by 'row databinding'? I've just done a little
hacking and I'm thinking that what I might do is use the Repeater_ItemCreated
event for this purpose. At least it seems to fire once per control/record.
 
B

B. Chernick

Perhaps I should restate this. The group of records has a main key field
(call it pk1). It also has a second subgrouping key (call it pk2). While
all the records have the same pk1, there is no predicting how many will have
any given value of pk2. So you could have 20 records with pk2 = 1, 1 record
with pk2 = 2, 6 records with pk2 = 3, etc. The records have to be displayed
2-dimensionally in their respective subgroups, and using a squarish custom
control that prevents use of more conventional grid layouts.

In any case, If I understood Cowboy correctly, I should insert html into the
page programmatically but I've never done this before and I'm having a hard
time finding the right reference. I've a feeling that I just don't know the
right key word yet. (And putting a
'Page.Response.Output.Write("</tr>test<tr>")' in the ItemCreated event just
puts text at the top of the page.)

Perhaps my real question now is how do I (can I) insert html at a specific
point in the page using the repeater ItemCreated event?
 
C

Cowboy \(Gregory A. Beamer\)

Pardon for getting past beginner. The short answer is the repeater will not
do the staggered rows, as you desire, by default. If you can have this
format:

AAAAAAA
AAABBBC
CCCCDDD

You can use a DataList instead of a repeater, as it will allow you to
specify a horizontal alignment and put a row break in after 7 items. There
is nothing that natively does this.

AAAAAAA
AAA
BBB
CCCCC
DDD

etc.

You can use a Repeater, but you end up with some code involved. The
information on the repeater class is here:
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeater.aspx

With Repeater, the event is ItemDataBound (with many other controls is it
Row data bound), which is here:
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeater.itemdatabound.aspx

this is where you would add the </tr><tr>.

The other event is ItemCreated, which occurs as the item is created. This is
where you have to pad prior to outputting the row.

Yes, this is a bit more complex. If you can live with

AAAAAAA
AAABBBC
CCCCDDD

it is much easier, as you simply use a DataList and set the parameters.

There is nothing I know of that will do precisely what you want in a web
control. There might be a third party control out there that does it,
however.
 
C

Cowboy \(Gregory A. Beamer\)

The ItemDataBound is useful for injecting code at the end of the event, so
it can be used to end the rows and start a new row.

I will have to delve into ItemCreated, as it is designed to circumvent the
natural coding, so you end up having to put the data back into the item. I
am not sure I will get a chance until later tonight or this weekend, so if
you find an answer, respond back and I will avoid the extra work. :)
 
M

Marc

I design one element (my text boxes, labels etc) and then create a repeater.
I copy and patse that element into the <ItemTemplate> tag.
Then I override the Item_DataBound event.
I check if e.item.ItemType is either Item or Alternating Item, and if so I
fill the labels/text boxes etc with data, using database fields.
e.g.
txtFirstName.Text := DataBinder.Eval(e.item.DataItem, 'sFirstName');

Yes that's Delphi :)

I find it all gets a bit mesy when you bind stuff inline on the ASPX page,
especially when you start using nested repeaters and user controls that need
to be loaded dynamically depending on a database field's value.

Hope this helps,


Marc
 
B

B. Chernick

I don't think so. It looks like what I need to do is simply insert a little
HTML into the page while it's rendering. But I need to know if that's
possible, and most importantly, HOW!
 
B

B. Chernick

I believe I've found a solution. How 'elegant' it is is another matter.

The repeater events were no use at all. I put a couple of public variables
into a module and overrode the usercontrol's render routine. At the
beginning, I did a
writer.Write("<Table id='" + tableId + "'>")

Every time that grouping key changes I output
writer.Write("</tr></table><Table>")

I put a <td> around every control and created a new <tr> after every 7
instances.
Since I also stored the max number of records in the module, I output
writer.Write("</table>") at the end.

All tables but the first are set to style='visibility:hidden'. Next step is
to write some Javascript.
 
C

Cowboy \(Gregory A. Beamer\)

You are one step away from making your own server control (compiled
control), so congratulations. You have gone beyond whee we were taking you,
although the code is still in the ASP.NET code behind. If you move it to a
server control (you do not have to do this now, btw), you will have achieved
a bit of elegance.

I hope this does not sound insincere, as I truly love it when someone thinks
beyond the problem to the solution. And, I am truly happy for you on finding
a solution. :)
 
B

B. Chernick

? Excuse me. Terminology question. I thought I was creating a 'server
control'. In any case the user control declaration within the ItemTemplate
of the repeater has the runat="Server" tag.
 

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,769
Messages
2,569,579
Members
45,053
Latest member
BrodieSola

Latest Threads

Top