Problems making LinkButton visible in certain rows only within a GridView - asp.net

I have set up a GridView as set out below. You can see there are four LinkButton's per row. What I want to do is make certain LinkButtons available depending on which row they appear in.
<asp:GridView ID="FormsGrid" runat="server" Width="657px" Height="250px" DataKeyNames="FORM_NAME,FORM_ACCESS,STATUS,ID"
AutoGenerateColumns="False" DataSourceID="SqlDataSource1" >
<Columns>
<asp:BoundField DataField="DEADLINE_DATE" HeaderText="Date" DataFormatString="{0:d}"
SortExpression="DEADLINE_DATE" />
<asp:BoundField DataField="FORM_NAME" HeaderText="Event"
SortExpression="FORM_NAME" >
<ItemStyle Width="240px" />
</asp:BoundField>
<asp:BoundField DataField="COMPULSORY" HeaderText="Compulsory?"
SortExpression="COMPULSORY" />
<asp:BoundField DataField="FORM_NO" HeaderText="Form"
SortExpression="FORM_NO" />
<asp:TemplateField HeaderText="Access">
<ItemTemplate>
<asp:LinkButton ID="FormLinkBtn" runat="server"
onclick="FormLinkBtn_Click">Form Link</asp:LinkButton>
<br />
<asp:LinkButton ID="NotReqBtn" runat="server"
onclick="NotReqBtn_Click">Not Required</asp:LinkButton>
<br />
<asp:LinkButton ID="DnLoadBtn" runat="server"
onclick="DnLoadBtn_Click">Download Pdf</asp:LinkButton>
<br />
<asp:LinkButton ID="UploadBtn" runat="server"
onclick="UploadBtn_Click">Upload Pdf</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="STATUS" HeaderText="Completed?"
SortExpression="STATUS" />
<asp:BoundField DataField="ID" HeaderText="ID" SortExpression="ID" Visible="False" />
</Columns>
</asp:GridView>
When I try to make them not visible use the code below in FormsGrid_RowDataBound, it doesn't work and a get a null value error.
if e.Row.Cells(4).Text = "1" then
Dim FLbtn As LinkButton = FormsGrid.FindControl("FormLinkBtn")
FLbtn.Visible = True
Dim NRbtn As LinkButton = FormsGrid.FindControl("NotReqBtn")
NRbtn.Visible = False
Dim DLbtn As LinkButton = FormsGrid.FindControl("DnLoadBtn")
DLbtn.Visible = False
Dim ULbtn As LinkButton = FormsGrid.FindControl("UploadBtn")
ULbtn.Visible = False
end if
Also when I click say the FormLinkBtn, how do I determine the value of the fields in that particualr row?

Suggestion #1:
wrap your "if" statement in an "if" that checks for a row type:
if (e.Row.RowType == DataControlRowType.DataRow)
{
......// your code here
}
You getting null value exception becuase first you hit the header row. There are few types of rows.
You are only interested in DataRow in this case.
On question part 2:
if you go with just a link buttons and click events you will need to pass some data in CommandArgument or CommandName properties of the linkButton. You can use CommandField or ButtonField instead to avoid dealing with passing data identifying the row in CommandArgument or CommandName.

Related

Using asp:Button with OnRowDeleting event

