Specifying XPath node indexes for nested repeaters - asp.net

Let's say I have an XML hierarchy that looks similar to this:
<Animal>
<Kingdom>
<Phylum>
<Class></Class>
<Class></Class>
</Phylum>
<Phylum>
<Class></Class>
<Class></Class>
</Phylum>
</Kingdom>
<Kingdom>
<Phylum>
<Class></Class>
<Class></Class>
</Phylum>
</Kingdom>
</Animal>
(etc.)
Likewise, I have ASP.NET code using nested repeaters, something like this:
<asp:Repeater ID="ShowKingdom" runat="server" DataSource="(SomeDataSource)">
<ItemTemplate>
<asp:TextBox ID="txtKingdom" runat="server" XPath="/*[local-name()='Animal']/*[local-name()='Kingdom'][{0}]">
<asp:Repeater ID="ShowPhylum" runat="server" OnItemDataBound="(SomeDataBinder)">
<ItemTemplate>
<asp:TextBox ID="txtKingdom" runat="server" XPath="/*[local-name()='Animal']/*[local-name()='Kingdom'][{0}]/*[local-name()='Phylum'][???]">
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
My problem: how do I specify the node index selector "[???]" for the XPath inside the nested repeater?!?
Note: my language is VB within ASP.NET.
Edit: I've tried using a different index "[{1}]" (gives me an index out-of-bounds error), a relative Xpath "[local-name()='Phylum']" (no "/*" preceding it -- does not recognize the node/path), and tinkering with the nested repeater data source (it either doesn't recognize the XPath or crashes).
Obviously, I haven't been able to get any of these to work. Do I need to consider another approach?
Edit #2: Another thing I tried that does not want to work: for the nested repeater:
DataSource="<%# XPathSelect('Phylum')%>"

I finally figured this out. I found the key here.
After doing a lot of digging, I realized that my {0} predicate index in my XPath was being replaced in the code-behind using a call to String.format.
I obtained the parent repeater index by referencing e.Item.Parent.Parent (where "e" is a RepeaterItemEventArgs object).
Once I had the indexes for both the current repeater and its parent, I was able to use {0} and {1} for my indexes, and the String.format did the rest.
Voila. Problem solved.

Related

"The name 'Bind' does not exist in the current context" when manipulating the result of Bind

I'm trying to bind a hue value retrieved from a databound gridview control to the backcolour of the text box that is being used to display the value. After editing the ItemTemplate for the relevant column, I've added the following code to take the Hue value from my data, convert it to a colour and then pass that to the BackColor property:
<asp:TextBox ID="TextBox8" runat="server" BackColor='<%# GetColourFromHue(int.Parse(Bind("Hue"))) %>' ReadOnly="True" Text='<%# Bind("Hue") %>'></asp:TextBox>
However, I get the following error:
CS0103: The name 'Bind' does not exist in the current context
The issue is the fact that I'm wrapping the Bind("Hue") command in more code: GetColourFromHue(int.Parse(Bind("Hue"))).
How can I manipulate the value returned by Bind so that I can assign it to the control property?
Thanks to #Andrei's comment, I can't use Bind, but I can use Eval. The following works:
GetColourFromHue(int.Parse(Eval("Hue").ToString()))

Too many characters in character literal?

