Get values from repeater that is filled with objects from a custom class - asp.net

I have stuck on how to get values from a specific row in a repeater.
I fill the repeater with objects from a coustom class like this(C#):
rptVisaBarn.DataSource = client.SkickaForalderBarn();
rptVisaBarn.DataBind();
(ASP.NET)
<asp:Label ID="lblFornamn" runat="server" Text='<%#DataBinder.Eval(Container.DataItem, "NamnBarn").ToString() %>'></asp:Label>
<asp:Label ID="lvlPersonNr" runat="server" Text='<%#DataBinder.Eval(Container.DataItem, "PersonNrBarn").ToString() %>'></asp:Label>
The thing i want to is when i click on the button that creates on every row i want to colect values from that object on that row and send them to a method that i have in a webbserivce.
I have tried some things but they dont work and i dont know where i should go from here..
A little help in the right direction would be really nice!
I you need more info just ask, becuse i really need help with this..

Do you want that click to be client or server side? There's a decent writeup here: http://www.developer.com/net/asp/article.php/3609466/ASPNET-Tip-Responding-to-the-Repeater-Controls-ItemCommand-Event.htm.
The highlights:
Register (somewhere) your repeater item command event. e.g.:
override protected void OnInit(EventArgs e)
{
base.OnInit(e);
rptData.ItemCommand += new RepeaterCommandEventHandler(rptData_ItemCommand);
}
Create a button in your repeater:
<asp:LinkButton ID="btnEdit" Runat="server" CssClass="tabletext" CommandName="edit"
CommandArgument='<%# Eval("pkRecordID") %>'>Edit</asp:LinkButton>
Handle the event:
private void rptData_ItemCommand(object source, RepeaterCommandEventArgs e)
{
//e.Item contains your data item.
//e.CommandName contains 'edit' in the case, or whatever is in your button's CommandName
//e.CommandArgument contains a record ID in this case, or whatever is in your button's CommandArgument
}

Related

Repeater ItemCommand does not work on large data

I have a webform that shows a list of items using a repeater and there is a Edit button associated with each item.
By clicking the Edit button, the page is redirected to the Edit page
Html
<asp:Repeater ID="r epeaterRequest" runat="server">
<ItemTemplate>
<asp:LinkButton ID="btnEdit" CommandArgument='<%# Eval("ItemID") %>' CommandName="Edit" runat="server">Edit</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
Code Befind
protected override void OnLoad(EventArgs e)
{
base.OnLoad(e);
if (Page.IsPostBack == false)
{
List<MyItem> data = new repository().getData();
repeater.DataSource = data;
repeater.DataBind();
}
}
private void repeater_ItemCommand(object source, RepeaterCommandEventArgs e)
{
int itemId;
if (int.TryParse(e.CommandArgument.ToString(), out itemId))
{
if (e.CommandName == "Edit")
{
Response.Redirect("~/Edit.aspx?id=" + itemId, false);
}
}
}
The problem is that when the number of list items gets larger like 2800 items in the List, it halts after clicking the Edit button. The ItemCommand does not get called or takes too long to get to the ItemCommand function.
(Loading and rendering the data is quick. It halts when the Edit button is clicked.
Everything is okay when there are less items like 1000.
I've tried adding this <httpRuntime maxRequestLength="102400" executionTimeout="300" /> to Web.Config but did not work.
Have you tried to add some simple paging to your repeater. That is a lot of data to load into the DOM at once. See this for an idea.
Why don't you change your LinkButton to simple hyperlink?
<asp:Repeater ID="r epeaterRequest" runat="server">
<ItemTemplate>
<a href='<%# Eval("href") %>'>Edit</a>
</ItemTemplate>
</asp:Repeater>
I think it is better solution in your case. Caz' you are doing the same, but using another way.

Using hyperlink with querystring for gridview row

Is there someway to turn the row of a gridview into a hyperlink so that when a user opens it in a new tab for example, it goes to that link? Right now I am using a LinkButton and when the user opens it in a new tab, it doesn't know where to go.
I figured the .aspx code would look something like:
<asp:TemplateField>
<ItemTemplate>
<Hyperlink ID="hyperlink" runat="server" ForeColor="red" HtmlEncode="false" navigationURL="testUrl.aspx"
</ItemTemplate>
</asp:TemplateField>
The only thing is, our URLs are set up in the C# code behind as a query string, so I'm not sure how to pass that into the navigationURL section.
I'm guessing there's something I can do on the page_load with the query string to redirect to the page I need, but this is my first time working with query strings so I'm a little confused.
Thanks!
<asp:TemplateField>
<ItemTemplate>
<asp:HyperLink ID="HyperLink1" runat="server" NavigateUrl='<%#String.Format("~/controller.aspx?routeID1={0}&routeID2={1}", Eval("routeid1"), Eval("routeid2"))%>'></asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
routeid1 and routeid2 are passed as query strings to the controller of that page.
What I did recently is modified my class to have a readonly property that constructs the A tag for me. This way I have control over what gets displayed; just text or a link.
<ItemTemplate>
<asp:Label ID="ColumnItem_Title" runat="server" Text='<%# Bind("DownloadATag") %>'> </asp:Label>
</ItemTemplate>
The code behind just binds an instance of the class to the gridview. You can bind the gridview whenever, on load on postback event, etc.
Dim docs As DocViewList = GetViewList()
GridViewDocuments.DataSource = docs
GridViewDocuments.DataBind()
In the above code, the DocViewList, instantiated as docs, is a list of a class that has all the properties that are needed to fill my GridView, which is named GridViewDocuments here. Once you set the DataSource of your GridView, you can bind any of the source's properties to an item.
Something like:
<asp:LinkButton ID="LinkButton_Title" runat="server" target="_blank"
PostBackUrl='<%# Eval(Request.QueryString["title"]) %>'
or binding them from the RowCreated event:
protected void GridView_OnRowCreated(Object sender, GridViewRowEventArgs e)
{
if(e.Row.RowType == DataControlRowType.DataRow)
{
(e.Row.FindControl("LinkButton_Title") as LinkButton).PostBackUrl = Request.QueryString["title"]))
}
}