I'm trying to connect an asp:Button with my OnRowDeleting event in a gridview, but I don't don't know how to do that :X. I'm currently using CommandField but for my own purposes I need it with a Button instead. Can anyone help me please?
EDIT:
Let me re-explain, I have a row with Delete and Edit buttons in the same CommandField. What I'm trying to do is to hide the 'Delete' button in some specific cases for specific rows only and not necessarily for every row. That's why I'm struggling with a CommandField because there's no ID coming with it so I can't refer to it in my codebehind. But - asp:Button has an ID but I can't manage to link it with the UserAccounts_RowDeleting function. And that's my question - how to link it? :)
EDIT2:
These are part of my codes:
<asp:GridView ID="UserAccounts" runat="server" AutoGenerateColumns="False" HeaderStyle-BackColor="#3AC0F2"
HeaderStyle-ForeColor="White" AutoGenerateDeleteButton="false"
RowStyle-BackColor="#A1DCF2" AlternatingRowStyle-BackColor="White" AutoGenerateEditButton="false"
onrowcancelingedit="UserAccounts_RowCancelingEdit" RowStyle-ForeColor="#3A3A3A" OnRowEditing="UserAccounts_RowEditing"
PageSize="10" AllowPaging="false" onrowdeleting="UserAccounts_RowDeleting"
OnRowUpdating="UserAccounts_RowUpdating" OnRowDataBound="UserAccounts_RowDataBound" onrowcreated="UserAccounts_RowCreated">
<Columns>
<asp:CommandField ShowDeleteButton="true" ShowEditButton='true' ButtonType="Link" />
<asp:BoundField DataField="UserName" HeaderText="Username" ReadOnly="true"/>
<asp:BoundField DataField="Email" HeaderText="Email" />
<asp:CheckBoxField DataField="IsApproved" HeaderText="Approved?" ReadOnly="false"/>
<asp:CheckBoxField DataField="IsLockedOut" HeaderText="Locked Out?" ReadOnly="true"/>
<asp:CheckBoxField DataField="IsOnline" HeaderText="Online?" ReadOnly="true"/>
<asp:BoundField DataField="Comment" HeaderText="Comment" NullDisplayText="N/A"/>
<asp:TemplateField HeaderText="Select" >
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
//Codebehind c#
protected void UserAccounts_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
if (Funcs.GetAdminLevel() >= 999)
{
username = UserAccounts.Rows[e.RowIndex].Cells[1].Text;
if (username.ToLower().Equals(HttpContext.Current.User.Identity.Name.ToLower()))
ActionStatus.Text = string.Format("ERROR: You can't delete your own account ('<font color=#000000><b>{0}</b></font>')!", username);
else if (Funcs.GetAdminLevel(username) >= 1)
ActionStatus.Text = string.Format("ERROR: You can't delete administrators' accounts ('<font color=#000000><b>{0}</b></font>')!", username);
else
{
Roles.RemoveUserFromRoles(username, Roles.GetRolesForUser(username));
Membership.DeleteUser(username);
ActionStatus.Text = string.Format("User '<font color=#000000><b>{0}</b></font>' has been successfully deleted!", username);
BindUserAccounts();
}
}
else
ActionStatus.Text = "You are not authorized to delete user accounts!";
}
I want to change the CommandField to ItemTemplate so I can enable/disable it through the codebehind for specific rows only. Also, I want the ItemTemplate, which would be asp:Button, to use the UserAccounts_RowDeleting event and that's where my problem is, I just don't know how to link the button to the event..
It sounds like you pretty much have the solution already. Use a TemplateField for your button. The key part is to set the CommandName of your button to "Delete". This tells the GridView that it is a delete button and the RowDeleting event should handle it.
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnDelete" runat="server" Text="Delete" CommandName="Delete" />
</ItemTemplate>
</asp:TemplateField>

How do I retrieve data from a hidden column in GridView? VB

