Nested repeater with Checkbox list using asp.net - asp.net

I am trying to do a nested repeater control with check box inside. Basically, what i want is
categorize the checkboxes like,
Group 1
Item 1
Item 2
Group 2
Item 3
Item 4
Group 3
Item 5
Item 6
The problem I am facing is, I getting the error :
Error 1 : 'DataRowView' is not declared. It may be inaccessible due to its protection level.
Error 2 : Name 'DataRowView' is not declared.
ASPX :
<asp:Repeater ID="rp_Groups" runat="server" OnItemDataBound="rp_Groups_ItemDataBound" >
<ItemTemplate>
<ul>
<asp:CheckBox runat="server" ID="chk_Group" Text='<%# Eval("category_type") %>' Value='<%# Eval("service_type_category_id") %>' onclick="OnGroupClick" />
<p class="nested">
<asp:CheckBoxList runat="server" ID="chk_Items" DataValueField="ServiceTypeID" DataTextField="Name"
DataSource='<%# ((DataRowView)Container.DataItem).CreateChildView("FK_esnServiceType_Service_Type_Categorization") %>' ></asp:CheckBoxList>
</p>
</ul>
</ItemTemplate>
</asp:Repeater>
Codebehind:
Public Sub Fill()
Dim dtServiceCategory As DataTable = ServiceTypeModel.GetService_Categories()
Dim dtServiceType As DataTable = ServiceTypeModel.Search("", True)
rp_Groups.DataSource = dtServiceCategory
rp_Groups.DataBind()
Dim ds As New DataSet()
ds.Tables.Add(dtServiceCategory)
ds.Tables.Add(dtServiceType)
Dim relation As New DataRelation("FK_esnServiceType_Service_Type_Categorization", ds.Tables("dtServiceCategory").Columns("service_type_category_id"), ds.Tables("dtServiceType").Columns("CategorizationID"), False)
ds.Relations.Add(relation)
relation.Nested = True
End Sub
Protected Sub rp_Groups_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rp_Groups.ItemDataBound
Dim chklist As CheckBoxList = DirectCast(e.Item.FindControl("chk_Items"), CheckBoxList)
If chklist IsNot Nothing Then
chklist.DataSource = DirectCast(e.Item.DataItem, DataRowView).CreateChildView("FK_esnServiceType_Service_Type_Categorization")
chklist.DataBind()
End If
End Sub
What am i missing ?

You should check which itemtype is being fired on the ItemDataBound event, this may or may not be the problem, as you don't have a header and footer template, however it is still good practice.
Protected Sub rp_Groups_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.RepeaterItemEventArgs) Handles rp_Groups.ItemDataBound
If e.Item.ItemType = ListItemType.Item OrElse e.Item.ItemType = ListItemType.AlternatingItem Then
Dim chklist As CheckBoxList = DirectCast(e.Item.FindControl("chk_Items"), CheckBoxList)
If chklist IsNot Nothing Then
chklist.DataSource = DirectCast(e.Item.DataItem, DataRowView).CreateChildView("FK_esnServiceType_Service_Type_Categorization")
chklist.DataBind()
End If
End If
End Sub
EDIT
I've just noticed that you are adding the relation after you have already binded the repeater's datasource. Try moving the .databind after the relation has been added.
EDIT 2
OK can you try this. Add the datatables to the dataset and set the repeaters datasource to: ds.Tables(0)
Public Sub Fill()
Dim ds As New DataSet()
Dim dtServiceCategory As DataTable = ServiceTypeModel.GetService_Categories()
Dim dtServiceType As DataTable = ServiceTypeModel.Search("", True)
ds.Tables.Add(dtServiceCategory)
ds.Tables.Add(dtServiceType)
Dim relation As New DataRelation("FK_esnServiceType_Service_Type_Categorization", ds.Tables("dtServiceCategory").Columns("service_type_category_id"), ds.Tables("dtServiceType").Columns("CategorizationID"), False)
relation.Nested = True
ds.Relations.Add(relation)
rp_Groups.DataSource = ds.Tables(0)
rp_Groups.DataBind()
End Sub

