i have in my aspx page
<%
for(int i=0;i<10;i++)
{
LinkButton1.CommandArgument=i.ToString();
%>
<asp:LinkButton ID="LinkButton1" runat="server" OnCommand="LinkButton1_Click"></asp:LinkButton>
<%
}
%>
how can i pass a value in my aspx.cs page like:
protected void LinkButtonStergeArticol_Click(object sender,CommandEventArgs e)
{
String id = e.CommandArgument.ToString();
}
?
i know it's not correct because i have more LinkButtons with the same ID, but is there any solution for my problem in this scenario? Or can you suggest me another approach?
i need to have a linkbutton for every item i have in an array. then i need to pass the item's index so that i can delete it in my aspx.cs page.
Can't you use a Repeater or ListView to generate that list of controls? Those are designed to generate a list of controls.
Have you tried something like following?
<%
for(int i=0;i<10;i++)
{
//LinkButton1.CommandArgument=i.ToString();
%>
<asp:LinkButton ID="LinkButton1"
runat="server"
OnCommand="LinkButton1_Click"
CommandName="SomeCommand"
CommandArgument="<%= i%>"></asp:LinkButton>
<%
}
%>
Related
Inside a for loop, how to pass the variable to the code-behind from an asp tag and access the variable value
CommandArgument works but shows <# gigs[x].Id%> - not the value.
Aspx
<%for (int x = 0; x < gigs.Count; x++){%>
<asp:LinkButton ID="LinkButton2" CssClass="btn btn-danger mt-3" runat="server"
UseSubmitBehavior="false" CommandArgument="<# gigs[x].Id%>"
OnClick="LinkButton2_Click">Hide Gig <i class="fa fa-eye-slash ml-1"></i>
</asp:LinkButton>
Code behind
protected void LinkButton2_Click(object sender, EventArgs e)
{
LinkButton lnk = sender as LinkButton;
String Value1 = lnk.CommandArgument;
Response.Write(Value1);
}
Result
<# gigs[x].Id%>
Expected Result
1
Try using <%# gigs[x].Id %> instead and call Page.DataBind() on the Page_Load event.
<%= %> is a shortened response.Write() and is never valid as an attribute, for any server tag.
<%# %> can be used, only if the container is databound (the page in your case).
You're much better off using a Strongly Typed Repeater. You can set the ItemType as your class gigs and have full access to all it's properties. Then you can easily use them in the LinkButton.
Repeater1.DataSource = gigs;
Repeater1.DataBind();
And then in the aspx
<asp:Repeater ID="Repeater1" runat="server" ItemType="MyNameSpace.MyClass.Gig">
<ItemTemplate>
<asp:LinkButton ID="LinkButton2" CommandArgument='<%# Item.Id %>' OnClick="LinkButton2_Click" runat="server">Hide Gig</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
I have a master page named MasterPage_MyMasterPage on whic i have created a static method as
public static string GetRoleName()
{
string sRoleName="admin";
if (HttpContext.Current.Session["UserName"] != null)
{
sRoleName = HttpContext.Current.Session["UserName"].ToString();
}
return sRoleName;
}
and on aspx page i called it as
<a >Brayan <asp:Label runat="server" Text='<%= MasterPage_MyMasterPage.GetRoleName() %>' ></asp:Label>
but it doesn't worked, it print as ...
Brayan <span><%= MasterPage_MyMasterPage.GetRoleName() ;></span>
Session["UserName"] is bind when login successfull.Please help me.
hey please try this works for me
<a >Brayan <asp:Label runat="server" Text='' ><%= MasterPage_MyMasterPage.GetRoleName()%> </asp:Label>
Inline expressions using the <%= ... %> syntax can be used to render to the page.
But they can't be used to set a server-control property, which is what you're attempting to do (Label.Text property).
Consider using data-binding syntax instead:
... Text = "<%# MasterPage_MyMasterPage.GetRoleName() %>"
Could it be the same as this one?
How do I set an ASP.NET Label text from code behind on page load?
Try this
<%= ((MasterPage_MyMasterPage)Page.Master).GetRoleName() %>
Update:
Make a protected method in your cs file something like this
protected string getRoleName()
{
return ((MasterPage_MyMasterPage)Page.Master).GetRoleName();
}
and in aspx file
<%= getRoleName() %>
I'm using an asp repeater to display a list of names and I want to display the current letter as a type of grouping header, like in an index page.
The data is sorted alphabetically before binding, but i'm finding it difficult to insert the 'A' and 'B' before the names are displayed.
Add a Panel control to your ItemTemplate with visibility set to False. When you are binding the repeater (assuming you are subscribing to the ItemDataBound event), run a check to see if the first letter has changed. If it has, set the panel's visibility to true and print out the letter.
Let me know if you need some example code.
EDIT: EXAMPLE CODE
For clarity sake, "AlphaHeaders" is what we will call the "A", "B", "C" letters that we want to display
aspx code
The Repeater will look like so:
<table>
<asp:Repeater id="rptRepeater" runat="server" OnItemDataBound="rptNames_OnItemDataBound">
<ItemTemplate>
<asp:Panel id="pnlAlphaHeader" runat="server" visible="False">
<tr><td><asp:Label id="lblAlphaHeader" runat="server" /></td></tr>
</asp:Panel>
<tr><td><asp:Label id="lblName" runat="server" /></td></tr>
</ItemTemplate>
</asp:Repeater>
</table>
aspx.cs code
First, you need a variable that holds the current AlphaHeader:
private string _AlphaHeaderCurrent = String.Empty;
Then you will do your work on the repeater's OnItemDataBound event:
protected void rptNames_OnItemDataBound(object sender, System.Web.UI.WebControls.RepeaterItemEventArgs e)
{
if ((e.ItemType==ListItemType.Item) || (e.ItemType==ListItemType.AlternatingItem)) {
string name = e.Item.DataItem("Name").ToString();
//check if the first letter of the current name is new. If it is new, we print out the header
if(!name.StartsWith(this._AlphaHeaderCurrent)) {
this._AlphaHeaderCurrent = name.SubString(1);
((Panel)e.ItemFindControl("pnlAlphaHeader")).Visible = true;
((Label)e.Item.FindControl("lblAlphaHeader")).Text = the._AlphaHeader;
}
((Label)e.Item.FindControl("lblName")).Text = name;
}
}
You sort before you bind.
That is, bind the sorted result set.
Without seeing the values you have, however, it is not possible to tell exactly how to do so.
Update - from your comment, I would say you need to change your binding source to something like Dictionary<string,IList<string>>.
With such a structure, you could bind by key (sorted) and sublist (secondary sort).
You need to sort your data before bind it to the repeater.
You can use nested repeaters (repeater inside repeater). Like category and subcategory.
In first repeater you can list all your names and make a condition starts with A. Then in sub repeater you can show all names. You will also use itemdatabound event to bind second repeater.
<asp:Repeater id="rptFirstLetters" runat="server" OnItemDataBound="rptChars_OnItemDataBound">
<ItemTemplate>
<div>"<%#Eval("letters") %>"
<asp:Repeater id="rptNames" runat="server">
<ItemTemplate>
<%#Eval("names") %>
</ItemTemplate>
</asp:Repeater>
</div> // bind all letters
</ItemTemplate>
Not really a nice way of doing this to be honest, repeaters generally result in ugly code I've found. The hierarchical approach from kad1r is probably the nicest if you can set it up, but there are alternatives, depending on your implementation details; I kind of prefer this in some ways as it keeps the markup very clean, and as I have a non-programmer design guy that is a plus for me.
ASPX:
<%# Page language="C#" Src="test.CODE.cs" Inherits="test_Page" %>
<asp:Repeater ID="TestRepeater" runat="server">
<ItemTemplate>
<asp:PlaceHolder Visible='<%# Eval("IsFirstInGroup") %>' runat="server">
<strong><%# Eval("Initial") %></strong><br/>
</asp:PlaceHolder>
<%# Eval("Name") %><br/>
</ItemTemplate>
</asp:Repeater>
CODE BEHIND:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
public class test_Page : Page
{
protected Repeater TestRepeater;
protected override void OnInit(EventArgs e)
{
base.OnInit(e);
String[] names = new String[]
{
"Alpha, John",
"Altman, Mary",
"Asher, Cyril",
"Bachman, Turner",
"Beta, Rob",
"Bexman, Norah",
"Clark, Freddy"
};
List<_DispItem> l = new List<_DispItem>();
for (int i = 0; i < names.Length; i++)
l.Add(new _DispItem() { Name = names[i], IsFirstInGroup = (i == 0 || names[i - 1][0] != names[i][0]) });
TestRepeater.DataSource = l;
TestRepeater.DataBind();
}
private class _DispItem
{
public String Name { get; set; }
public String Initial { get { return Name.Substring(0, 1); } }
public bool IsFirstInGroup { get; set; }
}
}
I created LinkButton that located inside of Repeater Control.
CategoryID is a variable in LinkButton Control that have to get value after Repeater Control was bound to data. But CategoryID always get zero.
I have the following ASP and C# code:
<asp:Repeater ID="rpt1" runat="server"
OnItemDataBound="rpt1_ItemDataBound"
OnItemCommand="rpt1_ItemCommand">
<ItemTemplate>
<div>
<%# Eval("Name") %>-<%# Eval("CollectionType")%>
<asp:LinkButton ID="LinkButton1" runat="server" Text="[edit item]"
PostBackUrl='AddItem.aspx?CategoryID=<%# Eval("CollectionID")%>' />
</div>
</ItemTemplate>
</asp:Repeater>
Code behind:
public void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
List<GlassesCollection> gc = BL.GetDataBL.GetCollection();
rpt1.DataSource = gc;
rpt1.DataBind();
}
}
Any idea why CategoryID variable doesn't get any value and how can I fix the problem?
A server control parameter cannot contain a mixture of literal text and evaluated expressions.
The code you have will literally be posting back to AddItem.aspx?CategoryID=<%# Eval("CollectionID")%> and it will not be evaluating the code within the angle brackets.
You need to change your parameter like so
PostBackUrl='<%# "AddItem.aspx?CategoryID=" + Eval("CollectionID")%>' />
I have a user control which is used to display search results. The HTML for each result displayed will vary based on the type of result being displayed: "contacts" are displayed in one way, "news articles" are displayed in another, etc. There are around 10 different types of results that are all marked up differently when they get to HTML — so I need around 10 or so different templates for individual results that I can choose between based on the current item being displayed.
I'm using an asp:Repeater to display the results, but I don't know how to select the appropriate template within the asp:Repeater <ItemTemplate>. Ideally I'd like the ASP to select the appropriate template to use based upon the object type being passed in via the searchResultsRepeater.DataSource — but unfortunately I can't use switch on type (see this blog entry for C# switch on type). I can however just pass through an enum value for the type of result being displayed.
In the backend C# code I have an abstract inline SearchResult class, and children of that class like ContactSearchResult, NewsArticleSearchResult, etc. The searchResultsRepeater.DataSource would then be bound to a List<SearchResult>. Each SearchResult contains a ResultListingType type field which gives the type of the listing to be displayed.
Attempt 1: using control flow inside the ASP itself
My first attempt was something like this:
<asp:Repeater ID="searchResultsRepeater" runat="server">
<ItemTemplate>
<div class="item">
<% switch (DataBinder.Eval(Container.DataItem, "type")) { %>
<% case ResultListingType.CONTACT: %>
<p><%# DataBinder.Eval(Container.DataItem, "firstName") %></p>
<p><%# DataBinder.Eval(Container.DataItem, "lastName") %></p>
<% break; %>
<% case ResultListingType.NEWS: %>
<p><%# DataBinder.Eval(Container.DataItem, "newsHeadline") %></p>
<p><%# DataBinder.Eval(Container.DataItem, "newsDate") %></p>
<% break; %>
<% Case AnotherTypeOfListing1: %>
<% Case AnotherTypeOfListing2: %>
<% Case AnotherTypeOfListing3: %>
<% Case AnotherTypeOfListing4: %>
<% Case AnotherTypeOfListing5: %>
<% etc... %>
<% } %>
</div>
</ItemTemplate>
</asp:Repeater>
Unfortunately, this doesn't work:
"switch" and "if" both give "invalid expression term" inside the <%# ... %> brackets.
"Container.DataItem" gives "the name "Container" does not exist in the current context" inside <% ... %> brackets.
Attempt 2: setting asp:PlaceHolder's to Visible = False
I found something that looked useful at how to change the ItemTemplate used in an asp:repeater?. I then tried something like:
<asp:Repeater ID="searchResultsRepeater" runat="server">
<ItemTemplate>
<div class="item">
<asp:PlaceHolder ID="newsResultListing" runat="server">
<p><%# DataBinder.Eval(Container.DataItem, "newsHeadline") %></p>
<p><%# DataBinder.Eval(Container.DataItem, "newsDate") %></p>
</asp:PlaceHolder>
<asp:PlaceHolder ID="contactResultListing" runat="server">
<p><%# DataBinder.Eval(Container.DataItem, "firstName") %></p>
<p><%# DataBinder.Eval(Container.DataItem, "lastName") %></p>
</asp:PlaceHolder>
</div>
</ItemTemplate>
</asp:Repeater>
In my ItemDataBound event I did:
Control newsResultListing = e.Item.FindControl("newsResultListing");
newsResultListing.Visible = false;
Control contactResultListing = e.Item.FindControl("contactResultListing");
contactResultListing.Visible = false;
switch (item.type)
{
case ResultListingType.CONTACT:
contactResultListing.Visible = true;
break;
case ResultListingType.NEWS:
newsResultListing.Visible = true;
break;
default:
throw new Exception("Unknown result listing type");
}
Unfortunately this doesn't work because ASP seems to still be running the contents of the PlaceHolder even after I set Visible = false. I get the error "DataBinding: 'usercontrols_ResultsListing+ContactResultsListing' does not contain a property with the name 'newsHeadline'" — i.e. the newsResultListing PlaceHolder is still looking for the "newsHeadline" field, even though that field doesn't exist for the result listing type being displayed.
In fact I've tried a quick test throw new Exception("e"); in my ItemDataBound, and it looks like the "DataBinding" error is thrown even before control flow gets to the ItemDataBound method, so there's really nothing I can do in there to avoid this error.
I suppose I could add every single field to the parent class and leave most of them null in my children, but that seems really ugly.
Is there a way to make this work, or an easier way to vary my ItemTemplate based upon the type of Container.DataItem I'm currently iterating over? I'm very new to ASP so there's likely something simple that I've missed. :)
OK, I think I've found a solution — I've created multiple additional user controls, one for each type of search result. Each one of these controls defines the HTML template for its corresponding type of search result.
My asp:Repeater contains absolutely nothing inside its ItemTemplate:
<asp:Repeater ID="searchResultsRepeater" runat="server">
<ItemTemplate>
<%-- empty template: we insert usercontrols in the ItemDataBound --%>
</ItemTemplate>
</asp:Repeater>
I bind a List<SearchResultData> to my asp:Repeater as before, and as before this list contains more specific subtypes of SearchResultData based on the type of result to be shown.
In my ItemDataBound handler I instantiate one of those user controls based on the type of data in e.Item.DataItem and then insert that user control into the repeater:
var aspxItem = e.Item;
var dataItem = (SearchResultData) e.Item.DataItem;
if (dataItem is ContactSearchResult.ContactSearchResultData)
{
var contactSearchResultUC = LoadControl("~/UserControls/ResultsListingSearchResult/ContactSearchResult.ascx") as ASP.ContactSearchResult;
contactSearchResultUC.data = (ContactSearchResult.ContactSearchResultData)dataItem;
aspxItem.Controls.Add(contactSearchResultUC);
}
else if (dataItem is NewsArticleSearchResult.NewsArticleSearchResultData)
{
var newsArticleSearchResultUC = LoadControl("~/UserControls/ResultsListingSearchResult/NewsArticleSearchResult.ascx") as ASP.NewsArticleSearchResult;
newsArticleSearchResultUC.data = (NewsArticleSearchResult.NewsArticleSearchResultData)dataItem;
aspxItem.Controls.Add(newsArticleSearchResultUC);
}
...etc
To add to George's solution, the <ItemTemplate> can be a mix of markup and dynamic controls. The following example renders a table of name/value pairs.
<table cellspacing="0" cellpadding="5" border="0" width="100%">
<tbody>
<asp:Repeater ID="TheRepeater" OnItemDataBound="TheRepeater_ItemDataBound" runat="server">
<ItemTemplate>
<tr>
<td class="LabelText"><%# ((NameValuePair)Container.DataItem).Name%>:</td>
<td class="ValueText">
<asp:PlaceHolder ID="ValuePlaceHolder" runat="server" />
</td>
</tr>
</ItemTemplate>
</asp:Repeater>
</tbody>
</table>
Code-behind
protected void TheRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (ListItemType.Item == e.Item.ItemType || ListItemType.AlternatingItem == e.Item.ItemType)
{
NameValuePair nvp = (NameValuePair)e.Item.DataItem;
PlaceHolder container = (PlaceHolder)e.Item.FindControl("ValuePlaceHolder");
if (typeof(nvp.Value) is String)
{
Literal textControl = new Literal() { Mode = LiteralMode.Encode, Text = (string)nvp.Value, EnableViewState = false };
container.Controls.Add(textControl);
}
...
You will need to override the ItemDataBound event handler and control it there.
Alternatively, put the logic into a user control and put the user control into the template instead.
The user control will still need to implement the appropraite switching, but makes it easier to reuse the logic.