Reacting to Button commands inside a Web Usercontrol in a ASP.NET Repeater - asp.net

I have an ASP.NET repeater, whose ItemTemplate is a WebUsercontrol named ProviderControl.
<asp:Repeater ID="rep" runat="server" OnItemDataBound="rep_ItemDataBound">
<ItemTemplate>
<custom:ProviderControl ID="row" runat="server" />
</ItemTemplate>
</asp:Repeater>
I am populating the custom control with data in the ItemDataBound event.
Inside the provider control I have two buttons that I want to be able to react to on the containing Page.
I know there are Commands, and Command arguments, but how would I do that?
Or is there an easier way than using Commands?

You have to handle ItemCommand event of "Repeater".
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
Button btn = e.CommandSource as Button;
Response.Write(btn.ID);
}

The best way would be to provide custom events in your UserControl for each button-click event. The UserControl will raise and the page can handle them.
http://www.codeproject.com/Articles/8797/Mastering-Page-UserControl-Communication#4.3

Related

ASP.NET call a function in code behind with LinkButton

I have this LinkButton here
<asp:LinkButton runat="server" ID="EditBtn" CssClass="LinkButton" Text="Edit" Width="45px" OnClientClick="Profiles_Edit" CommandName="edit" />
and I am trying to call this function in my code behind
protected void Profiles_Edit(Object sender, ListViewCommandEventArgs e)
{
//do something
}
but when I click on the button....nothing happens. My LinkButton is inside an ItemTemplate, which is inside a ListView, which is inside a ContentTemplate, which is inside a UpdatePanel....
What is wrong with the way I am calling it?
Thanks,
J
OnClientClick is for specifying the name of the JavaScript function on the client browser.
To call the server-side event, use OnClick.
Also, you may not need the CommandName attribute in this situation. It isn't clear where this LinkButton resides. If it's in a container like a ListView, you would handle it differently.

Link button in Repeater control redirect to grid view

I am developing a web application where I have a repeater control. A link button is inside the repeater control. When the link button is clicked, I want it to redirect to a page which would be a data entry page for that particular user(which was clicked). It has to use the user-id/emplid and pre-populate some fields in the new page and other fields should be allowed for data-entry.
My question-
How should I redirect to the new data entry page? I haven't decided on the page yet. I am thinking that it would be a form page or grid view and would be a separate page.
Code:
<asp:LinkButton ID="getDetails" OnCommand="getDetails_cmd" runat="server"
CommandArgument='<%#DataBinder.Eval(Container.DataItem,"Emplid")%>
' Text='<%#DataBinder.Eval(Container.DataItem,"NAME")%>'
CommandName="Details"></asp:LinkButton>
After redirecting to the page, I guess, using the commandargument, I can get the emplid. an I pass multiple values? Say the keys for the page?
How should I update multiple tables in the page?
Any help would be really appreciated.
Thanks,
You need handle ItemCommand event of Repeater control.
<asp:Repeater ID="Repeater1" runat="server"
onitemcommand="Repeater1_ItemCommand">
<ItemTemplate>
<asp:LinkButton
ID="getDetails"
runat="server"
Text='<%# Eval("NAME") %>'
CommandName="cmd"
CommandArgument='<%# Eval("Empid") %>'
>
</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
Handler of ItemCommand event,
protected void Repeater1_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "cmd")
{
Session["empid"]=e.CommandArgument;
Response.Redirect("~/page1.aspx");
}
}
If you're trying to direct to a new page, linkbutton is probably not the way to go since it does a postback to the same form normally, a standard hyperlink sending emplid in the querystring would work. In the new page get the emplid from the querystring using Request.Querystring("emplid"). As for saving to multiple tables, there are a number of ways to do that, one would be to wrap the multiple db update calls in a transactionscope.

Dynamically adding a Button to a PlaceHolder in a DataGrid

I have basically something like this:
<asp:datagrid id="DGrid" runat="server" AutoGenerateColumns="false">
<asp:TemplateColumn HeaderText="Stuff">
<ItemTemplate>
<asp:PlaceHolder id="PH" runat="server" />
</ItemTemplate>
</asp:TemplateColumn>
</asp:datagrid>
I need to add a Button to the PlaceHolder depending on the values of the data I am binding. At the moment I am adding the Button after the data is bound in Page_Load. The problem is that the data binding methods are not called in postbacks, so the Button disappears when I click on it.
Any suggestions on how to do this? Problem is that I need to know some attributes of the grid item to create the Button, so I cannot create it before the data has been bound.
How about subscribing to ItemCreated event?
Markup:
<asp:datagrid id="DGrid" runat="server" OnItemCreated="DGrid_ItemCreated" AutoGenerateColumns="false">...</asp:DataGrid>
Code-behind:
protected void DGrid_ItemCreated(object sender, DataGridItemEventArgs e)
{
var ph e.Item.FindControl("PH") as PlaceHolder;
// ...
}
UPDATE
Regarding the situation when the e.Item.DataItem is null on a postback: only the reliable information (e.g. databound control properties) is persisted across postbacks (if ViewState is enabled), the entire data items don't survive them. Therefore you have to manage the state by yourself. You can persist only the necessary data in a ViewState (and not the entire data items since it can blow it up).

