Sorting gridview - can't find column - asp.net

Relative newbie here. Discovered that I have to write an event handler to handle sorting of my data from an objectdatasource. Found a lot of references to code like what's below, but when the code runs I get the message "Cannot find column xxx" where xxx is the name of the column I'm trying to sort on.
I've verified that e.SortExpression is returning the proper column name, but the problem appears to be in the 2nd line below, where I try to create a datatable (dt) from the GridView1.Datasource. The value of dt after this statement is 'nothing', so the rest of the code fails.
Also, I'm listing most of the gridview definition in case that's helpful.
Protected Sub GridView1_Sorting(sender As Object, e As GridViewSortEventArgs) Handles GridView1.Sorting
Dim dt As Data.DataTable = New Data.DataTable(GridView1.DataSource)
If Not dt Is Nothing Then
dt.DefaultView.Sort = e.SortExpression
GridView1.DataSource = dt
GridView1.DataBind()
End If
End Sub
ASPX snippet:
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
DataSourceID="ObjectDataSource1" CellPadding="4"
EmptyDataText="No records found for your search" ForeColor="#333333"
GridLines="None" Width="930px" BorderColor="#CCCCCC" Font-Size="12px" AllowSorting="True">
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<Columns>
<asp:BoundField DataField="CustName" HeaderText="CustName"
SortExpression="CustName" />
<asp:BoundField DataField="CustType" HeaderText="CustType"
SortExpression="CustType" HeaderStyle-HorizontalAlign="Center" ItemStyle-HorizontalAlign="Center" />
<asp:TemplateField HeaderText="Address" SortExpression="Addr1">
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("Addr1") %>'></asp:Label>
</ItemTemplate>
<EditItemTemplate>
<asp:TextBox ID="TextBox1" runat="server" Text='<%# Bind("Addr1") %>'></asp:TextBox>
</EditItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Phone" HeaderText="Phone" SortExpression="Phone" />
<asp:BoundField DataField="ContactName" HeaderText="ContactName"
SortExpression="ContactName" />
<asp:BoundField DataField="LastContactDate" HeaderText="LastContact" SortExpression="LastContactDate" dataformatstring="{0:d}" />
<asp:BoundField DataField="CustSince" HeaderText="CustSince"
SortExpression="CustSince" dataformatstring="{0:MM/dd/yyyy}" />
<asp:BoundField DataField="Status" HeaderText="Status"
SortExpression="Status" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center" />
<asp:BoundField DataField="Source" HeaderText="Source"
SortExpression="Source" />
<asp:BoundField DataField="RelMgr" HeaderText="RelMgr"
SortExpression="RelMgr" />
<asp:TemplateField HeaderText="RelMgrInfo">
<ItemTemplate>
<asp:HyperLink ID="RelMgrEmailLink" runat="server" NavigateUrl='<%#Eval("RelMgrEmail", "mailto:{0}")%>' Text='<%# Eval("RelMgrEmail") + "<br>" + Eval("RelMgrPhone")%> '> </asp:HyperLink>
</ItemTemplate>
</asp:TemplateField>
</Columns>
Thanks!

You don't have to handle the sorting event if you work with the ObjectDataSource. Instead, set the SortParameterName to a string (like "OrderBy") and augment your business method signature that ObjectDataSource uses to retrieve data with this parameter:
public IEnumerable<Whatever> Retrieve( string OrderBy, ... other arguments ) ...
The grid will pass the parameter value to the ODS and then ODS will pass it to your method.

Related

Need to fill Gridview checkbox attribute from a cell data or database data

