How can i use foreach in Container.DataItem? - c#

How can i use it in Repeater ItemTemplate ?
foreach(string tag in Eval("etiketler"))
{
Response.Write("<a href='#'>"+tag+"</a");
}

there is no way to do it in this format. you should send Dataitem to a static method and then you should return string that contains your markup..
public static string GetMarkup(object dataItem)
{
var tags = DataBinder.Eval(dataItem, "etiketler"); // depend on etiketler type
StringBuilder sb = new StringBuilder();
foreach(string tag in tags)
{
sb.Append("<a href='#'>"+tag+"</a");
}
return sb.ToString();
}
use this method like this:
<%# GetMarkup(Container.DataItem) %>

<%# is not made to use foreach with it, neither if or other language keywords. It's mainly done to databinding.
But you can :
Do it in codebehind with the _ItemDataBound event of the repeater (hugely recommanded for complex processings/formatting).
See http://msdn.microsoft.com/fr-fr/library/system.web.ui.webcontrols.repeater.itemdatabound%28v=vs.110%29.aspx
Call a method of the page which takes in parameter the DataItem and creates the data you want. See How do you pass a Container.DataItem as a parameter? for example
Hope this helps

You can also use nested repeaters in ASP.NET
<asp:Repeater runat="server" ID="rpt1">
<ItemTemplate>
<asp:Repeater runat="server" ID ="rpt2" DataSource='<%# Eval("etiketler") %>'>
<ItemTemplate>
<%# Eval("tag") %>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>

Related

Can we pass multiple eval field in one command argument in Repeater Control?

can we pass multiple eval field in one command argument.
my code is here
<asp:TemplateField HeaderText="Details" SortExpression="source">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CommandArgument='<%#Eval("source") %>' CommandName="Download" Text='<%#Eval("source") %>'></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
I want to be pass many Eval field in single command argument with command name
if possible please show any reference.
If this is what you are asking as you didnt provide any code snippet i'm assuming like this
CommandArgument='<%#Eval("ScrapId")+","+ Eval("UserId")%>'
In code behind you can use retrieve values like this
protected void GridViews_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Comment")
{
string[] commandArgs = e.CommandArgument.ToString().Split(new char[] { ',' });
string scrapid = commandArgs[0];
string uid = commandArgs[1];
}
}
You can do something like
<%# Eval("Param1").ToString() + Eval("Param2").ToString() %>

Asp.net FindControl anywhere in under specific element [duplicate]

This question already has answers here:
Better way to find control in ASP.NET
(9 answers)
Closed 9 years ago.
Let's say i have this markup structure
<asp:Repeater id="rptItems" datasource="getItemsList()" runat="server" OnItemDataBound="rpAereos_ItemDataBound">
<ItemTemplate>
<asp:Panel id="tableHolder" runat="server">
<asp:table ID="TableHolded" runat="server">
<asp:TableRow>
<asp:TableCell>
<asp:Panel runat="server" ID="panelToFind">Test</asp:Panel>
</asp:TableCell>
</asp:TableRow>
</asp:table>
</asp:Panel>
</ItemTemplate>
</asp:Repeater>
Now on ItemDataBound event I want to find the element panelToFind, but I don't want to go through all the elements to find this element like e.Item.FindControl("tableHolder").FindControl("tableHolded").AReallyLongCallChainUntilMyItem ... , I want to find anything under the tableHolder panel that has the id panelToFind, How would my ItemDataBound event look?
I would like to know if something like: e.Item.FindControl("tableHolder").FindAny("panelToFind")
Declare an extension method like this:
public static class ControlExtensions
{
public static IEnumerable<Control> GetEnumerableChildren(this Control control)
{
return control.Controls.Cast<Control>();
}
public static Control FindAny(this Control control, string id)
{
var result = control.GetEnumerableChildren().FirstOrDefault(c => c.ID == id);
if (result != null)
return result;
return control.GetEnumerableChildren().Select(child => child.FindAny(id)).FirstOrDefault();
}
}
Then do:
var foundControl = e.Item.FindControl("tableHolder").FindAny("panelToFind");
Note will return null if no control exists with that id.

ASP.NET wrap an asp:HyperLink in <li>'s, from server-side

I have the next structure for a menu item:
class MenuItem
{
public string Path, Title;
}
I want to be able to Iterate an object of MenuItem[], creating a new object of asp:HyperLink on each iteration, and to add it to a <ul> list.
One thing that must happen is that each HyperLink will be inside a <li> tag.
How can I do that?
You can use a repeater. In the aspx:
<asp:Repeater ID="repMenuItems" runat="server">
<HeaderTemplate>
<ul>
</HeaderTemplate>
<ItemTemplate>
<li><asp:HyperLink ID="lnkMenuItem" runat="server" Text='<%# Eval("Title") %>' NavigateUrl='<%# Eval("Path")%>'/></li>
</ItemTemplate>
<FooterTemplate>
</ul>
</FooterTemplate>
</asp:Repeater>
And in the codebehind:
repMenuItems.DataSource = arrMenuItem; // your MenuItem array
repMenuItems.DataBind();
Additionaly you should change your class code for using Public Properties instead of Public Members, like this:
public class MenuItem
{
public string Title {get;set;}
public string Path {get;set;}
}
I recommend you to read more about Properties in .NET, a nice feature for object encapsulation http://msdn.microsoft.com/en-us/library/65zdfbdt(v=vs.71).aspx
Hope this helps you