Ensure that you have imported namespace System.Data
Try to add
<%# Import Namespace="System.Data" %>
to your ASPX file.
As another option you can import namespaces globally, not only in one page:
http://msmvps.com/blogs/simpleman/archive/2006/01/11/80804.aspx

Related

GridView not populating on Page_Load but on PostBack or Refresh

In an ASP.NET WebForms application there are just two controls in an aspx page, a DropDownList and a GridView. There is no default selected value of DropDownList on Page_Load. Changing the selection in DropDownList populates GridView accurately.
When the page is requested with a URL parameter such as .../View_Details.aspx?C_ID=123, the selected value in DropDownList changes but GridView does not populate for the first time but refreshing the page shows the records for given URL parameter.
ASPX markup:
<%# Page Title="Data" Language="vb" AutoEventWireup="false" MasterPageFile="~/HomePage.Master" CodeBehind="View_Details.aspx.vb" Inherits="App1.View_Details" %>
<asp:Content ID="Content4" ContentPlaceHolderID="BodyCP" runat="server">
<asp:DropDownList ID="CIDCombo" runat="server" DataSourceID="SqlDSCID" DataTextField="CName" DataValueField="CID" AutoPostBack="true"></asp:DropDownList>
<asp:SqlDataSource ID="SqlDSCID" runat="server" ... ></asp:SqlDataSource>
<asp:GridView ID="gvData" runat="server" AutoGenerateColumns="false">
<Columns>
<asp:BoundField DataField="Fld1" />
<asp:BoundField DataField="Fld2" />
...
</Columns>
</asp:GridView>
</asp:Content>
Code Behind:
Private C_ID As Long
Dim con As SqlConnection = New SqlConnection(ConfigurationManager.Connect...)
Dim cmd As New SqlCommand()
Dim stSqlQry As String = ""
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
C_ID = CLng(Request.QueryString("C_ID"))
If IsPostBack Then
Else
If C_ID > 0 Then
CIDCombo.SelectedValue = C_ID.ToString
LoadGVData(C_ID)
End If
End If
End Sub
Private Sub CIDCombo_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles CIDCombo.SelectedIndexChanged
If CIDCombo.SelectedIndex >= 0 AndAlso CLng(CIDCombo.SelectedValue) > 0 Then
LoadGVData(CLng(CIDCombo.SelectedValue))
End If
End Sub
Private Sub LoadGVData(ByVal lnCID As Long)
Try
If con.State <> ConnectionState.Open Then con.Open()
Dim da As SqlDataAdapter = New SqlDataAdapter()
stSqlQry = "SELECT Fld1, Fld2 ... WHERE CID = #CID"
da = New SqlDataAdapter()
cmd = New SqlCommand(stSqlQry, con)
cmd.Parameters.AddWithValue("#CID", lnCID)
Dim dtDataTableInc As DataTable = New DataTable("t_Data")
da.SelectCommand = cmd
da.Fill(dtDataTableInc)
'SOME DATA MANIPULATION WITH DATATABLE'
'****************************************************************************'
'DEBUG MODE SHOWS DataTable HAS ROWS BUT DON'T SHOW UP FIRST TIME IN GRIDVIEW'
'****************************************************************************'
gvData.DataSource = dtDataTableInc
gvData.DataBind()
Catch ex As Exception
'EXCEPTION HANDLING
Finally
If con.State <> ConnectionState.Closed Then con.Close()
End Try
End Sub
I see you have AutoEventWireup="false" put it on true.
Just a general note:
When working with DropDownLists and using AutoPostBack=True
make use of an UpdatePanel since the User gets frustrated when he always see a white page flickering :)
if you use an UpdatePanel you use the Onload event to populate your data
and put UpdateMode=Conditional
Good luck and happy coding.

