Can I add an additional action to a DetailsView in ASP.NET? - asp.net

Currently I have a DetailsView attached to a GridView. When you select an item from the GridView the details show up in the DetailsView (duh). Right now there are 3 event options on the DetailsView: Edit, Delete, and New. I would like to add a 4th, Format. This will simply run some queries and then perform a delete. Is this possible and how?
Another possibility would be to add this event to the GridView instead (maybe while in Edit mode?)

If you add your own buttons to the DetailsView as suggested you can hook the ItemCommand event on the DetailsView and add any logic for each CommandName in the ItemCommand method
<%# Page Language="C#" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">
void CustomerDetailView_ItemCommand(Object sender, DetailsViewCommandEventArgs e)
{
// Use the CommandName property to determine which button
// was clicked.
if (e.CommandName == "Add")
{
// Add the current store to the contact list.
// Get the row that contains the store name. In this
// example, the store name is in the second row (index 1)
// of the DetailsView control.
DetailsViewRow row = CustomerDetailView.Rows[1];
// Get the store's name from the appropriate cell.
// In this example, the store name is in the second cell
// (index 1) of the row.
String name = row.Cells[1].Text;
// Create a ListItem object with the store's name.
ListItem item = new ListItem(name);
// Add the ListItem object to the ListBox, if the
// item doesn't already exist.
if (!ContactListBox.Items.Contains(item))
{
ContactListBox.Items.Add(item);
}
}
}
</script>
<html >
<head runat="server">
<title>
DetailsView ItemCommand Example</title>
</head>
<body>
<form id="Form1" runat="server">
<h3>
DetailsView ItemCommand Example</h3>
<asp:DetailsView ID="CustomerDetailView"
DataSourceID="DetailsViewSource"
AutoGenerateRows="false"
DataKeyNames="CustomerID"
AllowPaging="true"
OnItemCommand="CustomerDetailView_ItemCommand"
runat="server">
<FieldHeaderStyle BackColor="Navy" ForeColor="White" />
<Fields>
<asp:BoundField DataField="CustomerID" HeaderText="Store ID" />
<asp:BoundField DataField="CompanyName" HeaderText="Store Name" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:ButtonField CommandName="Add" Text="Add Contact" />
</Fields>
</asp:DetailsView>
<hr />
Contacts:<br />
<asp:ListBox ID="ContactListBox" runat="server" />
<!-- This example uses Microsoft SQL Server and connects -->
<!-- to the Northwind sample database. Use an ASP.NET -->
<!-- expression to retrieve the connection string value -->
<!-- from the web.config file. -->
<asp:SqlDataSource ID="DetailsViewSource" runat="server"
ConnectionString=
"<%$ ConnectionStrings:NorthWindConnectionString%>"
InsertCommand="INSERT INTO [Customers]([CustomerID], [CompanyName], [Address], [City], [PostalCode], [Country]) VALUES (#CustomerID, #CompanyName, #Address, #City, #PostalCode, #Country)"
SelectCommand="Select [CustomerID], [CompanyName],
[Address], [City], [PostalCode], [Country] From
[Customers]">
</asp:SqlDataSource>
</form>
</body>
</html>

Related

Populate a ASP.NET UserControl Dynamically

