Placing ASP.Net DetailsView into Edit mode and Update mode - asp.net

We are working with an ASP.Net DetailsView with a VB.Net code-behind file. We are trying to allow the user to edit and save changes in the DetailsView by allowing the user to click the Edit button and then click the Update button.
Nothing happens when the user clicks the Edit button so we added an OnClick handler for the Edit button. The DetailsView will go into edit mode but only if the user clicks the Edit button twice. (Maybe an ASP.Net bug?)
Once the DetailsView is in Edit mode the Update and Cancel buttons are displayed as expected but nothing happens when the user clicks either of those buttons. We placed an OnClick on the Update button in an attempt to force the DetailsView to Update but the only choices for .ChangeMode(DetailsViewMode. are Edit, Insert, ReadOnly.
I also thought DetailsViews did not need additional OnClicks unless we needed to perform special handling.
Here is the markup for the DetailsView:
<asp:DetailsView
ID="DetailsView"
runat="server"
Height="50px"
Width="218px" AutoGenerateRows="False">
<Fields>
<asp:TemplateField ShowHeader="False">
<EditItemTemplate>
<asp:Button ID="ButtonUpdate" runat="server" CausesValidation="True"
CommandName="Update" Text="Update" OnClick="ButtonUpdate_Click" />
<asp:Button ID="ButtonCancelUpdate" runat="server" CausesValidation="False"
CommandName="Cancel" Text="Cancel" />
</EditItemTemplate>
<ItemTemplate>
<asp:Button ID="ButtonEdit" runat="server" CausesValidation="False"
CommandName="Edit" Text="Edit" OnClick="ButtonEdit_Click"/>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Forename" HeaderText="First Name:" />
</Fields>
</asp:DetailsView>
Here is the coding in the code-behind file:
Public Class StudentDetailsMaintenance
Inherits System.Web.UI.Page
Dim theTableAdapter As New DataSetSingleStudentTableAdapters.StudentsMaintenanceTableAdapter
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
' Load the data from the database into the DetailsView.
'------------------------------------------------------
DetailsView.DataSource = theTableAdapter.GetDataByStudentID(StudentMaintenance.IntStudentID)
DetailsView.DataBind()
End Sub
Protected Sub ButtonEdit_Click(sender As Object, e As EventArgs)
' Place the DetailsView into Edit mode.
'--------------------------------------
DetailsView.ChangeMode(DetailsViewMode.Edit)
End Sub
Protected Sub ButtonUpdate_Click(sender As Object, e As EventArgs)
' Place the DetailsView into Update mode.
'----------------------------------------
DetailsView.ChangeMode(DetailsViewMode.)
End Sub
End Class
The ButtonUpdate_Click routine is incomplete because we don't know how to get the DetailsView to do the update.
Addional Note:
This is the first time we are trying to do a DetailsView by not setting up a DataSource in the markup. Instead of doing that we are using the data from a DataSet TableAdapter created in the DataSet designer.
If we did the DetailsView along with the DataSource all in the markup then the Edit and Update buttons work without any problem. We were also doing this in an attempt to eliminate extra coding if possible.

If you want the DetailsView's automatic behaviour for Edit, you need to use a CommandField to show the Edit button:
<asp:DetailsView id="dvDetailsView" runat="server" DataSourceId="sqlDS" DataKeyNames="primaryKey">
<Fields>
<asp:CommandField ButtonType="Button" ShowEditButton="true" />
</Fields>
</asp:DetailsView>
As noted above you need to include the DataKeyNames property to specify the primary key for the datasource so that ASP.NET knows which record in the data source to update. Also as mentioned above, you need to make sure that the Bind("columnName") statements use the same field names as used in your data store.
Also, make sure that you provide an UpdateCommand in your SqlDataProvider (or equivalent for your data store) so that the update can take place.
Now when you place the DetailsView into Edit mode, the Update and Cancel buttons will automatically be displayed where the is. If you need to do some work with the data before the data is updated in the data store, then handle the DetailView's ItemUpdating event in the code behind.

Well, looking real briefly, try wrapping your Page_Load databind in an If Not Page.IsPostback.
Postback wreaks havoc on databound controls.

Related

How to use Session to save value on current row of GridView, to be copied into TextBox? - VB.Net

I'm trying to use Session to record the data of the 1st column of current row to be used in another Web From which will be opened using a LinkButton that is in the GridView.
Basically, if I click the LinkButton on the 1st row, the 1st column data of the 1st row will be copied to the next Web Form. But before I do that, I want to do a smaller scale experiment to test it. So instead for now I want the Session to copy the data into a TextBox in the same form.
For reference, here is the design of the GridView, most rows removed since they're not relevant:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
BorderColor="Black" BorderStyle="Solid" BorderWidth="1px" Font-Names="Arial">
<AlternatingRowStyle BackColor="#B7DBFF" />
<Columns>
<asp:BoundField DataField="caseticket" HeaderText="Ticket #" >
<HeaderStyle BackColor="#000066" ForeColor="White" Wrap="False" width="10%"/>
<ItemStyle Wrap="False" />
</asp:BoundField>
<asp:TemplateField ShowHeader="False">
<HeaderStyle BackColor="#000066" ForeColor="White" Wrap="False" width="10%"/>
<ItemTemplate>
<asp:linkbutton ID="newLog" runat="server" onclick = "CaseLog_click" >Add Log </asp:linkbutton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<HeaderStyle BackColor="#000066" />
<RowStyle HorizontalAlign="Center" />
</asp:GridView>
For the TemplateField is a LinkButton with a onclick property. With it, I created the sub:
Sub CaseLog_click(ByVal sender As Object, ByVal e As EventArgs)
Session("ticket") = GridView1.SelectedRow.Cells(1).Text
'Response.Redirect("~/CaseLog.aspx") ==> will be using this to proceed to next Web Form
TextBox1.Text = Session("ticket") '==> For test use only.
End Sub
If I only kept the Response.Redirect("~/CaseLog.aspx") in the sub, the LinkButton can direct me to the next Web Form. But as it is now, during testing when I use the LinkButton I get an error on the session line of the sub.
Object reference not set to an instance of an object.
Is the code salvageable, or do I need to redo this?
Thanks.
It looks like the button event to select the row is not wired up.
I would use say this:
<asp:BoundField DataField="HotelName" HeaderText="HotelName" SortExpression="HotelName" />
<asp:ButtonField CommandName="Select" HeaderText="Select" ShowHeader="True" Text="Button" />
Note CAREFULL how we put the CommandName="Select" in above. If you don't do this, then the selected row does not come though correctly to the click event you have.
You could try the select command as per above on your link button, but I would just use the above. Now, hightlight the grid in the form desinger. On the properity sheet, go to events, and double click on the SelectedIndex Change event. So, your buttion is not changing the selected index correctly.
The code stub will look like this:
Protected Sub GridView1_SelectedIndexChanged(sender As Object, e As EventArgs) Handles GridView1.SelectedIndexChanged
Dim lgridrow As GridViewRow = Me.GridView1.SelectedRow
Debug.Print("<" & lgridrow.Cells(0).Text & ">")
Debug.Print("<" & lgridrow.Cells(3).Text & ">")
Debug.Print("<" & Me.GridView1.SelectedRow.Cells(3).Text & ">")
End Sub
Note VERY careful how the event code stub is setup - the event args are different then yours.
So, you can try the CommandName="Select" in your existing code, but if not, then try the above button field as opposed to your custom asp.net button you have. As it stands, it don't look like your asp.net button is firing the row-changed event.
Edit and follow up:
Can I have extra buttons - run their own code?
Yes, you can. You can do this several ways (one is to pick up which button was clicked in the SelectedIndex change event.
Or, you can drop in extra buttons and use that event code stub.
So, in my example, lets add an extra button.
we now have this:
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False" ReadOnly="True" SortExpression="ID" />
<asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" SortExpression="HotelName" />
<asp:ButtonField CommandName="Select" HeaderText="Select" ShowHeader="True" Text="Button" />
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="LinkButton1" runat="server" OnClick="LinkButton1_Click"
CommandName="MySelect" CommandArgument ="<%# Container.DisplayIndex %>"
style="background-color:gray;color:white;text-decoration:none;padding-left:6px;padding-right:6px"
text="Mybutton"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
We thus have this:
Now, we can attach/have button code for the extra button. But NOTE careful we did NOT use the built in SELECT for the command argument. The REASON is that if we have Command=select, then the selected index WILL fire, but AFTER our button code stub. That means we cannot use the selectedrow (too early).
So, what we do/did in above was have the CommandArguemnt PASS the selected row value - that value will pass ok, and thus we don't care that the selected index event does not fire (and by CHANGING our command argument to NOT "select", then in fact the selectedindexchange event DOES NOT fire.
As a result, we use the passed row in the command argument, and we have this for the button code:
Protected Sub LinkButton1_Click(sender As Object, e As EventArgs)
Dim ixrow As Integer = sender.CommandArgument
Debug.Print(Me.GridView1.Rows(ixrow).Cells(0).Text)
End Sub
And note while we are editing the markup, intel-sense will give a list of options when editing. Eg this:
So, that gives us a chance to wire up (add) a standard click event). No selected index code stub is required (since the button would fire before selected index anyway). So we are now manually wiring up this event. We are NOT thus using the selectedindex change event - we don't even need it.
So, now in our button stub, we are free to do anything we want - including jumping to another page
eg:
Protected Sub LinkButton1_Click(sender As Object, e As EventArgs)
Dim ixrow As Integer = sender.CommandArgument
Debug.Print(Me.GridView1.Rows(ixrow).Cells(0).Text)
Session("HotelName") = Me.GridView1.Rows(ixrow).Cells(3)
Response.Redirect("~/ShowHotelDetails.aspx")
End Sub
So, to add separate code buttons:
Don't use selected index change event - you MIGHT still want it to run but it will run/fire AFTER your button code (so can't use selectedrow - too early).
But, you do need Command="myjunk" because without a command, then the command argument does not work. By passing the row index in commandargument, then we are free to grab data from the gridview as per above code via row index.
So, you can well dump the selected index change event. You just have to pass the row index, and work from that. The code stub can thus walk the dog, setup values in session, or even pass/make the url with parameters.