Can you tell me please what is wrong with this code??? About to getting crazy!!!
<asp:LinkButton ID="LinkButton1" OnClick="DivAc('griddiv')" Font-Size="Smaller" runat="server" CommandName='<%# Eval("harf").ToString().ToUpper()%>'><%# Eval("harf").ToString().ToUpper() %></asp:LinkButton>
Error: Too many characters in character literal... :(
Is DivAc('griddiv') a javascript function?
Then you have to use OnClientClick instead of OnClick.
OnClick is reserved for .NET functions. With OnClientClick you generates the OnClick-attribute in HTML.
This is probably a bit confusing.
So this is what you have to do:
<asp:LinkButton ID="LinkButton1" OnClientClick="DivAc('griddiv')" Font-Size="Smaller" runat="server" CommandName='<%# Eval("harf").ToString().ToUpper()%>'><%# Eval("harf").ToString().ToUpper() %></asp:LinkButton>
The immediate issue is that you placed a string (griddiv) in character quotes (a single quote, in C#, is for a single character only). You would need to write something like OnClick="DivAc(\"griddiv\")"
BUT
OnClick is a server-side event handler that takes the name of a public or protected function that takes (object,EventArgs) and returns void. So this won't compile anyway.
Where is DivAc? In JavaScript? If so, you want OnClientClick, in which case you can leave the single and double quotes as they are.
I think that your error is here:
CommandName='<%# Eval("harf").ToString().ToUpper()%>'><%# Eval("harf").ToString().ToUpper() %></asp:LinkButton>
I think that its should be:
CommandName='<%# Eval("harf").ToString().ToUpper()%'></asp:LinkButton>

Concatenate two or more strings in inline code ASP.NET

I am trying to place a * next to the name based on a condition.
My code :
<asp:Label ID="lblOne" runat="server" Text= '<%# Eval("name") + ((Eval("StatusId").Equals(0) && Eval("assignfilename") == null) ? " *" : "") %>' > </asp:Label>
Thanks
BB
I'm not really familiar with in-line codes and your code seems to be a bit complicated.
But I also need to concatenate an Eval("record") and a text. So to answer the question on how to concatenate, ampersand worked for me.
'<%# Eval("name") & " *" %>'
hope this helps anyone.
If you're pushing the limits of what you can easily handle with inline code, you could always write a function instead. Then you can do something like:
<asp:Label ID="lblOne" runat="server" Text= '<%# EmitSomeText(Eval("name"), Eval("StatusId"), Eval("assignfilename")) %>' />
This lets you break a complex expression up into however many lines it needs to be, which can be a little less awkward. You can use a function in your CodeBehind or any other class.
If you're binding to a class that you have access to, you could add a readonly property. Then you can do something like Eval("MyNewProperty").
I use that for exposing formatting that I need to re-use. For instance, Customer.CustomerFullName might return last name first seperated be a comma (intelligently handling situations where one or the other or both are missing) plus an optional title, since maybe my customers are medical folks and some of them have PhDs and MDs.
For simple one-off scenarios the code-behind function works okay.
You may also want to consider coding them as a property in the underlying object.
For example, if the text generated is going to be used in more than one instance, you'd need to code the function with Evals several times in different forms or controls.
I would create a property on the data object, e.g. NameWithStatusStar, then your label can be bound directly to the property with the code inside Eval("NameWithStatusStar")
This is more descriptive and reusable than a series of expressions, plus it's easier to change (e.g. add another field, change the formula etc.)
You can do it like this:
Text='<%#"CustomText "+Eval("Name")%>'
Text='<%#String.Concat(Eval("UserId"), Eval("Username")) %>'
This worked for me in my project. Found it here:
Concatenate text with Eval
Text='<%# string.Concat(Eval("FirstName"), " ", Eval("LastName"))%>'
This worked for me in my project. Found it here:
Concatenate text with Eval

Better "left / substring" solution for <%# Container.DataItem %>

This little asp.net code has some drawbacks.
If the itemrow is empty, it will fail.
If the item tends to be shorter than 10 chars, you already know.
<asp:LinkButton ID="lbnHistory" CommandName="lbnHistory"
CommandArgument="'<%# Container.DataItem %>'
Text='<%# ((string)Container.DataItem).ToString().Substring(5,10) %>'
runat="server">
</asp:LinkButton>
I'm also available to solve this with the repeatercommandevent i use for this task.
For simplification, I want it filled from a comma separated string.
The task itself is so simple and not worth creating and iterating a strong type.
What do you think?
Whops, I think I was to deep into other thoughs.
You just have to create a public method and wrap it into..
For the sake of clarify..
<%# SampleTruncing((string)Container.DataItem) %>

what is the use of Eval() in asp.net

What is the use of Eval() in ASP.NET?
While binding a databound control, you can evaluate a field of the row in your data source with eval() function.
For example you can add a column to your gridview like that :
<asp:BoundField DataField="YourFieldName" />
And alternatively, this is the way with eval :
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lbl" runat="server" Text='<%# Eval("YourFieldName") %>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
It seems a little bit complex, but it's flexible, because you can set any property of the control with the eval() function :
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server"
NavigateUrl='<%# "ShowDetails.aspx?id="+Eval("Id") %>'
Text='<%# Eval("Text", "{0}") %>'></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
Eval is used to bind to an UI item that is setup to be read-only (eg: a label or a read-only text box), i.e., Eval is used for one way binding - for reading from a database into a UI field.
It is generally used for late-bound data (not known from start) and usually bound to the smallest part of the data-bound control that contains a whole record. The Eval method takes the name of a data field and returns a string containing the value of that field from the current record in the data source. You can supply an optional second parameter to specify a format for the returned string. The string format parameter uses the syntax defined for the Format method of the String class.
IrishChieftain didn't really address the question, so here's my take:
eval() is supposed to be used for data that is not known at run time. Whether that be user input (dangerous) or other sources.

Resources