Is there anyway for a ASP.NET page with say a gridview on it to load a user control into a Modal popup. I would like to use the User Controls onload function but that is triggered when the parent page is loaded, not when you click on for example a link called 'edit' in the GridView.
I don't want to redirect to another ASP.NET page, I would like to popup the edit page which will contain many controls like Dropdowns and Listboxes that in themselves with contain hundreds of records.
I have tried using Ajax and JSON but the population of the dropdowns and listboxes is very slow.
Any help would be appreciated!
I have tried using Ajax and JSON but the population of the dropdowns and listboxes is very slow.
I do this all the time.
So, say a simple gv of hotels.
and our popup control is the user control that is a "form like" layout to edit the one row.
Note the "difficult" issue is if the user does edit, then we need to trigger a refresh of the grid. But, even that is quite easy.
So, say our gv - rather simple.
We drop in a plain jane button (for edit).
So, we have this markup (a gridview)
<div id="MyGridArea" runat="server" clientidmode="static">
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID"
CssClass="table table-hover" Width="60em" AllowPaging="True" GridLines="None"
ShowHeaderWhenEmpty="true" EnableViewState="false">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
<asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
<asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
<asp:BoundField DataField="HotelName" HeaderText="HotelName" SortExpression="HotelName" />
<asp:BoundField DataField="Description" HeaderText="Description" SortExpression="Description" />
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="cmdEdit" runat="server" Text="Edit" CssClass="btn"
OnClick="cmdEdit_Click" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<PagerStyle CssClass="GridPager" />
</asp:GridView>
<asp:Button ID="cmdAdd" runat="server" Text="+Add" CssClass="btn myshadow" />
</div>
<br />
<uc1:MyEditHotelC ID="EHotel" runat="server"
MyEditArea="MyEditArea"
MyGridArea="MyGridArea"
MyTable="tblHotelsA"
MyTitle="Edit Hotel Information" />
Note our plain jane edit button.
And, right below the gv is our user control.
Note how I have some custom (public properties) of the UC.
In above, the "div" for "grid" is setup, and also I define the div for editing.
Ok, so code to load is this:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadGrid()
End If
End Sub
Sub LoadGrid()
GridView1.DataSource = Myrst("SELECT * FROM [VtblHotelsA] ORDER BY HotelName")
GridView1.DataBind()
End Sub
And we now see/get this:
Ok, so now when we hit edit button?
We will get the current row, and THEN pop up our user control.
So, the code behind edit button is this:
Protected Sub cmdEdit_Click(sender As Object, e As EventArgs)
Dim btn As Button = sender
Dim gRow As GridViewRow = btn.NamingContainer
Dim intPK As Integer = GridView1.DataKeys(gRow.RowIndex).Item("ID")
Call EditOne(intPK)
End Sub
Sub EditOne(intPK As Integer)
Me.EHotel.MyPk = intPK
Me.EHotel.LoadData()
Me.EHotel.MyFocusCancel()
ScriptManager.RegisterClientScriptBlock(UpdatePanel1, UpdatePanel1.GetType,
"popedit", "popedit()", True)
End Sub
and now we see this:
I also have a pubic event for the UC. (since if the user edits, we need to re-load (re-display) the gv on this current page.
So, how does the UC pop up that dialog?
The UC uses jQuery.UI. (it does not matter what/which library you use to pop a dialog, but you should pick one and "run" with it.
So, the markup for the UC ALSO includes the jQuery pop dialog.
The markup for the UC is just a "div" and the jquery dialog code.
It looks like this:
<div id="EditRecord" runat="server" style="float:left;display:normal" clientidmode="Static" >
<br/>
<style>
.iForm label {display:inline-block;width:90px}
.iForm span {display:inline-block;font-weight:700
}
.iForm input {border-radius:8px;border-width:1px;margin-bottom:10px}
.iForm select {border-radius:8px;border-width:1px;margin-bottom:10px;margin-bottom:10px;height:24px;margin-left:-3px}
.iForm textarea {border-radius:8px;border-width:1px;margin-bottom:10px}
.iForm input[type=checkbox] {margin-right:8px}
</style>
<div style="float:left" class="iForm">
<label>HotelName</label>
<asp:TextBox ID="txtHotel" runat="server" f="HotelName" width="280">
</asp:TextBox> <br />
<label>First Name</label>
<asp:TextBox ID="tFN" runat="server" f="FirstName" Width="140"></asp:TextBox> <br />
<label>Last Name</label>
<asp:TextBox ID="tLN" runat="server" f="LastName" Width="140"></asp:TextBox> <br />
<label>City</label>
<asp:DropDownList ID="cboCity" runat="server" Width="140px"
DataTextField="City"
DataValueField="id"
f="City_ID" >
</asp:DropDownList>
<br />
<label>Province</label><asp:TextBox ID="tProvince" runat="server" f="Province" Width="75"></asp:TextBox>
(etc. etc. etc.). It just the layout in a div for editing the hotel.
And the pop dialog code is this:
<div id="mydelpop" style="display:none">
<h4>Really delete this Hotel?</h4>
</div>
<script>
function popedit() {
MyPWidth = "62em"
MyWidth = $(window).width()
if (MyWidth < 840) {
MyPWidth = (MyWidth - 25) + 'px'
}
var myDialog = $("#EditRecord");
myDialog.dialog({
title: "Edit Hotel",
width: MyPWidth,
modal: true,
appendTo: "form",
dialogClass : "dialogWithDropShadow",
close: myclose
});
}
function myclose() {
var myDialog = $("#EditRecord");
myDialog.dialog('close')
// myDialog.find("form").remove();
// destory the instance, but only
// if exists (if we dont' clean up then button
// clicks don't work on 2nd use of dialog)
if (myDialog.hasClass('ui-dialog-content')) {
myDialog.dialog('destroy');
}
}
</script>
So, the edit code, the JavaScript parts are part of the UC.
I only have to "set" the values for the UC, and of course "pop" the dialog by injecting the script. At that point, everything else is the UC.
You can see/try a working example of the above code here:
http://www.kallal.ca/WebSite11/WebForm2

aspx Gridview conditional format

I have a simple gridview and code behind to conditionally format some rows. It runs but nothing gets colored. I've tried various autoformatting and finally removed all in the hope that there was some magic but to no avail
protected void GridviewRowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
int CellValue = Convert.ToInt32(e.Row.Cells[2].Text);
if (CellValue >= 0)
{
e.Row.Cells[2].BackColor = System.Drawing.Color.Green;
}
if (CellValue < 0)
{
e.Row.Cells[2].BackColor = System.Drawing.Color.Red;
}
}
}
<%# Page Language="VB" CodeBehind="TrainPurch.aspx.vb" %>
<!DOCTYPE html>
<html lang="en" xmlns=http://www.w3.org/1999/xhtml>
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<asp:AccessDataSource ID="AccessDataSource1" runat="server" DataFile="D:\Inetpub/wwwroot\dealerinfo\oracledealerinfo.mdb" SelectCommand=" SELECT tblDealerMifTrained.R12Account, tblDealerMifTrained.GroupOwner, tblDealerMifTrained.Units AS Units, tblDealerMifTrained.ProductCode, ProdToEDP.Model, qry6aTrainedPurchase.Trained FROM (ProdToEDP INNER JOIN tblDealerMifTrained ON ProdToEDP.ProductCode = tblDealerMifTrained.ProductCode) INNER JOIN qry6aTrainedPurchase ON (tblDealerMifTrained.ProductCode = qry6aTrainedPurchase.ProductCode) AND (tblDealerMifTrained.R12Account=qry6aTrainedPurchase.R12Account) WHERE (((tblDealerMifTrained.Type)='Purchase')) GROUP BY tblDealerMifTrained.R12Account, tblDealerMifTrained.GroupOwner, tblDealerMifTrained.Units, tblDealerMifTrained.ProductCode, ProdToEDP.Model, qry6aTrainedPurchase.Trained;"></asp:AccessDataSource>
<div style="height:750px; overflow:auto">
<asp:GridView
id="GridView2"
runat="server"
AllowSorting="True"
DataSourceID="AccessDataSource1" Caption="Trained Purchased" PageSize="25" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="R12Account" HeaderText="R12Account" SortExpression="R12Account" />
<asp:BoundField DataField="GroupOwner" HeaderText="GroupOwner" SortExpression="GroupOwner" />
<asp:BoundField DataField="Units" HeaderText="Units" SortExpression="Units" />
<asp:BoundField DataField="ProductCode" HeaderText="ProductCode" SortExpression="ProductCode" />
<asp:BoundField DataField="Model" HeaderText="Model" SortExpression="Model" />
<asp:BoundField DataField="Trained" HeaderText="Trained" SortExpression="Trained" />
</Columns>
</asp:GridView> </div>
</form>
</body>
</html>
Display the page in design mode, right click on the gridview, and display the property sheet.
Like this:
Now that you display the property sheet, eg this:
In above, click on the event icon (lighting bolt).
You now see this:
So, double click on the Row data bound text area, and that should jump you to your code behind editor, and you can now type in code for that event.
However, I do note that the page you have has the code behind set for VB, and not c#. So I would REALLY suggest that you create a blank new page, and then copy the parts of the old web form into the new one - don't copy the WHOLE page markup, but JUST the parts inside of the form tags that you require. And then try the above set of steps to create the row data bound event.
In your code RowDataBound event missing.
<asp:GridView id="GridView2" runat="server" AllowSorting="True" OnRowDataBound= "GridviewRowDataBound"

