views:

411

answers:

3

Hi Guys,

I have a repeater that should show a bound field value only if it exists. Having read this post I decided to do it by using a literal within my repeater and using the OnItemDatabound trigger to populate my literal but my literal doesn't seem to be accessible from the c# code behind and I don't understand why!

Heres the aspx page

    <asp:Repeater runat="server" ID="rpt_villaresults" OnItemDataBound="checkForChildren">
    <HeaderTemplate>

    </HeaderTemplate>
    <ItemTemplate>       
//.................MORE CODE HERE......................                           
<div class="sleeps"><h4>To Sleep</h4><h5><%#Eval("sleeps")%> <asp:Literal ID="sleepsChildrenLit" runat="server" /> </h5></div>
//.............MORE CODE HERE........................

And the code behind

public void checkForChildren(object sender, RepeaterItemEventArgs e)
{
    Literal childLit = e.Item.FindControl("sleepsChildrenLit") as Literal; 
    //this is null at runtime
    String str = e.Item.DataItem.ToString();
    if (e.Item.DataItem != null)
    {
        if (Regex.IsMatch(str, "[^0-9]"))
        {
            if (Convert.ToInt32(str) > 0)
            {
                childLit.Text = " + " + str;
            }
        }         
    }
}
+2  A: 

As you are probably aware when you say: as Literal it can return null values. If you do a proper cast you will get an exception at runtime that will give you more info as to what is wrong and/or which element is causing you the problem.

If you always expect "chilLit" to have a value and your not checking for nulls then you should cast it to a Literal using

Literal childLit = (Literal)e.Item.FindControl("sleepsChildrenLit");
cgreeno
Great minds think alike ;)
Jon Skeet
+2  A: 

Well, with your current code we don't know whether that's because e.Item.FindControl is returning null, or because it wasn't a Literal. This is why you should use a cast instead of "as" if you're sure of the type that it really should be.

Change the code to:

Literal childLit = (Literal) e.Item.FindControl("sleepsChildrenLit");

and see what happens. If you get a cast exception, you'll know it's because it was the wrong type. If you still get an NRE, then FindControl was returning null.

EDIT: Now, aside from that, let's have a look at the code after it:

String str = e.Item.DataItem.ToString();
if (e.Item.DataItem != null)
{
    ...
}

If e.item.DataItem is null then the call to ToString() is going to throw an exception - so the check on the next line is pointless. I suspect you actually want:

if (e.Item.DataItem != null)
{
    String str = e.Item.DataItem.ToString();
    ...
}
Jon Skeet
Thanks Jon. I used the cast and the childLit is still null.It's also strange that intelisense isn't picking up the literal in the code behind. I should just be able to reference sleepsChildrenLit.Text.... but I cant even though its running at server.I thought that you could put a literal anywhere?
mancmanomyst
+2  A: 

The OnItemDataBound event handler checkForChildren() will also be called for the HeaderItem of the repeater. But in that case, e.Item.DataItem will be null. And of course FindControl() will also return null, since you do not have a Literal control with an ID "sleepsChildrenLit" in the HeaderTemplate.

You can use the e.Item.ItemType property to check whether the current Item is a HeaderItem of a FooterItem, or a "normal" Item, e.g:

if (e.Item.ItemType == ListItemType.Header)
{
...
}
else if (...)
{
...
}
M4N