Hi guys,
I am not a developer but I always try my best to manage my page coding by myself before bothering anyone and by checking many examples and apply them to my web application, but this time I really surrendered and had to ask.
I have a Gridview where I will be using to update one field which is CHECKBOX.
The gridview has a checkbox control where it's checked attribute need to be True or False based on the Database value.
Values are 1 and 2 only
I wrote the below code to catch the cell label and change the checkbox attribute but it didn't work
Protected Sub Refill_checkbox(ByVal sender As Object, ByVal e As System.EventArgs)
Dim i As Integer
For i = 0 To dg.Rows.Count - 1
Dim Test As String = CType(dg.Rows(i).Cells(3).FindControl("Att_Type"), Label).Text
If CType(dg.Rows(i).Cells(4).FindControl("Att_Type"), Label).Text = 1 Then
CType(dg.Rows(i).Cells(6).FindControl("CheckBox_Attendance"), CheckBox).Checked = True
Else
CType(dg.Rows(i).Cells(6).FindControl("CheckBox_Attendance"), CheckBox).Checked = False
End If
Response.Write(Test)
Next
End Sub
Unfortunately it even did not write the Test Variable to find if it catches the label from the gridview or not.
My Gridview is as following:
<asp:GridView ID="dg" runat="server" BorderColor="#CCCCCC" BorderStyle="None" AutoGenerateColumns="False"
BorderWidth="1px" CellPadding="4"
EnableModelValidation="True" ForeColor="Black" GridLines="Horizontal"
Width="99%" AllowPaging="True" PageSize="500" DataSourceID="SqlDataSource_BCS" >
<Columns>
<asp:TemplateField HeaderText="#">
<ItemTemplate>
<%#Container.DataItemIndex + 1 %>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Att_ID" HeaderText="Att_ID"
SortExpression="Att_ID" />
<asp:BoundField DataField="Emp_FullName" HeaderText="Emp_FullName"
SortExpression="Emp_FullName" />
<asp:BoundField DataField="Att_Desc" HeaderText="Att_Desc"
SortExpression="Att_Desc" />
<asp:BoundField DataField="Att_Type" HeaderText="Att_Type"
SortExpression="Att_Type" />
<asp:BoundField DataField="Att_Date" HeaderText="Att_Date"
SortExpression="Att_Date" />
<asp:templatefield HeaderText="Attendance" >
<itemtemplate >
<asp:CheckBox ID="CheckBox_Attendance" runat="server" />
</itemtemplate>
<itemstyle horizontalalign="left" />
</asp:templatefield>
</Columns>
<FooterStyle BackColor="#CCCC99" ForeColor="Black" />
<HeaderStyle BackColor="White" Font-Bold="True" BorderWidth="0px"/>
<PagerStyle BackColor="White" ForeColor="Black" HorizontalAlign="Right" />
<RowStyle BorderStyle="None" />
<SelectedRowStyle BackColor="#CC3333" Font-Bold="True" ForeColor="White" />
</asp:GridView>
I have no idea what is the correct way to do this.
Thanks in advance
You can bind your checkbox directly to the field like so...
<asp:CheckBox ID="CheckBox_Attendance" runat="server" Checked='<%# Eval("Att_type").ToString() = "1" %>' />
Otherwise, handle it directly on your gridview rowdatabound event:
Put the following on your gridview:
<asp:GridView ... OnRowDatabound="dg_RowDataBound">
Change your TemplateField to look like this:
<asp:TemplateField HeaderText="Attendance">
<ItemTemplate>
<asp:HiddenField id="hfType" Value='<%# Eval("Att_Type") %>' />
<asp:CheckBox ID="CheckBox_Attendance" runat="server" />
</ItemTemplate>
<ItemStyle HorizontalAlign="left" />
</asp:TemplateField>
In your code behind
Protected Sub dg_RowDataBound(sender As Object, e As GridViewRowEventArgs)
Dim cbAttendance As Checkbox = e.Row.FindControl("CheckBox_Attendance")
Dim hfType as Hiddenfield = e.Row.FindControl("hfType")
If hfType.Value = "1" Then
cbAttendance.Checked = True
End Sub

Accessing TemplateField controls value of gridview inside button click handler in asp.net

