I've written an ASP code for a webshop type project. There is a method that adds the ProductID to a cookie and adds 1 to the quantity of the product.
Another method reads the cookie, transforms the cookie to a data table and puts it in a gridview. This gridview basically is the shoppingcart.aspx page.
What i now need is a way to add a buttonfield to that gridview where i can add a ++ button (like the add to shopping cart button on a product page), normal asp buttons take a onclick="methodname" but these in the gridview don't.
add1ToShoppingCart(string productId)
{[...]shoppingCartCookie[productId] = (amount + 1).ToString();}
That is the code I use for all the ++ buttons. It takes the button.id (buttonID=productID). So I need a way to have all the buttons be the same image, but the buttonID has to be databound to the productID so it can somehow execute that method (with some sort of onclick="").
I've looked and googled for the past couple hours but I cant seem to find anything. In the past I found a lot of answers on stackoverflow so I hoped somebody here could help.
Thanks in advance.
you can use Template field :
<asp:TemplateField ItemStyle-Width="33px" ItemStyle-HorizontalAlign="Center" ItemStyle-VerticalAlign="Middle"
ShowHeader="false" HeaderStyle-Height="40px">
<ItemTemplate>
<asp:ImageButton ID="btnAddToCard" runat="server" ImageUrl="~/Images/btnAddToCard.png" CausesValidation="false"
CommandName="AddToCard" CommandArgument='<%# Eval("ID") %>'
/>
</ItemTemplate>
<HeaderStyle Height="40px"></HeaderStyle>
<ItemStyle HorizontalAlign="Center" VerticalAlign="Middle" Width="33px"></ItemStyle>
</asp:TemplateField>
and in your C# code behind you create the following event of your gridview and do what you want :
protected void GV_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "AddToCard")
{
//Write code to add to card
}
}
GV is the ID of my GridView !
Related
I have an issue with nested Gridview!
I have two Girdviews with the ID - GridView1(Parent Gridview) and GV2(Child Gridview)
I have a Asp:Button with the ID - btnedit(Event = OnClick())
Qs: how to access GV2 in btnedit_Onclick event?
I have attached the Code for your Reference:
<form id="form1" runat="server">
<asp:Button runat="server" ID="btnedit" Text="Edit" OnClick="btnedit_Click" />
<asp:GridView runat="server" ID="Gridview1">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label runat="server" ID="Lable1"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:GridView runat="server" ID="GV2">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label runat="server" ID="Lable2"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</form>
code Behind:
protected void btnedit_Click(object sender, EventArgs e)
{
}
Ok, so the user wants to operate on the row 1 of main GV and then get row 1 of the child.
Gridviews start at 0, so it not clear, but lets take the both first rows.
next up? I really (but really really really) suggest you use a main listview and then nest a child GV.
If you nest two GV's, you tend to get this:
Say this GV, with a "+" to expand the child grid:
And expanding, you get this:
So, nesting grids is VERY hard, since the "col span" is hard to setup.
However, if I build a main listview (looks the same as a GV), and then next a gv, then I get this:
So above uses a main list view, and thus for expanding child reocrds I do and did use a GV in the child of the listview.
I can post how above works and even the markup if you wish.
However, lets go with the two nested GV's - it will make a mess of a UI but for learning, how this works with the above nested LV + GV, or a GV + GV is the same.
So, some plane jane button - outside of the two grids, get the first row of the main, then the first row of the child grid.
This works:
protected void Button1_Click(object sender, EventArgs e)
{
GridViewRow MainGvRow = GridView1.Rows[0];
GridView ChildGV = MainGvRow.FindControl("GridView2") as GridView;
GridViewRow ChildGVRow = ChildGV.Rows[0]
}
This may get you started...
GridView gvGV2 = e.Row.FindControl("GV2") as GridView;
gvGV2.DataSource = "..."; //Your DataSource
gvGV2.DataBind();
// or do something else.
I have been trying to write this simple logic of deleting a row from the gridview and from the SQL database of the selected row, but keep getting a null reference to cell, which has the primary key [ID] in a field.
Here's my html:
<asp:GridView ID="grvInventoryEdit" runat="server" BackColor="White" onrowdeleting="grvInventoryEdit_RowDeleting"
onrowediting="grvInventoryEdit_RowEditing"
onrowupdating="grvInventoryEdit_RowUpdating">
<Columns>
<asp:CommandField ShowEditButton="True" />
<asp:CommandField ShowDeleteButton="True" /><asp:TemplateField HeaderText="Id">
<ItemTemplate>
<%#Eval("No")%>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" ID="txtEditNo" ReadOnly="True" Text='<%#Eval("No")%>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>........ </Columns> </asp:GridView>
And my back-end code for rowdeleting event is :
protected void grvInventoryEdit_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
TextBox id = (TextBox)grvInventoryEdit.Rows[e.RowIndex].FindControl("txtEditNo");
Asset asset = db.Assets.Single(a => a.No == Convert.ToInt32(id));
db.Assets.DeleteOnSubmit(asset);
db.SubmitChanges();
binddata();
}
and when the event fires, this is what i am seeing while debugging:
I am not sure why i am getting a null value ,though, there is a value for that cell.
Could you tell me what i am doing wrong ?
Regards,
Might be it is due to the readonly property of textbox, not suer.
If you want to use the image button for edit and delete then use
protected void ibtnDelete_Click(object sender, ImageClickEventArgs e)
{
GridViewRow gvRow = (GridViewRow)((ImageButton)sender).NamingContainer;
Int32 UserId = Convert.ToInt32(gvUsers.DataKeys[gvRow.RowIndex].Value);
// delete and hide the row from grid view
if (DeleteUserByID(UserId))
gvRow.Visible = false;
}
For complete code see
You are passing TextBox object instead instead of Text property of TextBox
Asset asset = db.Assets.Single(x=>x.No == Convert.ToInt32(id.Text));
and your TextBox is also coming null means it's unable to find it in GridView, try like this:
TextBox id = e.Row.FindControl("txtEditNo");
Also see this CodeProject article to understand how to use ItemTemplate and EditItemTemplate
why are you adding a second commandfield instead of just enabling the delete button on the existing one.
if you are using a command field you should be supplying an compatible datasource that provides Delete functionality
if you're "rolling your own" delete functionality then just use a regular Button control and supply a CommandName and CommandArgument, such as CommandName="MyDelete" CommandArgument=<row number> where <row number> is supplied via GridView RowDataBound() event.
Regardless of how you choose to implement Delete you should be placing the key field in the GridView DataKeys Property and not as a field within each row. This will make obtaining the PK far easier than what you are trying to do
I guess, in my HTML, i have only the value that's bound to the item, is being displayed, and there are no textboxes in my <ItemTemplate>, hence, it pulls null value. Whereas, in my <EditItemTemplate> there is a textbox, which can pull the value from the cell.
So I changed my HTML to this:
<asp:TemplateField HeaderText="Id">
<ItemTemplate>`<asp:label runat="server" ID="lblEditNo" ReadOnly="True" Text='<%#Eval("No")%>'></asp:label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox runat="server" ID="txtEditNo" ReadOnly="True" Text='<%#Eval("No")%>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
and no change in my codebehind, and this resolved the issue.
I have a ListView nested inside the column of a GridView, which looks something like this:
<asp:panel id="myPanel" Runat="server" EnableViewState="False">
<asp:GridView id="myDescription" AutoGenerateColumns="False" Width="100%" runat="server"
OnRowCommand="my_RowCommand" OnRowDataBound="GetDataForListView" EnableViewState="False">
<Columns>
<asp:BoundField DataField="id" HeaderText="ID">
<HeaderStyle HorizontalAlign="Center"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="data1" HeaderText="Thing 1">
<HeaderStyle HorizontalAlign="Center"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="data2" HeaderText="Thing2">
<HeaderStyle HorizontalAlign="Center"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="data3" HeaderText="Thing3">
<HeaderStyle HorizontalAlign="Center"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundField>
<asp:TemplateField SortExpression="id">
<ItemTemplate>
<asp:HyperLink id="hlView" runat="server" NavigateUrl="...">View</asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Column to contain my list of things">
<HeaderStyle HorizontalAlign="Center"></HeaderStyle>
<ItemStyle HorizontalAlign="Center"></ItemStyle>
<ItemTemplate>
<% /* This is my list view: */ %>
<asp:ListView ID="myListView" runat="server" OnItemCommand="DoSomething" EnableViewState="False">
<ItemTemplate>
<asp:LinkButton ID="lbAttachment" Runat="Server" Text='<%# Eval("FILE_NAME") %>'
CommandName='<%# Eval("ROW_NUM") %>' CausesValidation="False" >
</asp:LinkButton><br/>
</ItemTemplate>
</asp:ListView>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:panel>
The data is successfully binding, but the OnCommand event is not being fired on clicking the LinkButton (nor is any other event for the LinkButton, such as an OnClick event).
The rendered HTML for the link button shows that on clicking it, the page is performing a postback: javascript:__doPostBack('...','')
This means it is going back into my 'Page_Load' and refreshing the contents of the page - the grid view is binded here.
I can stop it from performing a postback by adding this attribute to the LinkButton:
OnClientClick="return false;"
But this only stops the postback from occurring, the OnCommand event still doesn't fire.
Any ideas?
The event signature in the code-behind is:
protected void DoSomething(object sender, CommandEventArgs e) { ... }
I have also tried using an OnItemCommand event on the ListView control with this event signature, but similarly the event is not invoked:
protected void DoSomething(object sender, ListViewCommandEventArgs e)
The OnRowdataBound event on the parent GridView is successfully invoked, it's only the nested ListView that fails to invoke its event.
The code I have shown is for the 2nd GridView on the page, there is another one too, and it is this one which gets binded on the Page_Load event. The Page Load event has a sequence of events as follows, where the 1st GridView (which we'll call GridView1) is bound:
Page_Load
Data for GridView is retrieved from database
Data is assigned to a 'DataView' object and assigned to the GridView1 DataSource property.
GridView1.DataBind() is invoked
Miscellaneous conditional logic which removes certain columns from GridView1
An OnClick attribute is added to each row.
So actually, the Page_Load binds the first GridView. The 2nd GridView is the one which contains the ListView which I am having a problem with. This 2nd GridView (the code of which is at the top of the post) is populated on the 'OnRowCommand' event of the 1st GridView, and has a sequence like this:
GetDataForListView
Get data from database
Assign the DataSet containing the data to the DataSource property of the 2nd GridView
Call the DataBind() method
Then, as you can see from the code I posted at the top, I have the OnRowDataBound event which fails to invoke its event in the code-behind.
Ciaran, I replicated the whole scenario and found out the below issue.
Issue: When any event related to either the GridView2 or ListView or the LinkButton is being fired it first hits the Page_load function. In the Page_load function you are not data binding GridView2 and the ListView so apparently they almost vanish and so the Event will not be fired.
Possible Fix:
You need to bind the GridView2 in the Page_load function in order fire those related events and the same goes with the ListView Too.
This fix is a very big one. I am not sure if you could try this.
a. If you are binding the GridView2 depending on the condition generated by the GridView1 click then store those parameters in some hidden field.
b. Have a function named LoadGridView2(parameters) where you bind the GridView2 and the ListView depending on the parameters passed and call this function in the Page_Load function each every time a PostBack is done and pass the stored parameters in the hidden field to the LoadGridView2(parameters)
c. By doing above you can bind the GridView2 according the GirdView1 Click condition and make the GridView2 and ListView available in the PostBack too. So now the event could be fired.
Let me know in case of any queries.
LinkButton has OnCommand, ListVIew has OnItemCommand. So the name isn't correct. OnCommand only fires if the LinkButton has a CommandName set. And also, the repeater may swallow the button's command argument. Certain controls do that because of the way events bubble up to the UI.
<asp:LinkButton ID="linkButton" Runat="Server" OnCommand="DoSomething"
CommandName="DoSomething"
CommandArgument='<%# Eval("ROW_NUM") %>' Text='<%# Eval("FILE_NAME") %>'>
</asp:LinkButton>
Or Try adding:
<asp:ListView .. OnItemCommand=".." />
And then do:
void DoSomething(Object Sender, ListViewCommandEventArgs e) {
// Do something
}
Your button would still need to set a command name like:
<asp:LinkButton .. CommandName="DoSomething" />
I have a gridview and I would like to Autosave the fields without using a save or an update button. How do I fire the RowUpdating Event without using a button? Or is there a better way of implementing this? Thanks for your help.
<div id="form_BCFLP" class="fm_Medium5" runat="server" visible="true">
<asp:GridView ID="GV_BCFLP" runat="server" AutoGenerateColumns="False" DataKeyNames="Id,Name"
GridLines="none" Visible="true" OnRowUpdating="GV_BCFLP_RowUpdating" EnableViewState="true" AutoPostback="true">
<Columns>
<asp:BoundField DataField="Name" ItemStyle-HorizontalAlign="left" ItemStyle-CssClass="lblSize_LargeBlack"></asp:BoundField>
<asp:TemplateField ItemStyle-HorizontalAlign="left">
<ItemTemplate>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
protected void GV_BCFLP_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
//I call my webservice here to update data
}
Using the RowUpdating event requires you to do a post back which probably is not what you are looking for. For proper auto saving you dont want to (typically) disrupt the user while they are filling in the form.
Instead you may want to look at using aJAX and javascript script functions to extract the entered data from the grid view and send it to your server. This way the user does not have to wait for your auto-save to finish before continuing the form.
Now there are lots of tutorials out there on how to use aJax and other scripting tools. I would suggest going down this route.
Cheers,
Nico
I am new to ASP.net thing, and i have some question regarding postback.
I have a Senario like this:
1) I have a grid on web with a panel inside.
2) I "Insert" the panel with a Web User Control by calling this
Control ctlControl;
ctlControl = LoadControl("~/UserControls/ChequeCreation.ascx");
pnlTransaction.Controls.Add(ctlControl);
3)The Web User Control providing two button. One is "update" and one is "reset".
Problem is like here:
What i wanted to achieve is when press the "update" button, it will update something back to my DB? But seem after i press the button "Update" or "Reset". The web user control is gone or missing. For my guest is because of the postback issues? Is that correct?
I tried if(!postback) still its doesn't work.
How am i going to overcome this? I already scratching my head about a day?
Thanks you so much.
Regards
LiangCk:
PS:Sorry for my english level, and please dont hesitate to voice out my error or mistake.
well you can convert any of your data columns to template column and then drag and drop your web user control to it
this will result in something like the following code check where "uc1:webUserControle1" is located in the code
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="ID" DataSourceID="SqlDB">
<Columns>
<asp:TemplateField HeaderText="ID" SortExpression="ID">
<EditItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("ID") %>'></asp:Label>
</EditItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("ID") %>'></asp:Label>
<uc1:webUserControle1 ID="WebUserControle1_1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="name" HeaderText="name" SortExpression="name" />
</Columns>
</asp:GridView>
if you are using AJAX, try add updatepanel on your UCT design page
ASP.NET will not preserve a dynamically added user control between postbacks. This is why it is dissapearing. You will need to add the control each time the page is created. However you will need to add it when the control tree is being initialized and restore the original control ID if you want your events to fire. These links provide a full explanation https://web.archive.org/web/20210330142645/http://www.4guysfromrolla.com/articles/092904-1.aspx and http://avinashsing.sunkur.com/2011/02/24/dynamic-controls-viewstate-and-postback/
You have to Every Time Reload the user control on Page_Init or
Page_Load. Then you can get the Button Click Event and After tha User
Control will not lost.
private void LoadUserControl(){
string controlPath = LastLoadedControl;
if (!string.IsNullOrEmpty(controlPath)) {
PlaceHolder1.Controls.Clear();
UserControl uc = (UserControl)LoadControl(controlPath);
PlaceHolder1.Controls.Add(uc);
}
}
protected void Page_Load(object sender, EventArgs e) {
LoadUserControl();
}