How to create a runat server DIV in the behind code ? ASP.NET & C#

I'm creating multiple DIVs according to database records at my C# behind code. How could I make them runat server ?
Thanks in advance ..
Create and add ASP.NET Panels.
The code
<asp:Panel id="abc" runat="server">
is exactly the same as if you do:
<div id="abc" runat="server">
They render the same, but it's the functionality with other WebControls that the Panel is most used, and the Panel web control gives you more control under code-behind as it exposes more properties.
If you want to access a DIV on serverside, you could also add runat="server". It will be created as HtmlGenericControl.
That's not necessary, just create a HtmlGenericControl and add it to the controls collection:
HtmlGenericControl div = HtmlGenericControl("div")
div.Id = "myid";
this.Controls.Add(div);
Use a custom control that pulls the data and renders it how you would like. Kind of like this:
public class MyDivControl : System.Web.UI.Control
{
private System.Data.DataTable tblMyResults;
protected override void Render(System.Web.UI.HtmlTextWriter writer)
{
// Get your Data (or do it on Page_Load if you'll need it more than once
if (tblMyResults != null && tblMyResults.Rows.Count > 0)
{
int iIndex = 0;
foreach (System.Data.DataRow rItem in tblMyResults.Rows)
{
writer.WriteLine("<div id=\"{0}_{1}\">", this.ClientID, iIndex++);
//Whatever content you want here using your rows.
writer.WriteLine("</div>");
}
}
}
}
Then just drop the control on the page where you want it to render.
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="default.aspx.cs" Inherits="Solution.Web.Presentation.pub._default" MasterPageFile="~/ui/master/main.master" %>
<%# Register TagPrefix="custom" Namespace="MyNameSpace" Assembly="MyProjectAssembly" %>
<asp:Content runat="server" ContentPlaceHolderID="cntMain">
<custom:MyDivControl runat="server" />
</asp:Content>
You can use Repeater Control
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<div id="box<%# Eval("ID")%>" runat="server"></div>
</ItemTemplate>
</asp:Repeater>
and bind data from codebehind

define variable in repeater?

I like to handle and compare a lot of date times in my repeater even I have to work more than one time with the same.
It's a bit ugly, to cast everywhere the Eval("MyDate") like ((DateTime)Eval("MyDate")) to substract 2 datetimes or to compare it, even if you have to do this more than in one operation.
I thought of saving all the evals in a var at start of the repeater?
DateTime mydt1 = Eval("myDate");
DateTime mydt2 = Eval("mydate");
after that, it's easy to do any operations in the whole repeater. Hope you understand my idea. Is this possible? I tried short but everytime errors.
mydt1 - mydt2....
Thank you and best regards.
You could call a method on the code behind page from the repeater using the DateTimes as arguments. The casting logic can be done in the code behind if the goal it to create a cleaner looking aspx page.
Example ASPX:
<asp:Repeater ID="Repeater1" runat="server">
<ItemTemplate>
<asp:Literal
ID="Literal1"
runat="server"
Text='<%# DateFoo(Eval("myDate1"), Eval("myDate2")) %>' />
</ItemTemplate>
</asp:Repeater>
Example C# code behind:
protected string DateFoo(Object o1, Object o2)
{
DateTime? dt1 = o1 as DateTime?;
DateTime? dt2 = o2 as DateTime?;
// Do logic with DateTimes
return "string";
}
If you want to add more logic to your repeater I would suggest you move the binding logic to the code behind:
ASPX:
<asp:Repeater id="myRepeater" runat="server">
<ItemTemplate>
<asp:Literal id="myLiteral" runat="server" />
</ItemTemplate>
</asp:Repater>
CS:
protected override void OnInit(EventArgs e)
{
myRepeater.ItemDataBound += myRepeater_ItemDataBound;
base.OnInit(e);
}
void myRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
// this method will be invoked once for every item that is data bound
// this check makes sure you're not in a header or a footer
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
// this is the single item being data bound, for instance, a user, if
// the data source is a List<User>
User user = (User) e.Item.DataItem;
// e.Item is your item, here you can find the controls in your template
Literal myLiteral = (Literal) e.Item.FindControl("myLiteral");
myLiteral.Text = user.Username + ", " + user.LastLoginDate.ToShortDateString();
// you can add any amount of logic here
// if you need to use it, e.Item.ItemIndex will tell you what index you're at
}
}
I hate evals with a passion.
This is why I use this code to be rid of them forever and go back to strong typing:
public static class DataItemExtensions
{
public static T As<T>(this IDataItemContainer repeater) where T : class
{
return (T)repeater.DataItem;
}
public static dynamic AsDynamic(this IDataItemContainer repeater)
{
return repeater.DataItem;
}
}
Then use it like this:
<asp:Repeater runat="server" DataSource="<%# this.MyObjectCollection %>">
<ItemTemplate>
<%# Container.As<MyObject>().DateTime %>
</ItemTemplate>
</asp:Repeater>
Note that if you use the Datasource like I did, you need to use this.DataBind() on the page.

Categories