Call Sub Procedure using Gridview Column Imagefield

I have a Gridview column called "Path" and when the user clicks on it I want it to pass that value of the "Path" cell to a sub procedure to execute the following code,
process.start(Path)
Currently the table is filled via SQL query and the "Path" is clickable but it wants to take me to URL which won't work for my situation. I also tried the Hyperlink column as well but was having the same problem. Any guidance would be appreciated! Thanks in advance.
You could use a LinkButton instead of a HyperLink.
Set the CommandArgument on the LinkButton, you could use either the GridView.RowCommand event handler or a LinkButton.OnClick event handler to call your sub.
<asp:GridView ID="gridView" runat="server" AutoGenerateColumns="False" OnRowCommand="gridView_RowCommand">
<Columns>
<asp:TemplateField HeaderText="Path">
<ItemTemplate>
<asp:LinkButton ID="lbPath" runat="server" CommandArgument="<%# Eval("Path")%>" OnClick="lbPath_Click"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Then in code behind:
Protected Sub lbPath_Click(sender As Object, e As EventArgs)
Dim linkButton As LinkButton = CType(sender, LinkButton)
Process.Start(linkButton.CommandArgument)
End Sub
For reference
https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.linkbutton(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.gridview.rowcommand(v=vs.110).aspx

asp.net VB gridview checkbox always show false on serverside code behind

I am trying to implement a gridview with checkbox column on asp.net (VB). when the user checks checkbox and click delete button, it should access database and delete all checked item.
I have already tried numerous googled solution and never worked for me. here is short scenario
on my aspx page:
1)search by id text box, when user enter ID and click search button, the below table is displayed
<asp:GridView ID="MyGridView" runat="server">
<Columns>
<asp:TemplateField headertext="Name">
<ItemTemplate>
<asp:Label id="namelbl"
text='<%# Eval("name")%>' runat="server"/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Delete Now?">
<ItemTemplate>
<asp:CheckBox Enabled="true" ID="chkStatus" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
after data is displayed, user checks the desired checkbox and click delete button, then the code behind is run
Protected Sub DelSelected(ByVal sender As Object, ByVal e As System.EventArgs)
Dim idList as ArrayList = new ArrayList()
For Each row As GridViewRow In MyGridView.Rows
Dim selectcb As CheckBox = CType(row.FindControl("chkStatus"), CheckBox)
If (selectcb.Checked) Then
'put into delete list
Trouble starts here, selectcb checkbox is always false
How could that happen, any idea would be appreciated
Thanks
you must bind your data only when no IsPostback in order to persist your checkbox selected, and no reset
If(! IsPostBack)
{
Bind();
}

