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.
Related
with asp.net c# I get the code of a country with bind :
<asp:Label runat="server" Text='<%# Bind("h_country") %>' ID="Label1"></asp:Label>
this return code of country like usa, tr, eg, il.
I need to put if conditions and I try to do it like this:
<asp:Label runat="server" Text='<%# if(Bind("h_country")=="usa") resonse.write("United States"); %>' ID="Label1"></asp:Label>
note: I'm using GridView and template.
I tried alo at code behind to get the value of country like this:
String s = Lable1.Text;
but also not workes!
how can I get it as a variable and use if condition ?
You need to use find control if thus label is within the gridview and then get the sting from label.
You probably want to handle this in the code behind
<asp:Label runat="server" Text='<%# GetCountry(Eval("h_country")) %>' ID="Label1"></asp:Label>
code behind
public string GetCountry(object country)
{
if (county.ToString() == "usa")
return "United States";
}
It would be better if you had a lookup so you don't have to have a lot of if statements
This is how you can do conditional checks in the markup while binding. Try something like below but I would not advise doing this kind of conditional checks and response.write at the template level but do it in code behind.
<asp:Label runat="server" Text='<%# Bind("h_country") == "usa" ? "United States" : (string)Bind("h_country") %>' ID="Label1"></asp:Label>
And this is how you can do it at code behind. Use the databound event to find the Label1 and set the appropriate text in there.
You need to define OnRowDataBound="gvTest_DataBound for the gridview in the markup
protected void gvTest_DataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
Label lblCountry = (Label)e.Row.FindControl("Label1");
if (lblCountry.text == "usa"){
// do something here
}
else {
// do something otherwise
}
}
}
English is not my native language; please excuse typing errors.
I am creating a survey type application, and I'm not sure how I should approach so I've been doing some trials and errors.
I have a Question class
public class Question
{
public int QuestionID;
public string QuestionText;
public int InputTypeID;
public List<WebControl> Controls;
public Question()
{
//initialize fields;
}
internal Question(int id, string text, int inputTypeId)
{
//assign parameters to fields
switch(inputTypeId)
{
case 1:
//checkbox
break;
case 2:
//textbox
TextBox t = new TextBox();
Controls = new List<WebControl>();
Controls.Add(t);
break;
...
}
}
}
My Question.aspx looks like this:
<asp:Repeater ID="repeater" runat="server">
<ItemTemplate>
//Want to display a control dynamically here
</ItemTemplate>
</asp:Repeater>
I tried this but it obviously didn't work...
<asp:Repeater ID="repeater" runat="server">
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "Controls") %>
</ItemTemplate>
</asp:Repeater>
and I just get this.
System.Collections.Generic.List`1[System.Web.UI.WebControls.WebControl] System.Collections.Generic.List`1
One question could have
one textbox
radiobutton list
checkbox list
In this case, should my Question class have List<WebControl> or just WebControl?
Also, how can I render the webcontrol inside the repeater?
You should do this in CodeBehind, using the Repeater ItemDataBound() event. Your question class should have a List<Control> which is the base class for WebControl and other controls, allowing the flexibility for different kinds of controls.
Doesn't have to use Page_Load but just for example,
void Page_Load(Object Sender, EventArgs e)
{
Repeater1.ItemDataBound += repeater1_ItemDataBound;
Repeater1.DataSource = [your List<Control> containing controls to add];
Repeater1.DataBind();
}
void Repeater1_ItemDataBound(Object Sender, RepeaterItemEventArgs e)
{
// Execute the following logic for Items and Alternating Items.
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var controlToAdd = (Control)e.Item.DataItem;
((PlaceHolder)e.Item.FindControl("PlaceHolder1")).Controls.Add(controlToAdd);
}
}
And the ItemTemplate:
<ItemTemplate>
<asp:PlaceHolder id="PlaceHolder1" Runat="server" />
</ItemTemplate>
What i'm trying to do is this
<asp:Repeater ID="ParentRepeater" runat="server" OnItemDataBound="ItemBound">
<ItemTemplate>
<asp:Repeater ID="Repeater_SideMenu_Guides_Medlem" runat="server">
<ItemTemplate>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
Codebehind
ParentRepeater.DataSource = CraftGuides.GetAllGroups();
ParentRepeater.DataBind();
protected void ItemBound(object sender, RepeaterItemEventArgs args)
{
if (args.Item.ItemType == ListItemType.Item)
{
Repeater childRepeater = (Repeater)args.Item.FindControl("ChildRepeater");
childRepeater.DataSource = CraftGuides.GetGuidesByGroupID( Insert ID from Parent Here );
childRepeater.DataBind();
}
}
Now, the thing is I don't know to get the ID from the parent inside the child to collect the data from the database
Providing that you have a Group object, you can use the following:
var item = args.Item;
var dataItem = item.DataItem as Group;
Then you easily grab the id of the group object and pass it into your GetGuidsByGroupID().
I like to use the as keyword since it will return null if the cast fails. Using (Group)item.DataItem would throw an exception if it failed.
Hi anybody know how to use databinder.eval in c#
Actually I've tried this
LinkButton lnkName = new LinkButton();
lnkName.CommandArgument = DataBinder.Eval("object","<%#COURSE_ID%>");
it is showing error. Whats the wrong with this?
You can't use Eval in the code behind of an aspx page.
this:
lnkName.CommandArgument = DataBinder.Eval("object","<%#COURSE_ID%>");
should be this:
lnkName.CommandArgument = YOUR_OBJECT_PROPERTY_HERE;
To fill in YOUR_OBJECT_PROPERTY_HERE you either need to specify the object.property etc like normal in C# code, or you'll have to use reflection to get the property value from the object (which is what eval does for you).
Here is a link showing how to use reflection to get the property information from an object. You can use it to duplicate how eval works if you need to: https://web.archive.org/web/1/http://articles.techrepublic%2ecom%2ecom/5100-10878_11-6099345.html
Link to DataBinder Eval Method: http://msdn.microsoft.com/en-us/library/4hx47hfe.aspx
How the DataBinder Eval Method works (and why the author thinks it should be avoided) http://weblogs.asp.net/jgalloway/archive/2005/09/20/425687.aspx
For Example in design page you can use like:
<asp:Button ID="btnEdit" CommandName="Edit"
CommandArgument='<%# DataBinder.Eval(Container, "RowIndex") %>'
CssClass="cursor_hand" runat="server" Text="Edit" />
Code Behind:
int rowIndex = int.Parse(e.CommandArgument.ToString());
if (e.CommandName.Equals("Edit"))
{
//do something
}
protected void GridView1_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowIndex > -1)
{
string h = DataBinder.Eval(e.Row.DataItem, "ColumnName").ToString();
}
}
You should use Eval expression and <% %> in *.aspx code not with C# code.
I have an ASP:Repeater Which I would like to display a list of check boxes in. These check boxes are related to a list of user preferences and the users resulting answer. See Code Bellow.
I would like to add do one of the following if possible
Option 1: It would be great if I could use the Event in the Repeater:OnItemCommand(...) to fire if any of the items change. It would seem to me that this event will only fire if there is a Button | LinkButton | ImageButton item in the list. IE it will not fire if I put in a check box with AutopostBack="True"
Option 2: Is there a way I could attach a method to an Event of CheckBox:CheckChanged I would need to pass this method a parameter saying which question/answer combo to change.
Option 3: Its your answer if you know an easier way that would be awesome.
The Code:
<asp:Repeater ID="RPTprefs" runat="server" DataSourceID="getAnswers" OnItemCommand="RPTprefs_ItemCommand">
<ItemTemplate>
<li><asp:CheckBox ID='questionID' runat="server"
Checked='<%# Eval("pr.up_is_selected") %>'
Text='<%# Eval("prp.prefs_question") %>'
AutoPostBack="true"
OnCheckedChanged="CheckChanged" /></li>
</ItemTemplate>
</asp:Repeater>
Thanks in advance
Here is what I came up with, which is basically your option #2.
In the ItemTemplate of the repeater, I use a Literal control (Visible set to false) which has the argument you wish to pass to the CheckedChanged function. The reason for using a control is because the control will retain its value in the ViewState after a post back, whereas the original data source for the Repeater will be lost.
In the OnItemCreated function, I bind the CheckChanged function for all of the check boxes to pass in the right argument. Here's my complete example. In this case, I want to pass the Id property of my data to the CheckChanged function.
Markup:
<asp:Repeater ID="Repeater1" runat="server" OnItemCreated="ItemCreated">
<ItemTemplate>
<asp:Literal ID="litArg" runat="server" Visible="false" Text='<%# Eval("Id") %>'>
</asp:Literal><%# Eval("Name") %>
<asp:CheckBox ID="chkCool" runat="server" AutoPostBack="true" Checked='<%# Eval("IsCool") %>' /><br />
</ItemTemplate>
</asp:Repeater>
Code behind:
public class SomeClass
{
public SomeClass(bool c, string n, int id)
{
IsCool = c;
Name = n;
Id = id;
}
public bool IsCool { get; set; }
public string Name { get; set; }
public int Id { get; set; }
}
.
.
.
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
List<SomeClass> people = new List<SomeClass>();
people.Add(new SomeClass(true, "Will", 666));
people.Add(new SomeClass(true, "Dan", 2));
people.Add(new SomeClass(true, "Lea", 4));
people.Add(new SomeClass(false, "Someone", 123));
Repeater1.DataSource = people;
Repeater1.DataBind();
}
}
private void CheckChanged(int id)
{
Response.Write("CheckChanged called for item #" + id.ToString());
}
protected void ItemCreated(object sender, RepeaterItemEventArgs e)
{
//this needs to be set again on post back
CheckBox chk = (CheckBox)e.Item.FindControl("chkCool");
Literal arg = (Literal)e.Item.FindControl("litArg");
Action<object, EventArgs> handler = (s, args) => CheckChanged(Convert.ToInt32(arg.Text));
chk.CheckedChanged += new EventHandler(handler);
}
Hope that helps.