After clicking the edit linkbutton of my gridview, I show the data on different text boxes which are not inside the gridview. I have a "Reset" button which i want to use to get back to the original values. But I am having problem to access those gridview data inside the button click handler and reset it.I tried using DirectCast() but its showing System.NullReferenceException.
<asp:GridView ID="GridView3" runat="server" AutoGenerateColumns="False" DataKeyNames="id">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="lblEdit" runat="server" CausesValidation="false" CommandName="editRecord" Text="EDIT" CommandArgument="<%# Container.DataItemIndex %>"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="id" InsertVisible="False" SortExpression="id" Visible="False">
<ItemTemplate>
<asp:Label ID="lblRecordID" runat="server" Text='<%# Bind("id") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="HANGER">
<ItemTemplate>
<asp:Label ID="lblHANGER" runat="server" Text='<%# Bind("HANGER") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns></asp:GridView>
The backend vb.net code is-
Protected Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnReset.Click
Dim vID As Label = DirectCast(GridView3.SelectedRow.FindControl("lblRecordID"), Label)
Dim vHanger As Label = DirectCast(GridView3.SelectedRow.FindControl("lblRecordID"), Label)
txtID.Text.Text = vID.Text()
ddlHanger.SelectedValue = vHanger.Text 'dropdown list that's why selectedValue used
End Sub
I have copied the portion of the code cause the gridview has lot more rows. I would appreciate if anyone please show me a solution.Thanks in advance.
First remove the following:
<ItemTemplate>
<asp:LinkButton ID="lblEdit" runat="server" CausesValidation="false"
CommandName="editRecord" Text="EDIT"
CommandArgument="<%# Container.DataItemIndex %>"></asp:LinkButton>
</ItemTemplate>
And add:
<asp:CommandField ButtonType="Button" ShowSelectButton="True" SelectText="EDIT" />
That markup will allow your GridView to have an EDIT button which will switch the current selected row index correctly. System.NullReferenceException error you are recieving could be because the GridView3.SelectedRow is NULL/EMPTY, which also means GridView3 currently has NO selected index.
To make sure that GrieView3 indeed selected a ROW, you can add: the following right AFTER the
<SelectedRowStyle BackColor="Black" BorderColor="White" BorderStyle="Dotted"
BorderWidth="3px" ForeColor="White" />
right after
</Columns>
So your final GridView3 markup should look like:
<asp:GridView ID="GridView3" runat="server" AutoGenerateColumns="False" DataKeyNames="id">
<Columns>
<asp:CommandField ButtonType="Button" ShowSelectButton="True"
SelectText="EDIT" />
<asp:TemplateField HeaderText="id" InsertVisible="False" SortExpression="id" Visible="False">
<ItemTemplate>
<asp:Label ID="lblRecordID" runat="server" Text='<%# Bind("id") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="HANGER">
<ItemTemplate>
<asp:Label ID="lblHANGER" runat="server" Text='<%# Bind("HANGER") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<SelectedRowStyle BackColor="Black" BorderColor="White" BorderStyle="Dotted"
BorderWidth="3px" ForeColor="White" />
</asp:GridView>
Then you can also use TryCast too, like so:
Protected Sub btnClear_Click(sender As Object, e As EventArgs) Handles btnReset.Click
Dim vID As String = TryCast(GridView3.SelectedRow.FindControl("lblRecordID"), Label).Text
Dim vHanger As String = TryCast(GridView3.SelectedRow.FindControl("lblRecordID"), Label).Text
txtID.Text.Text = vID
ddlHanger.SelectedValue = vHanger
End Sub

Set Current Date to TemplateField of a DetailView