asp:ImageButton in Gridview OnClick event not working

I've spent quite a while searching this problem, there are some other similar threads online but none have helped me fix it.
I have a GridView with an ImageButton within it, the imagebutton has an OnClick function but that event is never reached when it is clicked, below is my gridview:
<asp:GridView ID="gridBuildings" runat="server" AutoGenerateColumns="False"
GridLines="none" ShowFooter="false" ShowHeader="false"
Width="100%">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:ImageButton runat="server" ID="cmdBuy"
ImageUrl="~/images/button.jpg"
OnClick="ImageButton_Click"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
and here's the code-behind (I've removed the extra content, the response.redirect is never hit when the ImageButton is clicked)
Protected Sub ImageButton_click(ByVal sender As Object, ByVal e As ImageClickEventArgs)
response.redirect("test.aspx")
Dim row As GridViewRow = Me.gridBuildings.SelectedRow
(etc ... )
End Sub
There is a form runat="server" tag in the master page, as well as an asp:UpdatePanel and an asp:AjaxScriptManager I have a feeling the problem might be something to do with a postback but just can't work it out - any help would be appreciated.
Thanks!
Make sure you are not rebinding the grid every page load. If you rebind, the event will never fire. Wrap the binding statement in an if not ispostback block.

Checkbox within Datagrid retaining checked value on postback in VB.NET but not C#