ASP.NET: "Object Required" when repeating LinkButtons in an UpdatePanel

I have an UpdatePanel which has a Repeater repeating LinkButtons. When I click a LinkButton, the page does a partial postback, then I get a javascript error: "Object required". I tried debugging the javascript, but couldn't get a call stack. If I remove the UpdatePanel, the LinkButtons do a full postback, and they disappear from the page. How can I get this UpdatePanel to work?
<ajax:UpdatePanel ID="wrapperUpdatePanel" runat="server" UpdateMode="Always">
<ContentTemplate>
<asp:Repeater ID="endpointRepeater" runat="server" OnItemDataBound="EndpointDataBound">
<HeaderTemplate>
<div class="sideTabs">
<ul>
</HeaderTemplate>
<ItemTemplate>
<li>
<asp:LinkButton ID="endpointLink" runat="server" OnClick="EndpointSelected" />
</li>
</ItemTemplate>
<FooterTemplate>
</ul>
</div>
</FooterTemplate>
</asp:Repeater>
</ContentTemplate>
</ajax:UpdatePanel>
binding code:
protected void Page_Load(object sender, EventArgs e)
{
if (!this.IsPostBack)
{
this.SelectedEndpoint = Factory.Get<IEndpoint>(Enums.EndPoints.Marketing);
}
IEndpointCollection col = EndpointCollection.GetActivelySubscribingEndpointsForPart(this.Item);
if (this.Item.IsGdsnItem)
col.Add(Factory.Get<IEndpoint>(Enums.EndPoints.Gdsn));
if (col.Count > 0)
col.Insert(0, Factory.Get<IEndpoint>(Enums.EndPoints.Marketing));
this.endpointRepeater.DataSource = col;
this.endpointRepeater.DataBind();
if (this.endpointRepeater.Items.Count > 0)
{
LinkButton lb = this.endpointRepeater.Items[0].FindControl("endpointLink") as LinkButton;
this.EndpointSelected(lb, new EventArgs());
}
}
thanks,
mark
This may not be your main issue, but when including an object inside a Repeater that needs an event, you shouldn't be using that control's native events. Instead you should use the Repeater's OnCommand event.
If I were to guess, your problem is caused by the repeater not maintaining its DataBound state across PostBacks. The Linkbutton disappears from view because it is not bound to the page on every PostBack, so when the response is sent back to the client, it has nothing bound to it.
It sounds like the UpdatePanel is expecting the same (or similar) markup to be returned from the AJAX response as what is on the page already, so returning nothing for the repeater causes problems.
Try binding your repeater to the page/control in its OnInit() method. This should allow the ViewState for the repeater to be loaded on every PostBack.

Switching a Repeater's ItemTemplate at runtime

Is it possible to define multiple templates for a Repeater's ItemTemplate and switch between them according to some condition?
I use a repeater to view a list of posts but want to have a different view for rows that belong to the current user (e.g. contains a LinkButton for deleting the post)
If this is not possible, then is it possible to use a Multiview control inside a Repeater's ItemTemplate?
I tried to use a MultiView control inside the ItemTemplate and it worked very well, hope this helps someone with the same problem:
<asp:Repeater ID="Repeater1" runat="server" OnItemCommand="Repeater1_ItemCommand">
<ItemTemplate>
<asp:MultiView ID="MultiView1" runat="server" ActiveViewIndex="<%# ((Post)Container.DataItem).Member.ID == CurrentMemberID ? 1 : 0 %>">
<asp:View ID="View1" runat="server"><!-- some links --></asp:View>
<asp:View ID="View2" runat="server"><asp:LinkButton CommandName="DeletePost" CommandArgument="<%# ((Post)Container.DataItem).Id %>" ID="LinkButton1" runat="server">Delete Post</asp:LinkButton></asp:View>
</asp:MultiView>
</ItemTemplate>
</asp:Repeater>
I don't know if it's possible to switch between templates, but I've found the the Repeater.OnItemDataBound event most useful for modifying the display of individual repeater items.
For example, to show a link button based on the current user...
protected void repeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
LinkButton = e.Item.FindControl("btnDelete");
LinkButton.Visible = (e.Item.DataItem as DataRow)["CreatedBy"] == getCurrentUser();
}
Generally I keep the layout of the data consistent for each repeater item and modify the visual appearance by altering the CssStyle and Visible properties of controls in the template. If there are more radical layout changes, I'll put each layout option inside a placeholder and use logic to determine which placeholder to show.

Resources