I'm using a DetailView to insert data into a GridView via an sqlDataSource. I'm attempting to set one of the fields of the DetailView to the current date/time on Page Load so the user does not have to enter the date/time. I get no errors - however, the "Update Date" field of the DetailView fails to display the current date/time.
This is my hypertext:
<asp:DetailsView
id="dtlShipModes"
DataSourceID="SqlDataSource1"
AutoGenerateRows="False"
DefaultMode="Insert"
Runat="server" BackColor="White" BorderColor="White" BorderStyle="Ridge"
BorderWidth="2px" CellPadding="3" CellSpacing="1" GridLines="None">
<EditRowStyle BackColor="#9471DE" Font-Bold="True" ForeColor="White" />
<Fields>
<asp:BoundField
DataField="ShipMode"
HeaderText="Ship Mode:" />
<asp:CheckBoxField
DataField="Active"
HeaderText="Active:" />
<asp:TemplateField HeaderText="Update Date:">
<EditItemTemplate>
<asp:TextBox ID="txtUpdateDate" runat="server" Text='<%# Bind("UpdateDate") %>'></asp:TextBox>
</EditItemTemplate>
<InsertItemTemplate>
<asp:TextBox ID="txtUpdateDate" runat="server" Text='<%# Bind("UpdateDate") %>'></asp:TextBox>
</InsertItemTemplate>
<ItemTemplate>
<asp:Label ID="Label1" runat="server" Text='<%# Bind("UpdateDate") %>'></asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField
DataField="UpdateBY"
HeaderText="Update BY:" />
<asp:CommandField ShowInsertButton="true" InsertText="Add" />
</Fields>
<FooterStyle BackColor="#C6C3C6" ForeColor="Black" />
<HeaderStyle BackColor="#4A3C8C" Font-Bold="True" ForeColor="#E7E7FF" />
<PagerStyle BackColor="#C6C3C6" ForeColor="Black" HorizontalAlign="Right" />
<RowStyle BackColor="#DEDFDE" ForeColor="Black" />
</asp:DetailsView>
This is the code behind:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim txtupdatedby As String = DirectCast(dtlShipModes.FindControl("txtUpdateDate"), TextBox).Text
txtupdatedby = DateTime.Now.ToString
End Sub
Could I get some help please as to what I'm doing wrong?
To expand a little on Mych's answer, you would want to handle the ItemCreated event of the DetailsView:
<asp:DetailsView
id="dtlShipModes"
DataSourceID="SqlDataSource1"
AutoGenerateRows="False"
DefaultMode="Insert"
ItemCreated="dtlShipModes_ItemCreated"
Runat="server" BackColor="White" BorderColor="White" BorderStyle="Ridge"
BorderWidth="2px" CellPadding="3" CellSpacing="1" GridLines="None">
And then write the event handler like this:
protected void dtlShipModes_ItemCreated(Object sender, EventArgs e)
{
Dim txtupdatedby As TextBox = DirectCast(dtlShipModes.FindControl("txtUpdateDate"), TextBox)
txtupdatedby.Text = DateTime.Now.ToString
}
Notice that I changed your implementation a little, to use a reference to the TextBox, rather than the string.
This is all necessary because the DetailsView is not loaded with data yet in the Page's Load event.
You need to set your date when the Items in the DataView are being bound to the datasource. You need to use the ItemCreated event....
See... http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.detailsview.itemcreated(v=vs.110).aspx

Send email using gridview checked employees to them in asp.net vb