How to pass the value to the dropdown list to be highlighted value on Edit template?

The label lblTempLib in the Form has the data coming from table A. This needs to be passed on to the dropdown list as the selected value to datasource in the edit template.
This is the object datasource for LibDS (markup):
SelectCommand="SELECT [LibName] FROM [tblBuilding]"></asp:SqlDataSource>
<asp:FormView ID="frmUpdateIncident" runat="server" DataSourceID="InciDetailDS" OnDataBound="frmUpdateIncident_DataBound">
<EditItemTemplate>
<asp:Label runat="server" ID="lblLib" Text="Library:" CssClass="style_bold"></asp:Label><br />
<asp:Label ID="lblTempLib" runat="server" Text='<%# Eval("Library")%>'Visible="true"></asp:Label>
<asp:Dropdownlist runat="server" ID="ddLib" DataTextField="LibName" DataSourceID="LibDS" >
</asp:Dropdownlist>
VB.NET code:
Protected Sub frmUpdateIncident_DataBound(sender As Object, e As EventArgs) Handles frmUpdateIncident.DataBound
Dim ddLib As DropDownList
Try
If Page.FindControl("ddLibrary") IsNot Nothing Then
ddLib = DirectCast(frmUpdateIncident.FindControl("ddLibrary"), DropDownList)
ddLib.Items.FindByText(strLibName).Selected = True
End If
Catch ex As Exception
MsgBox(ex.Message)
End Try
End Sub
Ok, I finally got it. Need to pass the index value to the dropdown SelectedIndex value as this property can get and set the value unlike SelectedValue.
strLibName is the value passed on by the previous form.
I hardcoded ddLib.SelectedIndex in here to test it but I will be fixing it by passing the list index value.
VB.Net Code:
Protected Sub frmUpdateIncident_DataBound(sender As Object, e As EventArgs) Handles frmUpdateIncident.DataBound
If frmUpdateIncident.CurrentMode = FormViewMode.Edit Then
Dim ddlib As DropDownList
ddlib = DirectCast(frmUpdateIncident.FindControl("ddLibrary"), DropDownList)
If ddLib IsNot Nothing Then
If ddLib.Items.Count > 0 Then
If strLibName IsNot Nothing Then
ddlib.SelectedIndex = 2
Dim strtest As String = ddlib.SelectedValue.Trim
End If
End If
End If
End If
End Sub

Repeater Button CommandArgument is Empty String