Hey there, I have a project in VB.NET which is working fine which essentially has a Datagrid that has a TemplateColumn included which is a column of Checkboxes. The code to declare the datagrid is here...
<asp:datagrid id="dgDates" OnItemCommand="gridEventHandler" BorderColor="Black" BorderWidth="1px"
CellPadding="3" runat="server" AutoGenerateColumns="False" HorizontalAlign="Left" AllowSorting="True"
OnSortCommand="SortData" OnItemDataBound="gridItemDataBound">
<HeaderStyle Font-Underline="True" Font-Bold="True" HorizontalAlign="Center" ForeColor="Black"
BackColor="#D4D0C8"></HeaderStyle>
<Columns>
<asp:BoundColumn DataField="strParameterName" SortExpression="strParameterName" HeaderText="Parameter Name"></asp:BoundColumn>
<asp:BoundColumn DataField="dtParameterValue" SortExpression="dtParameterValue" HeaderText="Parameter Value"></asp:BoundColumn>
<asp:TemplateColumn HeaderText="Constant" SortExpression="blnStatic" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox ID="cbStaticRolling" Checked="False" Runat="server" AutoPostBack="true"></asp:CheckBox>
</ItemTemplate>
</asp:TemplateColumn>
</Columns>
as you can see the Checkbox has Autopostback="true" but there are other things on the page which produce postbacks as well.
My Page_load has this in it, being called on every load of the page, postbacks included...
Dim strGUID As String
strGUID = Session("strGUID")
dgDates.DataSource = SqlHelper.ExecuteDataset(ConfigurationManager.AppSettings(Web. [Global].CfgKeyConnStringADMIN), "dbo.spRptGetSchedulingDates", strGUID)
dgDates.DataBind()
intNumberOfDates = dgDates.Items().Count
as well my code behind has the following code for the gridItemDataBound
Protected Sub gridItemDataBound(ByVal sender As System.Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs)
'hide the intRptSchedulingDatesID for each row in the checkbox's content style variable
If (e.Item.ItemType = ListItemType.Item Or e.Item.ItemType = ListItemType.AlternatingItem) Then
CType(e.Item.FindControl("cbStaticRolling"), CheckBox).Style("Content") = CType(e.Item.DataItem, System.Data.DataRowView).Item("intRptSchedulingDatesID")
End If
End Sub
everything you see sbove is working perfectly fine...in the sense that when I click one of the checkboxes, the page_load fires, the gridItemDataBound fires on DataBind() and when all is done, the checkbox retains the value that the user clicked the checkbox.
With all this exact same code converted to C#....the events all fire in the same order, but the checkbox selected value always clears...any thoughts??
I'd say the problem is that you're are binding the grid on every postback (I can't explain the difference between VB and C#). This clears your selections. Why are you doing this?
You bind the grid on every page_load, this causes checkbox to be always the same.
Try to attach a checkedchange event on ItemDataBound and when event fires, store checkbox value on a session variable.
On ItemDataBound, check session variable and if its null, run this code, otherwise read checkbox's value from your session variable
And On Page_Load, if not IsPostBack (page is loading first time), set your session value to null

Resources