Good day
I have grid view with employee data displaying in it.
<asp:TabContainer ID="tcmanagers" runat="server" ActiveTabIndex="0"
Width="100%">
<asp:TabPanel ID="TabAdmins" runat="server" HeaderText="Admins" TabIndex="3">
<ContentTemplate>
<asp:Label ID="Label4" runat="server" Font-Bold="False" Font-Italic="False" CssClass="style3"
ForeColor="Blue" Width="290px">Select Admins to send:</asp:Label>
<asp:Button ID="Sendadmins" runat="server" Text="Send Email" Width="201px"/>
<br />
<br />
<asp:GridView ID="GridView3" runat="server" AutoGenerateColumns="False" DataKeyNames="Employee_ID"
DataSourceID="SqlDataSource3" Width="633px" CssClass="grd">
<Columns>
<asp:BoundField DataField="Employee_ID" HeaderText="Employee_ID" ReadOnly="True"
SortExpression="Employee_ID" Visible="False" />
<asp:BoundField DataField="Employee_Number" HeaderText="Employee Number" SortExpression="Employee_Number">
<ItemStyle Width="70px" Wrap="False" />
</asp:BoundField>
<asp:BoundField DataField="Employee_Surname" HeaderText="Surname" SortExpression="Employee_Surname">
<ItemStyle Wrap="False" />
</asp:BoundField>
<asp:BoundField DataField="Employee_Name" HeaderText="Name" SortExpression="Employee_Name">
<ItemStyle Wrap="False" />
</asp:BoundField>
<asp:BoundField DataField="Employee_Job_Title" HeaderText="Job Title" SortExpression="Employee_Job_Title">
<ItemStyle Wrap="False" />
</asp:BoundField>
<asp:BoundField DataField="Employee_Dept" HeaderText="Department" SortExpression="Employee_Dept">
<ItemStyle Wrap="False" />
</asp:BoundField>
<asp:BoundField DataField="Employee_EMail" HeaderText="Email Address" SortExpression="Employee_EMail">
<ItemStyle Wrap="False" />
</asp:BoundField>
<asp:TemplateField HeaderText="Check All"><HeaderTemplate>
<asp:CheckBox ID="chkAlladmin" runat="server" AutoPostBack="True" OnCheckedChanged="chkAllAdmin_CheckedChanged" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="chkAdmin" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns><RowStyle Font-Bold="False" Font-Italic="False" Font-Names="Arial" Font-Size="10pt" />
<EditRowStyle Font-Names="Arial" Font-Size="10pt" /><HeaderStyle Font-Bold="False" Font-Italic="False" Font-Names="Arial" Font-Size="10pt"
Font-Underline="False" CssClass="grdhead" HorizontalAlign="Center" />
<AlternatingRowStyle CssClass="grdalt" />
<SelectedRowStyle BackColor="Fuchsia" />
</asp:GridView>
<asp:SqlDataSource ID="SqlDataSource3" runat="server" ConnectionString="<%$ ConnectionStrings:ApplicationServices %>"
ProviderName="<%$ ConnectionStrings:ApplicationServices.ProviderName %>" SelectCommand="SELECT dbo.lms_Employee.Employee_ID,dbo.lms_Employee.Employee_EMail,dbo.lms_Employee.Employee_Number, dbo.lms_Employee.Employee_Surname, dbo.lms_Employee.Employee_Name, dbo.lms_Employee.Employee_Job_Title,dbo.lms_Employee.Employee_Dept FROM dbo.aspnet_Membership INNER JOIN dbo.aspnet_Users ON dbo.aspnet_Membership.UserId = dbo.aspnet_Users.UserId INNER JOIN dbo.aspnet_UsersInRoles ON dbo.aspnet_Users.UserId = dbo.aspnet_UsersInRoles.UserId INNER JOIN dbo.lms_Employee ON dbo.aspnet_Users.UserName = dbo.lms_Employee.Employee_UserName WHERE (dbo.lms_Employee.Employee_Active = 'True') AND (dbo.aspnet_UsersInRoles.RoleId = '9ec9b26d-64a1-4736-8e82-fe6de7c7caac') and Employee_Number <> '100'">
</asp:SqlDataSource>
</ContentTemplate>
</asp:TabPanel>
</asp:TabContainer>
Now I can select all data in it or one at a time with code below.
Protected Sub chkAllAdmin_CheckedChanged(sender As Object, e As EventArgs)
For Each gr As GridViewRow In GridView3.Rows
Dim cb As CheckBox = DirectCast(gr.FindControl("chkAdmin"), CheckBox)
If DirectCast(sender, CheckBox).Checked Then
cb.Checked = True
Else
cb.Checked = False
End If
Next
End Sub
What I want to do is send a email to all the selected employees. I have an iis server and sql server. So my database is on sql server and my web application is on iis server.
I have no idea how to approached this any help will be appreciated.
Without coding it for you, here's the strategy I use for this type of task:
Convert the BoundField items to TemplateFields. When you do this, you'll likely have controls with meaningful names inside the ItemTemplate for each field, like "lblEmployeeEmail"
On your button-click, loop through the items in the GridView and for each row, use the FindControl() method to find the CheckBox (and then check if it's checked) and use the FindControl() also to get any other fields you might need. (The email label, etc.)
Here's the generic code pattern to follow (lifted from learneveryday.net):
foreach (GridViewRow gvrow in GridView1.Rows)
{
CheckBox CheckBox1 = (CheckBox)gvrow.FindControl("CheckBox1");
if (CheckBox1.Checked)
{
// we write this code for find a label value
Label lblLookFor = (Label)gvrow.FindControl("lblLookFor");
string lookfor = lblLookFor.Text;
}
}
Of course, this only covers how to get the employees that are checked and how to retrieve their email address from the GridViewRows. I'm assuming you already know how to send emails, but if not, see the MSDN documentation.

Telerik Treelist NeedDataSource doesn't load data

I'm trying to load treelist, everything works well but i always see "No Records To Display".
Here is the control:
<telerik:RadTreeList ID="trlProductGroups" runat="server" AllowPaging="true" PageSize="5"
DataKeyNames="ID" ParentDataKeyNames="PARENT_ID" AutoGenerateColumns="false"
OnInsertCommand="trlProductGroups_InsertCommand" OnNeedDataSource="trlProductGroups_NeedDataSource"
OnUpdateCommand="trlProductGroups_UpdateCommand" OnDeleteCommand="trlProductGroups_DeleteCommand">
<Columns>
<telerik:TreeListEditCommandColumn UniqueName="InsertCommandColumn" ButtonType="ImageButton"
HeaderStyle-Width="60px" ItemStyle-HorizontalAlign="Center" />
<telerik:TreeListEditCommandColumn UniqueName="EditCommandColumn" ButtonType="ImageButton">
<ItemStyle CssClass="MyImageButton" />
</telerik:TreeListEditCommandColumn>
<telerik:TreeListButtonColumn UniqueName="DeleteCommandColumn" Text="Delete" CommandName="Delete"
ButtonType="ImageButton" />
<telerik:TreeListBoundColumn DataField="ID" UniqueName="ID" HeaderText="Grup ID"
ReadOnly="true" />
<%-- <telerik:TreeListTemplateColumn DataField="GROUP_NAME" UniqueName="GROUP_NAME" HeaderText="Grup Adı">
<EditItemTemplate>
<asp:TextBox ID="txtGroupName" runat="server"></asp:TextBox>
</EditItemTemplate>
</telerik:TreeListTemplateColumn>--%>
<telerik:TreeListBoundColumn DataField="GROUP_NAME" UniqueName="GROUP_NAME" HeaderText="Grup Adı" />
<telerik:TreeListBoundColumn DataField="PARENT_ID" UniqueName="PARENT_ID" HeaderText="Ana Grup ID"
ReadOnly="true" />
</Columns>
</telerik:RadTreeList>
And here is the NeedDataSource Code:
protected void trlProductGroups_NeedDataSource(object sender, TreeListNeedDataSourceEventArgs e)
{
WebAppTest.Objects.ProductGroups pGroups = new WebAppTest.Objects.ProductGroups();
DataTable dt = pGroups.SelectData(null, string.Empty);
trlProductGroups.DataSource = dt;
}
I can see the data in DataTable, but treelist wont load data. Is there any mistake i make?
Thanks
It's needs to be, at least one data has null id_parent value in datasoruce. Maybe it helps.

Resources