Losing my mind with this one. My button gets a commandargument of empty string even though the commandargument gets set. I have verified it gets set to the correct ID in debug mode, but then when I go to access this commandargument later in the repeaters ItemCommand event the commandarguments are empty string. And I have no idea why. I end up getting a sq foreign key exception because it is inserting an ID of 0 from the empty string values. There is no other code regarding the repeaters buttons that would be resetting it.
Repeater:
<asp:Repeater ID="repeaterAddresses" ViewStateMode="Enabled" DataSourceID="sqlFacilityAddresses" runat="server">
<ItemTemplate>
<Select:Address ID="AddressControl" runat="server" />
<asp:Button ID="btnMarkAsBilling" runat="server" EnableViewState="true" CommandName="Billing" Text="Mark as billing address" />
<asp:button ID="btnMarkAsPhysical" runat="server" EnableViewState="true" CommandName="Physical" Text="Mark as physical address" />
</ItemTemplate>
</asp:Repeater>
Code behind:
Protected Sub repeaterAddresses_ItemCreated(ByVal sender As Object, ByVal e As RepeaterItemEventArgs) Handles repeaterAddresses.ItemCreated
If Not IsNothing(DirectCast(e.Item.DataItem, DataRowView)) Then
If (e.Item.ItemType = ListItemType.Item) Or (e.Item.ItemType = ListItemType.AlternatingItem) Then
Dim addressControl As Address = DirectCast(e.Item.FindControl("AddressControl"), Address)
addressControl.AddressID = CInt(DirectCast(e.Item.DataItem, DataRowView)("Address_ID").ToString())
Dim btnBilling As Button = DirectCast(e.Item.FindControl("btnMarkAsBilling"), Button)
btnBilling.CommandArgument = CInt(DirectCast(e.Item.DataItem, DataRowView)("Address_ID").ToString())
Dim btnPhysical As Button = DirectCast(e.Item.FindControl("btnMarkAsPhysical"), Button)
btnPhysical.CommandArgument = CInt(DirectCast(e.Item.DataItem, DataRowView)("Address_ID").ToString())
End If
End If
End Sub
Protected Sub repeaterAddress_ItemCommand(ByVal sender As Object, ByVal e As RepeaterCommandEventArgs) Handles repeaterAddresses.ItemCommand
Dim conn As New SqlConnection(ConfigurationManager.ConnectionStrings("Trustaff_ESig2").ConnectionString)
Dim button As Button = CType(e.CommandSource, Button)
Select Case e.CommandName
Case "Billing"
Dim cmdBillingAddress As New SqlCommand("[SP_Facility_UpdateBillingAddress]", conn)
With cmdBillingAddress
.CommandType = CommandType.StoredProcedure
.Parameters.Add(New SqlParameter("#Facility_ID", DbType.Int32)).Value = sqlFacilityAddresses.SelectParameters("Facility_ID").DefaultValue
.Parameters.Add(New SqlParameter("#BillingAddress_ID", DbType.Int32)).Value = e.CommandArgument
End With
conn.Open()
cmdBillingAddress.ExecuteNonQuery()
conn.Close()
Case "Physical"
Dim cmdPhysicalAddress As New SqlCommand("[SP_Facility_UpdatePhysicalAddress]", conn)
With cmdPhysicalAddress
.CommandType = CommandType.StoredProcedure
.Parameters.Add(New SqlParameter("#Facility_ID", DbType.Int32)).Value = sqlFacilityAddresses.SelectParameters("Facility_ID").DefaultValue
.Parameters.Add(New SqlParameter("#PhysicalAddress_ID", DbType.Int32)).Value = e.CommandArgument
End With
conn.Open()
cmdPhysicalAddress.ExecuteNonQuery()
conn.Close()
End Select
PopulateBillingPhysicalAddresses(sqlFacilityAddresses.SelectParameters("Facility_ID").DefaultValue)
End Sub
Try this:
<asp:Button ID="btnMarkAsBilling" runat="server" EnableViewState="true"
CommandName="Billing" Text="Mark as billing address"
CommandArgument='<%# Eval("Address_ID") %>'/>
Note the single quotes around the attribute value. ASP.NET will not execute the server side data binding code if they are double quotes. You'll need to remove the CommandArgument assignments from your code behind.
Address_ID will need to be a property on the object you are databinding to the repeater.

ASP.NET: Bind HyperLinkColumn to more than one field

Using ASP.NET and the DataGrid, how do I bind a HyperLinkColumn to more than one field?
Dim detail As New HyperLinkColumn
With detail
.Text = "View Details"
.HeaderText = ""
.NavigateUrl = "\TeamDetail.aspx?Account={0}&Broker={1}"
.DataNavigateUrlField = "AccountKey, BrokerNumberKey"
End With
I was hoping for an data-binding event on HyperLinkColumn but no such luck.
You need to use a TemplateColumn. This will give you named controls you can work with in the ItemDataBound event.
ASP
<asp:TemplateColumn>
<ItemTemplate>
<asp:HyperLink runat="server" ID="LinkColumn" NavigateUrl="" Text="View Details"></asp:HyperLink>
</ItemTemplate>
</asp:TemplateColumn>
VB
Private Sub ReportGrid_ItemDataBound(ByVal sender As Object, ByVal e As System.Web.UI.WebControls.DataGridItemEventArgs) Handles ReportGrid.ItemDataBound
Const target = "/TeamsDetail.aspx?Account={0}&Broker={1) Select Case e.Item.ItemType
Case ListItemType.Item, ListItemType.AlternatingItem
Dim ctrl = CType(e.Item.FindControl("LinkColumn"), HyperLink)
Dim row = CType(e.Item.DataItem, DataRowView)
If ctrl IsNot Nothing Then
Dim accountKey = CInt(row("PrincipalAccountKey"))
Dim brokerNumberKey = CInt(row("BrokerNumberKey"))
ctrl.NavigateUrl = String.Format(target, accountKey, brokerNumberKey)
End If
End Select
End Sub