How to hide link button based on a result returned by a class ?

I am bit new to C# and got a question.
I have a class as below that simply return false ( this is just to test)
public class SetAuthority
{
public SetAuthority()
{
//
// TODO: Add constructor logic here
//
}
public static Boolean AuthorizedToAddEdit()
{
return false;
}
}
I have a DetailsView with two link buttons to Edit and add New record. I want to hide the link buttons based on the above class method returning value.
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="False" visible='<%# SetAuthority.AuthorizedToAddEdit() %>'
CommandName="Edit" Text="Edit"></asp:LinkButton>
<asp:LinkButton ID="LinkButton2" runat="server" CausesValidation="False" visible='<%# SetAuthority.AuthorizedToAddEdit() %>'
CommandName="New" Text="New"></asp:LinkButton>
</ItemTemplate>
Above works file and Edit and New link buttons are hidden when I run the program.
But the question is, I have a separate link button outside of the DetailsView. It is just a link to navigate to another page. I want to hide this in similar way using the same logic. I have the below code in my webform.
<asp:LinkButton ID="LinkButton5" runat="server" CausesValidation="False" visible='<%# SetAuthority.AuthorizedToAddEdit() %>'
CommandName="OpenAdminPage" Text="Open Admin Page"></asp:LinkButton>
But the link button is always visible and seems it is not calling the class and not getting the value back. It appeared to be the class not return any value and can someone help me to identify what is the different between having this and working in DetailsView and not working for a simple link button.
Note: have a workaround where I can call the same method in Page Load event that works fine without any issue. Code is below
protected void Page_Load(object sender, EventArgs e)
{
Boolean myAllowAdd;
myAllowAdd = SetAuthority.AuthorizedToAddEdit();
if (myAllowAdd == false)
{
LinkButton1.Visible = false;
}
}
The reason is that this is for databinding expressions only: <%# Since the DetailsView is databound it works there.
If you would DataBind the page it worked also for the LinkButton outside of the DetailsView:
protected void Page_Load(object sender, EventArgs e)
{
Page.DataBind();
}
inline asp.net tags... sorting them all out (<%$, <%=, <%, <%#, etc.)
Side-note: be careful with static in ASP.NET. The static method does not yet hurt. But if you'd also use static fields you'd enter a minefield since it would be shared across all requests. Your current code-behind "work-around" is the better approach anyway.

ASP.NET Gridview Templatefield with multiple items

I am creating a web application in ASP.net/VB.NET and I have an issue with the GridView control.
Currently, I have the GridView populated with data from the DB and I've also coded the update button to allow the user to edit any necessary information through a form that pops up.
What I'd like to do, if possible, is add a button to the two right columns(I already put one in the Dock Out Time column) which will be invisible if the column is set or will set the current time to the column. Setting the time for those two columns is already handled through the update form, but my supervisor asked me to try and see if this was possible.
Those two Time columns are TemplateFields(since I format the display time from what is actually in the DB) and I added an asp button in the ItemTemplate for that Set Button in the picture.
Is this even possible to do and if so, how would I access this button in the code behind so I can add functionality(setting the time and hiding it if the column is not null)If it's not really possible to have two items like this in a TemplateField I can just make 2 extra columns for these buttons but I think this would look much cleaner.
Any input would be greatly appreciated. thank you for your time.
Yes this is possible, check this answer:
https://stackoverflow.com/a/11077709/1268570
Basically you need to handle the RowCommand event from the grid and identify each button with a command, optionally you can add arguments to each button when you bind, for example:
<asp:GridView runat="server" OnRowCommand="grdProducts_RowCommand"
ID="grdProducts">
<Columns>
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="false"
CommandName="myLink" CommandArgument='<%# DataBinder.Eval(Container, "RowIndex") %>' Text="Button"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ShowEditButton="True" />
</Columns>
</asp:GridView>
In code behind:
protected void grdProducts_RowCommand(object sender, GridViewCommandEventArgs e)
{
switch (e.CommandName)
{
case "myLink":
this.lblMessage.Text = e.CommandName + " " + e.CommandArgument + " " + DateTime.Now.ToString();
// referenece to the current row
var row = this.grdProducts.Rows[int.Parse(e.CommandArgument.ToString())];
break;
default:
break;
}
}
After you update your grid in the RowCommand event, you should repopulate the grid data to render the changes

How to get selected item in ASP.NET GridView

How can I get the selected item on the SelectedIndexChanging handler when using two SelectCommands? I can get the selected row through e.SelectedRow but I'm unable to get the selected column.
It's correct to have more than one SelectCommand in a GridView? If not, what's the best way?
You don't select a column in a gridview, you select a row. If you want a particular field of a row to be "selectable" you might consider using a HyperLinkField or a ButtonField and handle the events for that. But to my knowledge, admittedly it's limited, there is no way to be able to know, purely with a GridView and its SelectedRow Property which field in the row was "selected" when the row was selected.
You don't have to use select commands. you can use template fields and add a named command to it then you can check which of them was clicked in the RowCommand event (and u can also get the row index as well) see below.
<asp:TemplateField ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" CausesValidation="false"
CommandName="MyCommand" Text="Button" CommandArgument='<%# Container.DataItemIndex %>'></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
RowCommend Event below
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if(e.CommandName.Equals("MyCommand"))
{
int row = Int32.Parse(e.CommandArgument.ToString());
}
}

Resources