I'm kind of stuck here, after doing some research I can't seem to find an answer. Anyway I don't know how can I retrieve the Primary key in my Gridview hidden column.
Here is my gridview
<asp:GridView ID="grdDent" runat="server" AutoGenerateColumns="False" Width="852px" DataKeyNames="app_id">
<Columns>
<asp:TemplateField>
<EditItemTemplate>
<asp:CheckBox ID="chkApp" runat="server" />
</EditItemTemplate>
<ItemTemplate>
<asp:CheckBox ID="chkApp" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="app_id" HeaderText="app_id" Visible="False" />
<asp:BoundField DataField="app_date" HeaderText="Date" SortExpression="Date" />
<asp:BoundField DataField="app_time" HeaderText="Time" SortExpression="Time" />
<asp:BoundField DataField="app_rsn" HeaderText="Reason" SortExpression="Reason" />
<asp:BoundField DataField="app_info" HeaderText="Comment" SortExpression="Comment" />
<asp:BoundField DataField="app_sts" HeaderText="Status" SortExpression="Status" />
<asp:BoundField DataField="Patient" HeaderText="Requested by" SortExpression="Patient" />
<asp:BoundField DataField="app_timestamp" HeaderText="Date requested" SortExpression="Date requested" />
</Columns>
</asp:GridView>
And here is my code at button click
For Each row As GridViewRow In grdDent.Rows
If row.RowType = DataControlRowType.DataRow Then
Dim chkApp As CheckBox = TryCast(row.Cells(0).FindControl("chkApp"), CheckBox)
If chkApp.Checked Then
cmd = New MySqlCommand("UPDATE appointment_table SET app_sts = 'Approved' WHERE app_id = #p1", con)
cmd.Parameters.AddWithValue("#p1", row.Cells(1).Text)
con.Open()
cmd.ExecuteNonQuery()
con.Close()
End If
End If
Next
Here is my code to fill up the gridview
Using cmd = New MySqlCommand("SELECT app_id, app_date, app_time, app_rsn, app_info, app_sts, group_concat(pat_lname, pat_fname) As Patient, app_timestamp FROM appointment_table INNER JOIN patient_table WHERE app_sts = 'Queue'", con)
con.Open()
Dim ds As New DataSet()
Dim a As New MySqlDataAdapter(cmd)
a.Fill(ds)
grdDent.DataSource = ds
grdDent.DataBind()
con.Close()
End Using
The problem now is that whenever I click the button, it would not do anything, not even show an error, so I do not know what to do.
First debug the code and check from which line you are getting the error.
Also try following code.
.HideData
{
display: none;
}
Replace your app_id bound field like as below.
Don't use visible false property.
when you set visible=false that column will not rendered in gridview's html.
so, instead of visible=false make its style='display:none'
use like this :
<asp:BoundField DataField="ItemDesc" HeaderText="app_id" >
<ItemStyle CssClass="hidden"/>
</asp:BoundField>
<style type="text/css">
.hidden
{
display:none;
}
</style>
and use this in your foreach loop
dim appid as string
appid=row.Cells(1).Text
I see that you store the primary key in DataKeyNames="app_id"
so you would grab that in code with
grdDent.DataKeys.Item(a row index here).Value
You can drop the BoundField holding this value. It being "Visible=False" will not hold any value.
The way I do it is like this..
1st remove your boundfield and just add a lable to one of the template fields like this.
<asp:GridView ID="grdDent" runat="server" AutoGenerateColumns="False" Width="852px" DataKeyNames="app_id">
<Columns>
<asp:TemplateField>
<EditItemTemplate>
<asp:CheckBox ID="chkApp" runat="server" />
</EditItemTemplate>
<ItemTemplate>
<asp:CheckBox ID="chkApp" runat="server" />
<asp:Label ID="lblApp_ID" Visible="False" runat="server" Text='<%# Bind("app_id") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="app_date" HeaderText="Date" SortExpression="Date" />
<asp:BoundField DataField="app_time" HeaderText="Time" SortExpression="Time" />
<asp:BoundField DataField="app_rsn" HeaderText="Reason" SortExpression="Reason" />
<asp:BoundField DataField="app_info" HeaderText="Comment" SortExpression="Comment" />
<asp:BoundField DataField="app_sts" HeaderText="Status" SortExpression="Status" />
<asp:BoundField DataField="Patient" HeaderText="Requested by" SortExpression="Patient" />
<asp:BoundField DataField="app_timestamp" HeaderText="Date requested" SortExpression="Date requested" />
</Columns>
</asp:GridView>
by doing this it will put the label in each row but it wont show up to the user and the part that says "Text='<%# Bind("app_id") %>'" that binds the text to that label in each row.
Now for the code on the button click you should use this:
Dim i As Integer = 0
Dim app_ID As Integer '<- I was using an integer but you can use any datatype
For Each row As GridViewRow In grdDent.Rows
If CType(row.FindControl("chkApp"), CheckBox).Checked = True Then
app_ID = CType(grdDent.Rows(i).FindControl("lblApp_ID"), Label).Text
cmd = New MySqlCommand("UPDATE appointment_table SET app_sts = 'Approved' WHERE app_id =" & app_ID , con)
con.Open()
cmd.ExecuteNonQuery()
con.Close()
End If
i += 1
Next
All of this has worked for me, so I hope it works for you!
You can use something like this:
For Each row As GridViewRow In yourgrid.Rows
Dim chk As CheckBox = CType(row.FindControl("chkApp"), CheckBox)
If chk IsNot Nothing And chk.Checked Then
'get your selected row data here and perform update operation
End If
Next row
NOTE: My suggestion is to first debug the code and make sure your code is working fine and method is calling perfectly.
You can check getting asp.net gridview selected row data from server-side to get more details.
Hope it helps you!

How to make check boxes checked on a Grid view when one checkbox of a row is checked?

