I have a gridview that is serviced by a sqldatasource and I was just wondering how is it possible to have the Edit button do something other than put the gridview row in edit mode.
<asp:CommandField ShowSelectButton="True" ShowEditButton="true" ButtonType="Button" />
What I want to do is have a custom edit page/control that is loaded when you click Edit.
As opposed to just put the row in edit mode and turn the fields into editable textboxes.
Is something like that possible?
There are two options that come to my mind:
Use EditTemplates for your GridView fields
This will let you customize the look / content of each of the fields when they go into edit mode.
<Columns>
<asp:TemplateField ...>
<EditItemTemplate>
<!-- child controls -->
</EditItemTemplate>
<ItemTemplate>
<!-- child controls -->
</ItemTemplate>
</asp:TemplateField>
</Columns>
Handle the RowEditing event
You can handle the RowEditing event to do whatever manipulation on the Gridview that you want in repsonse to a "Edit" button in the row being clicked.
Related
This question may look repeating but I'm having a slightly different challenge. I have a GridView with multiple columns. The first column is a Button column and the rest are populated from the database.
Problem Statement:
When a user clicks the Edit button on a specific row, a TextBox should appear in the column called UnitRate in the GridView gv2. The default text of the TextBox should be the value / text of that same cell. This TextBox should appear only for that specific cell not for the entire column. The current GridView is shown below.
And I want something like this
Code for GridView
<asp:GridView ID="gv2" runat="server" Font-Size="Small" OnRowCommand="gv2_RowCommand">
<HeaderStyle BackColor="Yellow" />
<AlternatingRowStyle BackColor="LightGray" />
<RowStyle BackColor="LightGray" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btn_edit" runat="server" Text="Edit" CssClass="btn btn-warning btn-sm" CommandName="editData" CommandArgument='<%# Container.DisplayIndex %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns></asp:GridView>
You can try something like this: https://www.c-sharpcorner.com/UploadFile/1e050f/edit-and-update-record-in-gridview-in-Asp-Net/
You can use the EditItemTemplate to make that UnitRate field a text box when the user clicks edit. You can then make the EditItemTemplate for all the rest of the fields to just be a label. The drawback is that you have to spell out all the columns explicitly rather than having them autogenerated, but that's unavoidable if you want something non-standard like this to happen, where one field is editable while others aren't.
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 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();
}
I am displaying a table in a grid view in a asp.net webpage. I want the user to select one row in the website and delete it. How can I do that. I have a delete button in the same page, where I will do code behind to drop the row in the database. But my problem is how can user select one row in the table .
<asp:GridView ID="GridView1" runat="server" CssClass="style29">
<Columns>
<asp:TemplateField HeaderText="Send Message to Group">
<ItemTemplate>
<asp:LinkButton ID="LinkButton2" runat="server"
PostBackUrl='<%# Eval("GroupName", "SendMessage.aspx?GroupName={0}") %>'
Text='Send Message'></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Is it possible to do without a check box? Or can I add a delete image to the table in a separate column and on clicking the button the row will be deleted.
You should add:
<asp:CommandField ShowSelectButton="True"/>
on your gridview.
Use ICallbackEventHandler to trigger an action on the server.
But my problem is how can user select one row in the table .
this code adds a Select button:
<asp:CommandField ShowSelectButton="True" />
Now your problem is only to get the server to execute some piece of code, do that using ICallbackEventHandler or Ajax.
I have a GridView that is populated via a database, inside the GridView tags I have:
<Columns>
<asp:TemplateField>
<ItemTemplate><asp:Panel ID="bar" runat="server" /></ItemTemplate>
</TemplateField>
</Columns>
Now, I want to be able to (in the code) apply a width attribute to the "bar" panel for each row that is generated. How would I go about targeting those rows? The width attribute would be unique to each row depending on a value in the database for that row.
<asp:Panel ID="bar" runat="server" Width='<%# Eval("Width") %>' />
If you like, you can change Eval("Width") to the expression that calculates the width.
You are going to want to handle the GridView's RowCreated event. This occurs just after the GridView creates each row and will give you programmatic access to the row and all the controls contained within it.
Here is the MSDN page on the event.
I suggest you to not use Eval, if you can, because it's a little slower. In that cases I generally prefer to cast my data source to his base type:
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Panel ID="bar" runat="server" Width='<%# ((yourCustomData)Container.DataItem).Width %>' />
</ItemTemplate>
</TemplateField>
</Columns>
where yourCustomData is the row type of your data source (i.e. the element of a List<>).
This method is really faster than Eval.
Edit: oh, don't forget to include in the page a reference to the namespace that contains yourCustomData
<%# Import Namespace="yourNameSpace.Data" %>
I suggest you attach a callback handler to the OnRowDataBound event. Each row binding will fire an event which you can handle in your callback handler.
In that callback handler, you can get the info about the item being bound to the row and apply the width according to the values in your database.