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
Related
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
}
I have regular asp.net gridview,and i want to enable editmode in each row,and also without editbutton (like excel grid).
Edited data i want to save to my database by clicking "Post" button outside the grid(one button for whole grid).
How can i reach it?
To achieve this, you are going to have to use ItemTemplates for each column with textboxes in them as the control..
ASP
<asp:TemplateField HeaderText="Heading Title" SortExpression="Heading Title">
<ItemTemplate>
<asp:TextBox ID="tbTextbox" runat="server" Width="65px" Text='<%# Bind("ColumnNameYouWantToView") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
After this is set up properly, you will want the post button. You can either put it in the grid or outside the grid. I use both, but here is the one inside the grid as a footer.
ASP
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnView" runat="server" Text="View" OnClick="btnView_Click" Width="40px" />
</ItemTemplate>
<FooterTemplate>
<asp:Button ValidationGroup="UPDATE" ID="btnUpdate" OnClick="btnUpdate_Click" runat="server" Text="Update" Width="50px"></asp:Button>
</FooterTemplate>
<FooterStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="50px" />
</asp:TemplateField>
So far, what I have found that works best is using a foreach statement in your button click. The biggest flaw with this idea is that it will update every single row. It works, but if you only change a single row at a time, it will update all of them. I have my pager set to 10, so 10 rows are always updated (unless you are just searching for a single record and update it, the only that single record is updated).
Code Behind C#
protected void btnUpdate_Click(object sender, EventArgs e)
{
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["databaseConnection"].ConnectionString);
conn.Open();
//finds the controls within the gridview and updates them
foreach (GridViewRow gvr in gvGridViewName.Rows)
{
string ID = (gvr.FindControl("lblId") as Label).Text.Trim();//finds the control in the gridview
string anotherControl = ((TextBox)gvr.FindControl("tbTextBox")).Text.Trim();//finds the textbox in the gridview
//Your update or insert statements
}
This is how I do it. You can also look into Real World Grids but I haven't had much luck with this as I would always get an error if a textbox was empty. This however, is suppose to be "smart" enough to just update the rows that have been changed, but again, I didn't have much luck of doing it this way. Hope this helps!
I'm new to asp.net development. I would like to ask if it is possible for one link button to have two or more commands?
What I want to happen is that my link button should be able to handle the edit and update commands. Once i click the link in my grid view, it will show the data on its respective controls (i.e textbox for name will have the data of what I clicked) then once I edit any data on the textbox and click the same link it will update and save in the database.
<asp:TemplateField HeaderText="ID">
<ItemTemplate>
<asp:LinkButton ID="lnkEdit" runat="server" CommandArgument='<%#Eval("ID")%>' CommandName="Update"
HeaderText="ID" SortExpression="ID" Text='<%#Eval("ID")%>'>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
Thanks in advance. Please help!. :)
Its not possible to have multiple commandname for one linkbutton,but when you click linkbutton for editing you can change commandname to "Update".I think this will solve your problem.For changing the commandname for linkbutton refer to this link.
You don't need to create two commands.
First set command name to Edit. Hence on clicking it. It will show data in controls.
Also in click event set command name to Update.
And after updating again set command name to Edit.
Write click event code like this.
if(CommandName=="Edit")
{
//Fill Value in controls
// Set CommandName to Update
}
else if(CommandName=="Update")
{
// Update value in database
// Set command name to Edit
}
Alternatively you can use two linkbuttons with one visible at a time.
Hope this help.
Hi Jenny use code like this:-
<asp:TemplateField HeaderText="ID">
<ItemTemplate>
<asp:LinkButton ID="lnkEdit" runat="server" CommandArgument='<%#Eval("ID")%>' CommandName="Update" Onclick="lnkEdit_Click"
HeaderText="ID" SortExpression="ID" Text='<%#Eval("ID")%>'>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
In aspx.cs Page write code like below:-
protected void lnkEdit_Click(object sender, EventArgs e)
{
LinkButton btn = (LinkButton )sender;
int Id = Convert.ToInt32(btn.CommandArgument.ToString());
if(btn.CommandName=="Edit")
{
// Write here code for edit
btn.CommandName="Update";
}
else if(btn.CommandName=="Update")
{
// Write here code for Update
btn.CommandName="Edit";
}
}
Hope this help.
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());
}
}
hi I have this gridview like this.
<asp:DropDownList ID="triggerDropDown" runat="server" AutoPostBack="true" onselectedindexchanged="triggerDropDown_SelectedIndexChanged">
<asp:GridView ID="myGridView" run="server">
<Columns>
<asp:TemplateField HeaderText="Column 1">
<ItemTemplate>
<asp:DropDownList ID="myDropDown1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Column 2">
<ItemTemplate>
<asp:DropDownList ID="myDropDown2" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
now, when I change my triggerDropDown I want to change also all of the DropDowns inside Column 1 how can I do that?
protected void triggerDropDown_SelectedIndexChanged(object sender, EventArgs e)
{
// what should I do here?
}
Inside your event method you should access the DropDownList that resides within each row of the GridView. Doing this you can bind each DropDownList to whatever data you want.
This link shows you how to do that:
http://www.velocityreviews.com/forums/t191319-need-help-with-accessing-a-control-within-a-template-field.html
Basically:
Iterate over each row of your GridView;
Find the DropDownList control with something like:
DropDownList mddl = GridView.Rows[2].FindControl("myDropDown1");
Bind new data to mddl.
The gridview is very likely not what you want here. The way to change the value of a control contained in a row is usually through grabbing a handle to the desired control using e.Item.FindControl() from within the ItemDataBound event of the gridview.
The problem with your approach is that you're wanting a control outside of the gridview (triggerDropDown) to interact with a single row of the gridview. Do you want the first row, first column, last row, first column or first column for each of the items in the grid? It's probably better you take the target of your trigger dropdown and place it outside of the gridview and deal with it directly.
If you really intend to change items in a row in the grid consider doing so in the ItemDataBound event of the gridview and you'll find lots of examples out there.
Actually I can use GridViewRow :) I just have to find the GridViewControl and get its Rows attribute which is a GridViewRow and now I can do a foreach of each row.
foreach (GridViewRow gridViewRow in (this.FindControl("myGridView") as GridView).Rows)
{
// I can see all elements of my row here as if I am traversing on GridViewEvents
}