I have a gridview. Which consisits of two checkbox item templates.
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="False"
CellPadding="4" ForeColor="#333333" GridLines="None"
<Columns>
<asp:BoundField DataField="student_name" HeaderText="Student Name" SortExpression="student_name" >
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundField>
<asp:BoundField DataField="student_id"
HeaderText="Student ID" ItemStyle-HorizontalAlign="Center"
SortExpression="student_id" ReadOnly="True" >
<ItemStyle HorizontalAlign="Center"></ItemStyle>
</asp:BoundField>
<asp:TemplateField HeaderText="Practical Test">
<ItemTemplate>
<asp:CheckBox AutoPostBack="false" Checked="true" Id="CheckBoxTheory" runat="server" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Theory Test">
<ItemTemplate>
<asp:CheckBox AutoPostBack="false" Checked="true" Id="CheckBoxPractical" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
When checking any one of the checkbox of a row of grid view ,i wants to make check the other checkbox automatically..and vice versa.. how is it possible?
On server side you need to change the checkbox so it has AutoPostBack="True" and add a OnCheckedChanged="CheckBoxTheory_Checked" so that the system can postback when you select it.
Then you can use something along the lines of:
Sub CheckBoxTheory_Checked (sender as object, e as eventargs)
Dim CheckBoxTheory as CheckBox = sender
Dim gvRow as GridviewRow = DirectCast(CheckBoxTheory.NamingContainer, GridviewRow)
Dim CheckBoxPractical as CheckBox = gvRow.FindControl("CheckBoxPractical")
If CheckBoxTheory.Checked = True Then
CheckBoxPractical.Checked = True
Else
CheckBoxPractical.Checked = False
End If
End Sub
This would get the sender as the checkbox, get the parent container (or NamingContainer), which would be a GridviewRow and then find the CheckBoxPractical control and then check if against the other checkbox value.
This is a long winded way of doing it but is the simplest at explaining the method.

C# How do I create a Hyperlink OnClick event on GridView?

I'm having trouble creating the GridView I want.
I would like the user to get inside the website and see the GridView which is attached to a DB.
Columns are: ID, InsertionTime, Filepath, ProccessedByUser
Now I want the user to click the filepath he/she would like to process. When he/she clicks the filepath, I want their username (logged in with built-in asp website authentication) to be updated (added) into DB.
My markup is standard and I haven't got to manage with code behind.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" DataSourceID="AccessDataSource1"
onselectedindexchanged="GridView1_SelectedIndexChanged">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False"
ReadOnly="True" SortExpression="ID" />
<asp:BoundField DataField="starttime" HeaderText="starttime"
SortExpression="starttime" />
<asp:HyperLinkField DataNavigateUrlFields="path" DataTextField="path"
HeaderText="path" />
<asp:BoundField DataField="user" HeaderText="user" SortExpression="user" />
</Columns>
</asp:GridView>
I tried using HyperlinkField but it doesn't seem to support onlick events.
Any suggestions?
Thanks.
I assume you are looking for the LinkButton control which has an OnClick event.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataKeyNames="ID" DataSourceID="AccessDataSource1"
onselectedindexchanged="GridView1_SelectedIndexChanged">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" InsertVisible="False"
ReadOnly="True" SortExpression="ID" />
<asp:BoundField DataField="starttime" HeaderText="starttime"
SortExpression="starttime" />
<asp:TemplateField HeaderText="Path" SortExpression="Filepath">
<ItemTemplate>
<asp:LinkButton ID="LbPath" runat="server"
Text='<%# Eval("Filepath") %>'
CommandName="PathUpdate"
CommandArgument='<%#Bind("path") %>'>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="user" HeaderText="user" SortExpression="user" />
</Columns>
</asp:GridView>
Now you can handle the LinkButton's click event or the GridView's RowCommand event.
protected void Gridview1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "PathUpdate")
{
string path= e.CommandArgument.ToString();
// do you what you need to do
}
}
Note that i've used a TemplateField which is the most dynamic column type in a GridView since you can add anything you want, even nested GridViews or UserControls.
You could use a ButtonField, and then handle OnRowCommand of the gridview. Example here:
http://msdn.microsoft.com/SV-SE/library/system.web.ui.webcontrols.buttonfieldbase.buttontype.aspx
You can set the ButtonType attribute of ButtonField to display the button as a Link.

Use LINQ with GridView

I am new to web dev and using controls so please forgive me.
I have a GridView with check boxes in it (please see markup below)
When a user goes through and checks any boxes and hits my submit button
I want to run LINQ query to get all the rows with the checkbox1.checked = True
Something like:
Dim sList = (From row in Gridview1
Where row.Cells("IsStarFleet") = True
row.Cells("ID)).ToList
Markup:
<asp:GridView ID="GridView1" runat="server" Width="516px" AutoGenerateColumns="False" AllowPaging="True">
<Columns>
<asp:BoundField DataField="ID" HeaderText="ID" />
<asp:BoundField DataField="FirstName" HeaderText="FirstName" />
<asp:TemplateField HeaderText="IsStarFleet">
<ItemTemplate>
<asp:CheckBox ID="CheckBox1" runat="server" AutoPostBack ="False" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
You need to use FindControl for controls in a TemplateField and Cells(index) for BoundFields:
Dim checkedIDs = From row In GridView1.Rows.Cast(Of GridViewRow)()
Where DirectCast(row.FindControl("CheckBox1"), CheckBox).Checked
Select row.Cells(0).Text
Dim checkedIdList = checkedIDs.ToList()

Resources