I have a Gridview inside an Ajax UpdatePanel. Inside each GV row I have a checkbox field. The idea is that the user checks the lines they want, and click a button to both update a label in that row as "shipped" and then also export the checked lines to an xls file (csv really).
When my codebehind fires it loops through the gridview rows, looks for the checks, updates the database to mark each line and then I use .DataBind() to refresh the grid. This works perfectly and as expected.
Now I want to also export the checked rows to excel. So I created a method for doing this and popped it in after updating each row for marking the lines and BEFORE the .DataBind() refresh. Now the .DataBind() never fires to refresh. I do receive the XLS download and if I manually refresh the screen, the lines are updated as expected.
Here's my code:
ASPX (Just a portion of the gridview):
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:GridView ID="GridView1" runat="server" AllowSorting="True" AutoGenerateColumns="False"
DataKeyNames="MinqNum" DataSourceID="SqlDataSource1" Font-Size="Small" BorderColor="Black"
BorderStyle="Solid" BorderWidth="1px" CellPadding="0">
<RowStyle Font-Size="Small" HorizontalAlign="Left" VerticalAlign="Bottom" BorderColor="#999999"
BorderStyle="Solid" BorderWidth="1px" Wrap="true" />
<Columns>
<asp:TemplateField>
<ItemStyle CssClass="ItemStyle"/>
<HeaderStyle Wrap="true" Font-Size="X-Small" HorizontalAlign="Center"
VerticalAlign="Bottom" BorderWidth="0px" />
<ItemTemplate>
<asp:ImageButton ID="btn_editss" runat="server" CommandName="Edit" ImageUrl="~/images/edit.gif" />
</ItemTemplate>
<EditItemTemplate>
<asp:ImageButton ID="btn_savess" runat="server" CommandName="Update" ImageUrl="~/images/save.gif" />
<asp:ImageButton ID="btn_cancelss" runat="server" CommandName="Cancel" ImageUrl="~/images/cancel.gif" />
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Date" SortExpression="MinqDate">
<ItemStyle CssClass="ItemStyle" HorizontalAlign="Center" Font-Size="Smaller"/>
<HeaderStyle Wrap="true" Font-Size="X-Small" HorizontalAlign="Center" VerticalAlign="Bottom" BorderWidth="0px"/>
<ItemTemplate>
<asp:Label ID="lbl_minqdate" runat="server" Text='<%#Bind("MinqDate", "{0:MM/dd/yy}") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:Label ID="lbl_minqdate" runat="server" Text='<%#Bind("MinqDate", "{0:MM/dd/yy}") %>'></asp:Label>
</EditItemTemplate>
</asp:TemplateField>
</asp:GridView>
</ContentTemplate>
</asp:UpdatePanel>
Button Click Event (codebehind):
Protected Sub btn_markshipped_clicked(ByVal sender As Object, ByVal e As EventArgs)
For Each row As GridViewRow In GridView1.Rows
If row.RowType = DataControlRowType.DataRow Then
Dim isChecked As Boolean = DirectCast(row.FindControl("cb_supship"), CheckBox).Checked
If isChecked Then
'btn_markshipped.Text = "changed"
Dim cmd As New SqlCommand("UPDATE InquiryV4.dbo.Main SET Sup_Shipped = 'S' WHERE MinqNum = #MinqNum")
cmd.Parameters.AddWithValue("#MinqNum", row.Cells(5).Controls.OfType(Of Label)().FirstOrDefault().Text)
'cmd.Parameters.AddWithValue("#Country", row.Cells(2).Controls.OfType(Of DropDownList)().FirstOrDefault().SelectedItem.Value)
'cmd.Parameters.AddWithValue("#CustomerId", gvCustomers.DataKeys(row.RowIndex).Value)
Me.ExecuteQuery(cmd, "UPDATE")
End If
End If
Next
'btnUpdate.Visible = False
'Me.BindGrid()
btn_exportexcel()
GridView1.DataBind()
End Sub
btn_exportexcel sub (codebehind):
Private Sub btn_exportexcel()
Dim dt = New DataTable()
dt.Columns.Add("MTX PN")
dt.Columns.Add("Inq#")
dt.Columns.Add("Customer")
dt.Columns.Add("Qty")
dt.Columns.Add("Eng")
dt.Columns.Add("A/M")
For Each gvrow As GridViewRow In GridView1.Rows
Dim chk As Boolean = DirectCast(gvrow.FindControl("cb_supship"), CheckBox).Checked
If chk = True Then
Dim i = gvrow.RowIndex
Dim lbl_mtxpn As Label = gvrow.FindControl("lbl_mtxpn")
Dim lbl_inqnum As Label = gvrow.FindControl("lbl_inqnum")
Dim lbl_customer As Label = gvrow.FindControl("lbl_customer")
Dim lbl_SamplesRequested As Label = gvrow.FindControl("lbl_SamplesRequested")
Dim lbl_AssignedTo As Label = gvrow.FindControl("lbl_AssignedTo")
Dim lbl_LTN_Eng As Label = gvrow.FindControl("lbl_LTN_Eng")
Dim lbl_AcctMGR As Label = gvrow.FindControl("lbl_AcctMGR")
Dim dr = dt.NewRow()
dr.Item("MTX PN") = Convert.ToString(lbl_mtxpn.Text)
dr.Item("Inq#") = Convert.ToString(lbl_inqnum.Text)
dr.Item("Customer") = Convert.ToString(lbl_customer.Text)
dr.Item("Qty") = Convert.ToString(lbl_SamplesRequested.Text)
dr.Item("Eng") = Convert.ToString(lbl_LTN_Eng.Text) + "(" + Convert.ToString(lbl_AssignedTo.Text) + ")"
dr.Item("A/M") = Convert.ToString(lbl_AcctMGR.Text)
dt.Rows.Add(dr)
End If
Next
Dim GridView2 = New GridView()
GridView2.DataSource = dt
GridView2.DataBind()
Response.Clear()
Response.Buffer = True
Response.ContentType = "application/ms-excel"
Response.AddHeader("content-disposition", String.Format("attachment;filename={0}.xls", "selectedrows"))
Response.Charset = ""
Dim sw As New StringWriter()
Dim hw As New HtmlTextWriter(sw)
GridView2.RenderControl(hw)
Response.Output.Write(sw.ToString())
Response.End()
End Sub
As I said, without the export function the gridview.databind() works as expected and updates the gridview. As soon as the export function is put inbetween, it blocks the .databind() from happening.
Any ideas? Just for giggles I also tried a response.redirect instead and that has the same issue.
This is happening because you are:
Clearing the response;
Sending the Excel file;
Ending the response.
In other words, the server's reply to your request is to send the excel file. It doesn't send a new batch of HTML to the browser, because you told it to stop after the file was sent. As you have observed, your page doesn't change, because you didn't send your browser any new HTML.
I don't believe it's possible to both send a file AND send new HTML to the browser, but I'm open to being proved wrong. Most cases I've seen of people attempting both these things involve a rebind and page refresh first, and then an Ajax-like GET call to the server to get the Excel file. Other options include opening a new, very small window that just does a GET and returns the Excel file, and then closes after it's sent.
Are you trying to have 2 GridViews or two views of the same data displayed in the same GridView?
Related
I have a drop down list 'Country', 'city' text box and an 'Add' button. The country drop down is NOT mandatory so I can just add a city without a country, adding an empty 'country' to the gridview works OK. the problem when I click on 'Edit' in the gridview it binds it to the first country in the list it does not just show a blank:
<asp:DropDownList ID="DDLCountry" runat="server" AutoPostBack="true" AppendDataBoundItems="true" OnSelectedIndexChanged="DDLCountry_SelectedIndexChanged" InitialValue="">
<asp:ListItem Text="------------------------ Select ------------------------" Value="" />
</asp:DropDownList>
<asp:TextBox ID="txtCity" runat="server"></asp:TextBox>
<asp:Button ID="btnNewLList" runat="server" OnClick="btnNewLList_Click" Text="Add new Country"/>
<asp:GridView ID="gvAddNewCountry" runat="server" AutoGenerateColumns="False" DataKeyNames="ID" OnRowCommand="gvAddNewCountry_RowCommand" OnRowDeleting="gvAddNewCountry_RowDeleting" OnRowDataBound="gvAddNewCountry_RowDataBound" OnRowUpdating="gvAddNewCountry_RowUpdating" OnRowEditing="gvAddNewCountry_RowEditing" OnRowCancelingEdit="gvAddNewCountry_RowCancelingEdit" ShowHeaderWhenEmpty="True">
<EmptyDataTemplate>
No Data
</EmptyDataTemplate>
<Columns>
<asp:TemplateField HeaderText="Actions">
<ItemTemplate>
<asp:Button ID="btnEdit" runat="server" Text="Edit"/>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ButtonType="Button" ShowEditButton="true" ShowCancelButton="true">
</asp:CommandField>
<asp:TemplateField HeaderText="Country>
<ItemTemplate>
<asp:Label ID="lblCountry" runat="server" Text='<% #Eval("Country") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="DDCountry" runat="server" AppendDataBoundItems="True" AutoPostBack="false"></asp:DropDownList>
</EditItemTemplate>
</asp:TemplateField>
Code behind:
Protected Sub gvAddNewCountry_RowCommand(sender As Object, e As GridViewCommandEventArgs)
If e.CommandName = "Edit" Then
Dim rowCountryToEdit As Integer = e.CommandArgument
Dim ddListCountry As DropDownList = (CType(gvAddNewCountry.Rows(CInt(e.CommandArgument)).FindControl("DDCountry"), DropDownList))
ddListCountry.DataSource = (From x In Country Where x.Domain = "lCountry" Order By x.Description Select x).ToList()
ddListCountry.DataTextField = "Description"
ddListCountry.DataValueField = "ID"
ddListCountry.DataBind()
End If
End Sub
Thanks for your help X
Ok, so when you have/want a ddl in a gv row?
We require TWO steps.
First step: Load up the list of choices for the dll
2nd step: set the ddl to the current row value, or blank (no choice) if null no value exists yet for the current row. This ALSO means we have to get/grab the current row value for the dll, and set the ddl to reflect this existing choice.
So, this is a two step process.
And the "event" we typical use for this is the row bind event. (all such controls from listview, gridview and more have this event).
Also, a VERY nice helper tip? During (but ONLY during) the data bind event, you have FULL USE of ALL columns from the data source - EVEN COLUMNS NOT in the gv!!!
I don't have a entity database first setup that you have, but lets load up a gv with a combo box:
So, our gv:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
CssClass="table table-hover" Width="50%"
DataKeyNames="ID">
<Columns>
<asp:BoundField DataField="FirstName" HeaderText="First Name" />
<asp:BoundField DataField="LastName" HeaderText="First Name" />
<asp:BoundField DataField="HotelName" HeaderText="Hotel Name" />
<asp:BoundField DataField="City" HeaderText="City" />
<asp:BoundField DataField="Description" HeaderText="Descripiton" />
<asp:TemplateField HeaderText="Rating">
<ItemTemplate>
<asp:DropDownList ID="cboRating" runat="server"
DataTextField="Rating"
DataValueField="ID">
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And our code to fill is this:
Dim rstRating As New DataTable
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()
' get data for rating combo
rstRating = MyRst("SELECT ID, Rating FROM tblRating ORDER BY ID")
' get data for grid
GridView1.DataSource = MyRst("SELECT * FROM tblHotelsA ORDER BY HotelName")
GridView1.DataBind()
End Sub
Public Function MyRst(strSQL As String) As DataTable
Dim rstData As New DataTable
Using conn As New SqlConnection(My.Settings.TEST4)
Using cmdSQL As New SqlCommand(strSQL, conn)
conn.Open()
rstData.Load(cmdSQL.ExecuteReader)
End Using
End Using
Return rstData
End Function
Note VERY carefull in above, I created a page wide (class wide) data table called rstRating. This will go out of scope after the data bind, but we ONLY need it to persit DURING the gv data bind operating (since for each row of the gv, we don't want to run that query over and over - we need this same pick list for the dll).
Ok, so now we see/get this:
The only part we need is to load up the dll, and set it for each row. We use the RowDataBound event.
So, code for that was this:
Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs) Handles GridView1.RowDataBound
' bind drop down for each row
If e.Row.RowType = DataControlRowType.DataRow Then
' get combo
Dim rDrop As DropDownList = e.Row.FindControl("cboRating")
rDrop.DataSource = rstRating
rDrop.DataBind()
rDrop.Items.Insert(0, New ListItem("Please Select", "0"))
' now get current row value for rating.
Dim gData As DataRowView = e.Row.DataItem
If IsDBNull(gData("Rating")) = False Then
rDrop.Text = gData("Rating")
End If
End If
End Sub
So, for each row, get the dll.
For for that row, load up with choices
And THEN for that row, set the ddl to the current row value (but check for null, and don't set - it will then show our "select" choice value.
I am trying to copy a row from a gridview to be displayed on a new page through a button in one of the columns in the gridview. I have my gridview populated from an Access database that is linked to my project. I have tried several different things, but nothing will display the row information when the project is ran. The current code I am trying from the actual dataview is:
Example 1a
<asp:GridView ID="Grid1" runat="server" Width ="90%" AutoGenerateColumns="false" OnRowDeleting="Grid1_RowDeleting" DataKeyNames="Title">
<Columns>
<asp:BoundField DataField="Title" HeaderText="Title" />
<asp:BoundField DataField="Console" HeaderText="Console" />
<asp:BoundField DataField="Year_Released" HeaderText="Year Released" />
<asp:BoundField DataField="ESRB" HeaderText="ESRB Rating" />
<asp:BoundField DataField="Score" HeaderText="Personal Score" />
<asp:BoundField DataField="Publisher" HeaderText="Publisher" />
<asp:BoundField DataField="Developer" HeaderText="Developer" />
<asp:BoundField DataField="Genre" HeaderText="Genre" />
<asp:BoundField DataField="Purchase" HeaderText="Purchase Date" />
<asp:TemplateField ItemStyle-Width="7%" ShowHeader="False">
<ItemTemplate>
<asp:LinkButton ID="lnkDetails" runat="server" Text="View" PostBackUrl='<%# "~/ViewDetails.aspx?RowIndex=" & Container.DataItemIndex %>'/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
And the codebehind code on the page where I am trying to have the code be displayed is:
Example 1b
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
If Me.Page.PreviousPage IsNot Nothing Then
Dim rowIndex As Integer = Integer.Parse(Request.QueryString("RowIndex"))
Dim GridView1 As GridView = DirectCast(Me.Page.PreviousPage.FindControl("Grid1"), GridView)
Dim row As GridViewRow = GridView1.Rows(rowIndex)
lblTitle.Text = row.Cells(0).Text
lblConsole.Text = row.Cells(1).Text
lblYear.Text = row.Cells(2).Text
lblESRB.Text = row.Cells(3).Text
lblScore.Text = row.Cells(4).Text
lblPublisher.Text = row.Cells(5).Text
lblDeveloper.Text = row.Cells(6).Text
lblGenre.Text = row.Cells(7).Text
lblPurchase.Text = row.Cells(8).Text
End If
End Sub
I have also tried another set of code where the button on the gridview was:
Example 2a
<asp:Button ID="btnLink" runat="server" Text="View Details" PostBackUrl='<%# Eval("Title", "~/ViewDetails.aspx?Id={0}") %>'/>
Where the codebehind code is:
Example 2b
Protected Sub Page_Load(sender As Object, e As EventArgs)
If Not IsPostBack Then
Dim GameTitle As String = Request.QueryString("Id")
Dim connString As String = "PROVIDER=Microsoft.ACE.OLEDB.12.0;" + "DATA SOURCE=" + Path.Combine(AppDomain.CurrentDomain.BaseDirectory + "App_Data" + "db1.accdb")
Using connection As New OleDbConnection(connString)
connection.Open()
Dim reader As OleDbDataReader = Nothing
Dim command As New OleDbCommand((Convert.ToString("SELECT * from [Video_Games] WHERE Title='") & GameTitle) + "'", connection)
reader = command.ExecuteReader()
While reader.Read()
lblTitle.Text = reader(0).ToString()
lblConsole.Text = reader(1).ToString()
lblYear.Text = reader(2).ToString()
lblESRB.Text = reader(3).ToString()
lblScore.Text = reader(4).ToString()
lblPublisher.Text = reader(5).ToString()
lblDeveloper.Text = reader(6).ToString()
lblGenre.Text = reader(7).ToString()
lblPurchase.Text = Convert.ToDateTime(reader(8).ToString()).ToShortDateString()
End While
End Using
End If
End Sub
End Class
I have tried making variations of both, mainly the second, but whatever I try the labels are not populated with the row information. Any assistance would be appreciated, and I can post any other code needed, like how I populated the gridview. Thank you.
It was as simple as changing the AutoEventWireup to "true" in my .aspx file.
I am trying to simply change the background color of a row in a GridView based on the value in one of the GridView cells. I have two functions. The first one hits my database and creates a DataTable from the database data. The DataTable is then used as the datasource for my GridView. Here is the code:
Protected Sub FillMipDataGridOnReqNoSearch()
Dim ReqNumber As String = Me.txtReqNo.Text
Try
Dim DbConnection As New DevConnection()
Dim Da As New SqlDataAdapter()
Using DbConnection.Conn
DbConnection.Conn.Open()
Using SqlCmd As New SqlCommand()
With SqlCmd
.Connection = DbConnection.Conn
.CommandType = CommandType.StoredProcedure
.CommandText = "MyStoredProcedure"
.Parameters.AddWithValue("#RequestNumber", SqlDbType.NVarChar).Value = ReqNumber End With
Using Da
Da.SelectCommand = SqlCmd
Using Dt As New DataTable()
Da.Fill(Dt) 'populates the dataset
Gv_MipData.DataSource = Dt
Gv_MipData.DataBind()
'the following three lines pass the cell indeces for each dateTime cell that needs to be formatted
ShortenDateTimeStrings(4) 'date from cell
ShortenDateTimeStrings(5) 'date to cell
ShortenDateTimeStrings(11) 'date submitted cell
End Using
End Using
End Using
End Using
Catch ex As Exception
End Try
End Sub
The second function is the GridView's RowDataBound event handler. Here is the code:
Protected Sub Gv_MipData_DataBound(sender As Object, e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles Gv_MipData.DataBound
If e.Row.RowType = DataControlRowType.DataRow Then
Dim ApprovalStatus As String = e.Row.Cells(9).Text
If ApprovalStatus = "D" Then
e.Row.BackColor = Drawing.Color.Red
End If
End If
End Sub
The above code breaks in the FillMipDataGridOnReqNoSearch() function on the Gv_MipData.DataBind() line. It catches this exception:
Unable to cast object of type 'System.EventArgs' to type
'System.Web.UI.WebControls.GridViewRowEventArgs'.
I tried changing the parameter e in the RowDataBound event handler to the type EventArgs, but it threw this error:
'Row' is not a member of 'System.EventArgs'.
I know I've gotten off-track somewhere. Any suggestions?
Update: The Markup for the GridView
<asp:GridView ID="Gv_MipData" AllowSorting="true" runat="server" CssClass="GridViewStyle"
PageSize="30" Width="100%" AllowPaging="true" OnRowCommand="Gv_MipData_RowCommand">
<RowStyle CssClass="RowStyle" />
<EmptyDataRowStyle CssClass="EmptyRowStyle" />
<PagerSettings Position="TopAndBottom" />
<PagerStyle CssClass="PagerStyle" />
<SelectedRowStyle CssClass="SelectedRowStyle" />
<HeaderStyle CssClass="HeaderStyle" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="GvBtnApprove" runat="server" CausesValidation="False" Style='display: block;
width: 100px;' CommandName="Approve" CssClass="buttonlggrid" Text="Approve">
</asp:LinkButton>
<asp:LinkButton ID="GvBtnDeny" runat="server" CausesValidation="False" Style='display: block;
width: 100px;' CommandName="Deny" CommandArgument="<%#Container.DataItemIndex %>"
CssClass="buttonlggrid" Text="Deny">
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
I have web application created with VB Visual Studio 2008. I have a created a new page to display a grid view showing contracts from a database with a certain status. In the grid view i have an item template field with a link button. The default text for the link button is Add.
When the button is clicked, i would like to add the id number of the contract from the db to a list of integers. If the contract id is present on the list, the text of the button should read as 'Remove' and it should then be removed from the list. if it is not present in the list, the text of the button should read as 'add' and it should be added to the list. In the click event for the button, i have the code to achieve this.
The page loads fine and displays the items in the grid view, however when i click the add button it was generating a null exception error pointing to my casting the link button. I then put the grid view in an update panel, and i no longer get the null exception error but now nothing happens.
here is aspx code & vb code for the grid view. the null error was firing on the line with Dim btnT As New LinkButton and the next line with btnT = CType(sender, LinkButton). Any assistance will be greatly appreciated, the strange thing is have very similar code (i practically duplicated the code) in a vb asp.net web site, and it works fine.
<td align="center">
<div class="style82">
Contract Queue
</div>
<hr />
<div class = "queue">
<div class="status">
<asp:Label ID="lblMessage" runat="server"></asp:Label>
</div>
<div>
<asp:UpdatePanel ID="MainUpdate" runat="server">
<ContentTemplate>
<div>
<asp:GridView ID="grdvContract" runat="server" AllowPaging="True"
AllowSorting="True" AutoGenerateColumns="False" BackColor="White"
BorderColor="Black" BorderStyle="Solid" BorderWidth="1px" CellPadding="4"
Font-Names="Arial" Font-Size="Small"
ForeColor="Black" GridLines="Vertical" PageSize="25" Width="100%"
OnRowDataBound="grdvContract_RowDataBound">
<FooterStyle BackColor="#333300" BorderColor="#FF5050" BorderStyle="Solid"
ForeColor="#FF9900" />
<RowStyle BackColor="#F7F7DE" />
<Columns>
<asp:BoundField DataField="dealno" HeaderText="Deal No" SortExpression="dealno" />
<asp:BoundField DataField="Type" HeaderText="Type" SortExpression="Type" />
<asp:BoundField DataField="Currency" HeaderText="Currency"
SortExpression="Currency" />
<asp:BoundField DataField="Amount" HeaderText="Amount"
DataFormatString="{0:#,###,###.00}" SortExpression="Amount" HtmlEncode="false" />
<asp:BoundField DataField="Status" HeaderText="Status"
SortExpression="Status" />
<asp:HyperLinkField DataNavigateUrlFields="dealno" Text='<img src="graphics/txt.gif" border="0" />'
DataNavigateUrlFormatString="deal_ticket_standard.aspx?id={0}"
HeaderStyle-HorizontalAlign="Left"
HeaderText="Standard View" ItemStyle-HorizontalAlign="Left" Target="javascript:window.open ('deal_ticket_standard.aspx?id={0}', 'win', 'height=400,width=400,location=no,menubar=no,resizable,scrollbars,status=no,toolbar=no');">
<HeaderStyle Width="50" />
<ItemStyle HorizontalAlign="Left"/>
</asp:HyperLinkField>
<asp:BoundField DataField="rate" HeaderText="Rate" ReadOnly="True" SortExpression="rate"/>
<asp:BoundField DataField="cDate" HeaderText="Contract Date" ReadOnly="True" SortExpression="cDate" />
<asp:TemplateField HeaderText = "Action" >
<ItemTemplate>
<asp:LinkButton ID="btnAction" runat="server" Text = "Add" AutoPostBack = "False"
OnClick = "btnAction_Click" CausesValidation="False"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<PagerStyle BackColor="#F7F7DE" ForeColor="Black" HorizontalAlign="Right" />
<SelectedRowStyle BackColor="#CE5D5A" Font-Bold="True" ForeColor="White" />
<HeaderStyle BackColor="#6B696B" Font-Bold="True" ForeColor="White" />
<AlternatingRowStyle BackColor="White" />
</asp:GridView>
</div>
<div id="ActionStatus" runat="server" visible="false" class="status">
** <asp:Literal ID="ltActionSuccess" runat="server"></asp:Literal> **
</div>
<div>
<br />
Total Deals to be included in this file: <asp:Label ID="lblTotal" class="total" runat="server"></asp:Label>
<br />
</div>
</ContentTemplate>
</asp:UpdatePanel>
<asp:UpdateProgress ID="MainUpdateProgress" runat="server" AssociatedUpdatePanelID="MainUpdate">
<ProgressTemplate>
<div >
Please wait, loading updated content...
</div>
</ProgressTemplate>
</asp:UpdateProgress>
</div>
</div>
</td>...
Imports System.Data
Partial Public Class contract_queue
Inherits System.Web.UI.Page
Private _DealList As List(Of Integer)
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack Then
DealList = New List(Of Integer)
FillContractQueue()
End If
End Sub
Public Property DealList() As List(Of Integer)
Get
Return _DealList
End Get
Set(ByVal value As List(Of Integer))
_DealList = value
End Set
End Property
Protected Sub grdvContract_RowDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.GridViewRowEventArgs) Handles grdvContract.RowDataBound
Dim grid_row As GridViewRow
grid_row = e.Row
If e.Row.RowType = DataControlRowType.DataRow Then
Dim deal_no As Integer = CInt(DataBinder.Eval(grid_row.DataItem, "dealno"))
Dim btnR As LinkButton = grid_row.FindControl("btnAction")
btnR.Attributes.Add("dealid", deal_no)
'If DealList.Contains(dealno) Then
' btnR.Text = "Remove"
'Else
' btnR.Text = "Add"
'End If
End If
End Sub
Protected Sub btnAction_Click(ByVal sender As Object, ByVal e As System.EventArgs)
Me.ActionStatus.Visible = True
Me.ltActionSuccess.Text = "Test"
Dim total As Integer = 0
total = DealList.Count
Me.lblTotal.Text = total
Dim btnT As New LinkButton
btnT = CType(sender, LinkButton)
Dim deal_id As Integer = btnT.Attributes("dealid")
If DealList.Contains(deal_id) Then
DealList.Remove(deal_id)
btnT.Text = "Add"
total = DealList.Count
Me.ltActionSuccess.Text = "Deal " & deal_id & " added to file"
Me.lblTotal.Text = total
Else
DealList.Add(deal_id)
total = DealList.Count
btnT.Text = "Remove"
Me.ltActionSuccess.Text = "Deal " & deal_id & " removed from file"
Me.lblTotal.Text = total
End If
End Sub
Protected Sub FillContractQueue()
Dim ContractDeals As New DataSet()
'set up db connection'
Dim strConnect As String = ConfigurationManager.ConnectionStrings("ibl_treasuryConnectionString").ConnectionString
Dim objConnection As New System.Data.SqlClient.SqlConnection(strConnect)
Dim strQuery As String
strQuery = "SELECT convert(varchar, t_deal_register.contractdate, 106) AS cDate, t_deal_register.id AS dealno, t_deal_type.dealtype AS Type, t_client.client_name AS Client, t_dealer_ibl.dealer_ibl + '/' + t_dealer_client.dealer_client AS Dealers, t_deal_register.amount AS Amount, t_deal_register.fxrate AS rate, t_status.Status, t_currency.currency + '/' + t_currency_1.currency AS Currency FROM t_deal_register INNER JOIN t_deal_type ON t_deal_register.dealtype = t_deal_type.id INNER JOIN t_client ON t_deal_register.clientname = t_client.id INNER JOIN t_dealer_ibl ON t_deal_register.dealer_ibl = t_dealer_ibl.id INNER JOIN t_dealer_client ON t_deal_register.dealer_client = t_dealer_client.id INNER JOIN t_currency ON t_deal_register.currency = t_currency.id INNER JOIN t_status ON t_deal_register.status = t_status.id INNER JOIN t_currency AS t_currency_1 ON t_deal_register.pay_currency = t_currency_1.id where t_deal_register.status = '14' ORDER BY t_deal_register.id DESC"
Dim objCommand As New System.Data.SqlClient.SqlCommand(strQuery, objConnection)
objConnection.Open()
Try
Dim DealAdapter As New System.Data.SqlClient.SqlDataAdapter(objCommand)
DealAdapter.Fill(ContractDeals)
Catch ex As Exception
Me.lblMessage.Text = ex.Message
Finally
objConnection.Close()
If ContractDeals.Tables.Count > 0 Then
grdvContract.DataSource = ContractDeals
grdvContract.DataBind()
End If
End Try
End Sub
End Class
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lnkButtonID" runat="server"
OnClick="lnkButton_Click" Text='<%#DataBinder.GetPropertyValue(Container.DataItem, "ID")%>'
name = '<%#DataBinder.GetPropertyValue(Container.DataItem, "Name")%>'
address = '<%#DataBinder.GetPropertyValue(Container.DataItem, "address")%>'
description = '<%#DataBinder.GetPropertyValue(Container.DataItem, "Description")%>'
></asp:LinkButton>
</ItemTemplate>
I currently have a GridView with two buttons that I have added using the following code;
<asp:GridView ID="gvResults" AutoGenerateColumns="False" runat="server" Font-Size="small"
DataKeyNames="BeachHutID" OnRowDataBound="gvResults_RowDataBound" CssClass="BBCSearch">
<Columns>
<asp:BoundField DataField="BeachHutID" SortExpression="BeachHutID" Visible="false">
</asp:BoundField>
<asp:ImageField DataImageUrlField="HutImage" ItemStyle-Width="1%" ReadOnly="true" />
<asp:BoundField HeaderText="Facilities" DataField="Facilities" Visible="false"></asp:BoundField>
<asp:BoundField HeaderText="Info" DataField="Info" Visible="false"></asp:BoundField>
<asp:TemplateField>
<ItemTemplate>
<asp:PlaceHolder ID="lblHolder" runat="server"></asp:PlaceHolder>
<br />
<asp:PlaceHolder ID="imgHolder" runat="server"></asp:PlaceHolder>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnHire" CommandArgument='<%# Eval("BeachHutID") %>' runat="server"
Text="Hire Beach Hut" OnClick="Hire_Click" />
<asp:Button ID="ButtonLogin" CommandArgument='<%# Eval("BeachHutID") %>' runat="server"
Text="Login to Hire Beach Hut" OnClick="Login_Redirect" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
What I want to happen is if the user is logged in, the btnHire button should be enabled and showing and if they're not logged in, ButtonLoggedIn is showing and btnHire is hidden. This is the code I have at the moment;
Public Sub PopulateGrid()
Dim AvailableHuts As New DataTable
AvailableHuts = GetData()
gvResults.DataSource = AvailableHuts
gvResults.DataBind()
gvResults.Enabled = True
'If statement controlling the enabling and disabling of the Beach Hut booking button
If Session("LoginID") = "" Then
For Each rowItem As GridViewRow In gvResults.Rows
rowItem.Cells(5).Enabled = True
Next
End If
lblCaption.Text = "Your search returned " + CStr(AvailableHuts.Rows.Count) + " results"
End Sub
At the moment both buttons are enabled at all times and I'm not sure what I need to add/changed to get the desired result.
From the answer posted by #Andrei, I have added the following to to this Sub;
Protected Sub gvResults_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs) Handles gvResults.RowDataBound
Dim URL(), Text() As String
Dim img As Image
Dim lbl As Label
Dim FacilitiesImg As PlaceHolder = e.Row.FindControl("imgHolder")
Dim Infolbl As PlaceHolder = e.Row.FindControl("lblHolder")
'Added Code from answer
Dim hireBtn As Button = CType(e.Row.FindControl("btnHire"), Button)
hireBtn.Visible = Not String.IsNullOrEmpty(Session("LoginID"))
'Added Code from answer
Dim LoginBtn As Button = CType(e.Row.FindControl("ButtonLogin"), Button)
LoginBtn.Visible = String.IsNullOrEmpty(Session("LoginID"))
If e.Row.RowType = DataControlRowType.DataRow Then
URL = e.Row.DataItem(3).Split(",")
Text = e.Row.DataItem(2).Split(",")
'Add the Facilities Images to the grid Row
For Each item In URL
If item.ToString <> "" Then
img = New Image
img.ImageUrl = item.ToString
FacilitiesImg.Controls.Add(img)
End If
Next
'Add the information to the grid row
'convert # into a carriage return and * into £
For Each item In Text
If item.ToString <> "" Then
lbl = New Label
lbl.Text = Replace(Replace(item.ToString, "#", "<br />"), "*", "£")
Infolbl.Controls.Add(lbl)
End If
Next
End If
End Sub
However I'm receiving the following error when trying to run the program;
Cannot refer to an instance member of a class from within a shared method or shared member initializer without an explicit instance of the class
Any assistance would be much appreciated.
Thanks
Not sure how is your authentication implemented, but let's assume you use HttpContext.Current.Request.IsAuthenticated. Then you can just manipulate Visible property of the buttons in code behind:
btnHire.Visible = HttpContext.Current.Request.IsAuthenticated
ButtonLoggedIn.Visible = Not HttpContext.Current.Request.IsAuthenticated
Update.
Sorry, somehow missed from the post the fact that you seems to be using Session("LoginID") to decide if the use is logged in. The you can do this:
btnHire.Visible = Not String.IsNullOrEmpty(Session("LoginID"))
ButtonLoggedIn.Visible = String.IsNullOrEmpty(Session("LoginID"))
Update 2.
As it turns out, buttons are a part of GridView row. As they are inside the template, you cannot really reach them in the code behind. So you can take two options.
First, you can subscribe to RowDataBound event (which you already did), and inside it do FindControl in the current row to find the necessary button:
Sub gvResults_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
...
Button hireBtn = CType(e.Row.FindControl("btnHire"), Button);
hireBtn.Visible = Not String.IsNullOrEmpty(Session("LoginID"))
and likewise for the second button.
Second, you can try doing it in the markup:
<asp:Button ID="btnHire" CommandArgument='<%# Eval("BeachHutID") %>'
runat="server" Text="Hire Beach Hut" OnClick="Hire_Click"
Visible=<%# String.IsNullOrEmpty(Session("LoginID")) %> />
try
<asp:Button ID="btnHire" CommandArgument='<%# Eval("BeachHutID") %>' runat="server" Visible='<%# islogin()?true:false %>' Text="Hire Beach Hut" OnClick="Hire_Click" />
<asp:Button ID="ButtonLoggedIn" CommandArgument='<%# Eval("BeachHutID") %>' runat="server" Visible='<%# islogin()?false:true %>' Text="Login to Hire Beach Hut" OnClick="Login_Redirect" />
paste this code to aspx.cs page:
Public Shared Function isLogin() As Boolean
Dim stat As Boolean = False
Try
If Session("LoginID") IsNot Nothing AndAlso Session("LoginID") <> "" Then
stat = True
End If
Catch e1 As Exception
stat = False
End Try
Return stat
End Function
Edit2:
Visible='<%# islogin()?false:true %> this means if isLogin() return true then Visible property set to false else it's visible property set to true.