Gridview is not updating inside of UpdatePanel

I understand that this is a very common issue, I have been reading documentation on it for days, and I am about to pull my hair out over this issue.
BACKGROUND
I have multiple Gridviews inside of an UpdatePanel. What is happening, is someone is importing an Excel spreadsheet, I am using OpenXML to shread the data and store it in a VB.NET datatable object. I then run all of that data through a custom validation (based on DB information) and then spit out the exceptions (errors) that occur into a Gridview depending on the exception. the max number is 4 Gridviews in one UpdatePanel (each Gridview has it's own functionality). There are two Gridviews that I am using a button to do an action using the data contained in the Gridview. Those two buttons are also located in the Update Panel, just underneath the corresponding Gridviews. Each Gridview is wrapped in an AJAX Collapsible Panel Extender.
Now, when the user clicks on the button, I have a click event in the code behind where I take the information and depending on the exception that occurred, Update or Insert the DB. I loop through the rows, and if no error occurs, I call the datatable.ImportRow and pass the current row to my "Ready" table. I use a ScriptManager.RegisterStartupScript in order to display an alert box letting them know if any errors occurred. Then, I rebind the exception table and the "Ready" table. I have tried just adding an AsyncPostbackTrigger, I have attempted simply calling udpMain.Update() in the code behind, and tried both options of setting the UpdatePanel's UpdateMode property to "Always" and "Conditional".
HTML
<asp:UpdatePanel ID="udpMain" runat="server" UpdateMode="Always">
<ContentTemplate>
<asp:Panel ID="pnlOwnershipDetailsHead" runat="server" Visible="false">
<div class="windHeader" style="cursor: pointer">
<asp:Label id="lblOwnershipDetails" runat="server">Ownership Exceptions</asp:Label>
<asp:ImageButton id="btnOwnershipHead" runat="server"/>
</div>
</asp:Panel>
<asp:Panel ID="pnlOwnershipDetailsBody" runat="server" Visible="false" CssClass="pnl">
<asp:GridView ID="gvOwnershipDetails" runat="server" CssClass="wind" CellPadding="5" AutoGenerateColumns="false">
<HeaderStyle CssClass="windHeader" />
<Columns>
<asp:BoundField DataField="Description" HeaderText="Description" />
<asp:BoundField DataField="Serial Number" HeaderText="Serial Number" />
<asp:BoundField DataField="Facility" HeaderText="Facility" />
<asp:BoundField DataField="Department" HeaderText="Department" />
<asp:BoundField DataField="EmpID" HeaderText="EmpID" />
<asp:BoundField DataField="Configuration" HeaderText="Config" />
<asp:BoundField DataField="Error" HeaderText="Errors" />
<asp:TemplateField>
<HeaderTemplate>
<asp:CheckBox ID="chkHeader" ToolTip="Select All" runat="server" onclick="changeAllCheckBoxes(this)" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="chkItem" runat="server" ToolTip="Select this item" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<asp:Button ID="btnOwnershipDetails" Text="Change Information" runat="server" CssClass="btn editBtn" />
<ajax:ConfirmButtonExtender ID="cbeOwnershipDetails" runat="server" TargetControlID="btnOwnershipDetails"
ConfirmText="Are you sure you would like to change the ownership information for the selected items?"
OnClientCancel="CancelClick" />
</asp:Panel>
</ContentTemplate>
<asp:UpdatePanel>
CODE BEHIND
Protected Sub btnOwnershipDetails_Click(sender As Object, e As System.EventArgs) Handles btnOwnershipDetails.Click
Dim importdata As New ImportData
Dim ownershipdt As Data.DataTable = Session("ownershipdt")
Dim finalimportdt As Data.DataTable = Session("finalimportdt")
Dim existsError As Boolean = False
For Each Row As Data.DataRow In ownershipdt.Rows
Dim i As Integer = 0
Dim cb As CheckBox = CType(gvOwnershipDetails.Rows(i).Cells(7).Controls(1), CheckBox)
If cb.Checked Then
If importdata.CheckEmpExists(Row("EmpID").ToString) And importdata.CheckSiteExists(Row("Facility").ToString) And importdata.CheckDeptExists(Row("Department").ToString) Then
importdata.UpdateDBOwnership(Row("Serial Number").ToString, ClientInfo.GetEmpID(Row("EmpID").ToString), ClientInfo.GetSiteID(Row("Facility").ToString), ClientInfo.GetDeptID(Row("Department").ToString), _
Row("Description").ToString, Row("Configuration").ToString, portalUser.EmployeeText)
finalimportdt.ImportRow(Row)
Else
existsError = True
End If
End If
i += 1
Next
If existsError = False Then 'Show alert box
ScriptManager.RegisterStartupScript(udpMain, udpMain.GetType(), "alert", "alert('You have changed the ownership information for the selected rows.')", True)
Else
ScriptManager.RegisterStartupScript(udpMain, udpMain.GetType(), "alert", "alert('There was an issue changing ownership to all of the selected rows.')", True)
End If
bindGV(gvOwnershipDetails, ownershipdt)
bindGV(gvImportDetails, finalimportdt)
'udpMain.Update()
Session("ownershipdt") = ownershipdt
Session("finalimportdt") = finalimportdt
btnEmail.Enabled = True
End Sub
Put your panel code between ContentTemplate under asp:UpdatePanel
<asp:UpdatePanel>
<ContentTemplate>
</ContentTemplate>
</asp:UpdatePanel>
Finally! I Have found the answer! https://sites.google.com/site/arlen4mysite/full-postback-for-templatef
Or a single line of code in the Page_Load() does the same thing
ScriptManager.GetCurrent(this).RegisterPostBackControl(btnOwnershipDetails);

GridView inside UpdatePanel not refreshing without a call to code behind

I am new to ASP.Net and I am confused about the way a GridView control works inside an UpdatePanel.
I have read the documentation here which states "By default, any postback control inside an UpdatePanel control causes an asynchronous postback and refreshes the panel's content." yet, when I place a GridView and a Button control inside the element, unless the button has a defined OnClick event to do grid1.DataBind();, the grid will NOT refresh its data. Also, I have tried by specifying an AsyncPostBackTrigger on the UpdatePanel for the Button, but again I got the same behaviour. Now, I noticed that the UpdatePanel DOES refresh when I press a Button without OnClick event, however the GridView inside it does not. Please can you shed some light on this? Must I always have that call to code behind to explicitly refresh it?
My connection string in Web.Config
<connectionStrings>
<add name="myConnectionString"
connectionString="Data Source=XXXXX;Initial Catalog=XXXX;Persist Security Info=True;User ID=XXXXX;Password=XXXXX"
providerName="System.Data.SqlClient" />
</connectionStrings>
My Default.aspx
<%# Page Language="C#" AutoEventWireup="true" CodeBehind="Default.aspx.cs" Inherits="EmptyWebApp.Default" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server"> <title></title> </head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager" runat="server" EnablePartialRendering="true" />
<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional">
<ContentTemplate>
<asp:GridView ID="grid1" runat="server" DataSourceID="SQLDevelopment" AutoGenerateColumns="False">
<Columns>
<asp:BoundField DataField="UserID" HeaderText="UserID" SortExpression="UserID" />
<asp:BoundField DataField="Date" HeaderText="Date" SortExpression="Date" />
</Columns>
</asp:GridView>
<asp:SqlDataSource ID="SQLDevelopment" runat="server"
ConnectionString="<%$ ConnectionStrings:myConnectionString %>"
SelectCommand="SELECT * FROM [TestTableA]"></asp:SqlDataSource>
<%=DateTime.Now.ToString()%> <br />
<asp:Button ID="btnRefresh" runat="server" Text="Refresh without C# event"/>
<asp:Button ID="btnRefresh1" runat="server" Text="Refresh with C# event" OnClick="btnRefresh1_Click"/>
</ContentTemplate>
</asp:UpdatePanel>
</div>
</form></body><html>
My Code behind for btnRefresh1
protected void btnRefresh1_Click(object sender, EventArgs e)
{
grid1.DataBind();
}
THANK YOU
There is nothing wrong with update-panel code - issue is that grid-view will not demand the data again from data-source on post-back. Rather, it will use view-state to load the corresponding data.
However, call to DataBind will force grid-view to get the data from data source again thereby refreshing it (or you may try disabling the view-state for grid view) - see documentation for the method - comments within example code says the same.
In case, you do not want to add DataBind call in refresh button, you can do the same in Page_Load - thereby refreshing the grid on every post-back (regardless the control that has caused it).
Use .DataBind() in the script for your gridview (ie gridview1.DataBind();). This is just rebinds the data to the gridview that was already set in your data source.
<asp:GridView ID="grid1" runat="server" DataSourceID="SQLDevelopment" AutoGenerateColumns="False">
See MSDN for more info.
Or allow the ScriptManager to do it all for you in one line of code!
ScriptManager.GetCurrent(this).RegisterPostBackControl(ButtonSubmit);
Replace the ButtonSubmit with your own control.

How to collapse and expand devexpress master/detail asp.net gridview

I have two asp.net devexpress gridviews in master/detail configuration. I expand a master row to display the child rows and do manipulations on the child rows such as edit, add new and delete rows. After that I want the parent gridview to collapse and both the gridviews to refresh with new data. Please let me know how could I do it. On devexpress site I see the mention of CollapseRow and ExpandRow javascript clientside methods. But couldn't find any sample code describing how to call those.
Thanks
First assign clientInstanceName to grid as:
<dx:ASPxGridView ID="ASPxGridView1" runat="server" KeyFieldName="ID"
ClientInstanceName="grid">
When you complete update or delete as you said call grid.CollapseAllDetailRows(); after the operation that you have completed. or on ASPxClientGridView.DetailRowExpanding Event set the expanded detail row visibleindex. check the following code snippet and code as per your requirement.
<html>
<head runat="server">
<title></title>
<script language ="javascript" type ="text/javascript">
var focusedIndex;
</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<dx:ASPxGridView ID="ASPxGridView1" runat="server" KeyFieldName="ID" ClientInstanceName="grid">
<ClientSideEvents DetailRowExpanding="function(s, e) {
focusedIndex = e.visibleIndex;
}" />
<SettingsBehavior AllowFocusedRow="True" AllowSelectByRowClick = "true" />
<SettingsDetail ShowDetailRow="True" />
</dx:ASPxGridView>
<dx:ASPxButton ID="ASPxButton1" runat="server" AutoPostBack="False" Text="ASPxButton">
<ClientSideEvents Click="function(s, e) {
//var visibleindex = grid.GetFocusedRowIndex();
//grid.CollapseAllDetailRows();
if( focusedIndex != 'undefined')
{
grid.CollapseDetailRow(focusedIndex );
}
}"/>
</dx:ASPxButton>
</div>
</form>
</body>
</html>

Resources