Checkboxes in usercontrol won't check although they say they are

I have a simple usercontrol, with a datalist, and checkboxes inside.
<asp:DataList ID="DataListDroits" runat="server" DataKeyField="droit_id" DataSourceID="SqlDroits">
<ItemTemplate>
<asp:HiddenField ID="HiddenFieldDroitID" runat="server" Value='<%# Eval("droit_id") %>' />
<asp:CheckBox ID="CheckBoxDroit" runat="server" Text='<%# Eval("droit_label") %>' />
</ItemTemplate>
</asp:DataList>
I check them using code behind in the usercontrol :
Public Sub CheckRole(ByVal role As Integer)
For Each dliOrganisme As DataListItem In Me.DataListOrganismes.Items
Dim DataListDroits As DataList = dliOrganisme.FindControl("DataListDroits")
If DataListDroits IsNot Nothing Then
For Each dliDroit As DataListItem In DataListDroits.Items
If role = CInt(CType(dliDroit.FindControl("HiddenFieldDroitID"), HiddenField).Value) Then
Dim CheckBoxDroit As CheckBox = dliDroit.FindControl("CheckBoxDroit")
CheckBoxDroit.Checked = True
End If
Next ' DataListDroits
End If
Next ' DataListItem
End Sub
And in the page_load of the calling webform :
Dim CheckBoxesRoles1 As ASP.organisme_checkboxesroles_ascx = Me.FormViewRubrique.FindControl("CheckBoxesRoles1")
Dim rolesCoches As New List(Of Integer)
Dim cmdRoles As New SqlCommand("SELECT droit_id FROM o_droit_rubrique WHERE rubrique_id = #rubrique", conn)
cmdRoles.Parameters.AddWithValue("rubrique", Request.QueryString("rid"))
Dim rdrRoles As SqlDataReader = cmdRoles.ExecuteReader
While rdrRoles.Read
CheckBoxesRoles1.CheckRole(rdrRoles("droit_id"))
End While
rdrRoles.Close()
... and yet, they are not checked.
But if I do this :
Protected Sub Page_LoadComplete(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.LoadComplete
Dim CheckBoxesRoles1 As ASP.organisme_checkboxesroles_ascx = Me.FormViewRubrique.FindControl("CheckBoxesRoles1")
If CheckBoxesRoles1 IsNot Nothing Then
For Each role As Integer In CheckBoxesRoles1.CheckedRoles
Response.Write("role : " & role & "<br>")
Next
End If
End Sub
I tells me they are...
I'm going mad here ! Why does it tells me they are checked while they obviously are not ?
Well... for one thing, you aren't checking if your checkboxes are checked, all you're doing is outputting the value of "role". What exactly are you expecting here?
Two suggestions:
1) Set the Checked property of your CheckBox in the aspx like so:
<asp:CheckBox ID="CheckBoxDroit" runat="server" Text='<%# Eval("droit_label") %>' Checked='<%# (Eval("droit_id") > 0).ToString()' />
2) Set the property in OnItemDataBound in code-behind
One of two things is happening: Either the code you expect to be executing is not really executing (ie, is your if block ever true? Is the control not being found? Try a breakpoint), OR you are doing it at the wrong time -- after the page has already been rendered.

Resources