Checkboxes in usercontrol won't check although they say they are - asp.net

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.

Related

ASP Repeater not showing data

I'm trying to get an alphabet pager working in GridView. It does work, but only one letter shows up in the repeater that I'm using to show the letters. I've read other posts and looked at my code and it seems like it should be working, but it's not.
Any help would be appreciated.
Here is my html
<asp:Repeater ID="rptAlphabets" runat="server">
<ItemTemplate>
<asp:LinkButton ID="lnkBtn1" runat="server" Text='<%#Eval("Value")%>' Visible='<%# Convert.ToBoolean(Eval("Selected"))%>' OnClick="Alphabet_Click"/>
<asp:Label ID="lblAlpha" runat="server" Text='<%#Eval("Value")%>' Visible='<%# Convert.ToBoolean(Eval("Selected"))%>' />
</ItemTemplate>
</asp:Repeater>
Here is my code behind
Private Sub GenerateAlphabets()
Dim alphabets As New List(Of ListItem)()
Dim alphabet As New ListItem
alphabet.Value = "ALL"
alphabet.Selected = alphabet.Value.Equals(ViewState("CurrentAlphabet"))
alphabets.Add(alphabet)
For i As Integer = 65 To 90
alphabet = New ListItem()
alphabet.Value = [Char].ConvertFromUtf32(i)
alphabet.Selected = alphabet.Value.Equals(ViewState("CurrentAlphabet"))
alphabets.Add(alphabet)
Next
rptAlphabets.DataSource = alphabets
rptAlphabets.DataBind()
End Sub
I'm using most of the code from an aspsnippets method.
EDIT :
I'm calling the GenerateAlphabets from my Page_Load
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Try
ClearMessages()
If Not IsPostBack Then
ViewState("CurrentAlphabet") = "ALL"
Me.GenerateAlphabets()
BindGrids()
BindDropDownListBoxes()
End If
Catch ex As Exception
Me.HandleError(ex)
End Try
End Sub
Change your LinkButton code like this.
<asp:LinkButton ID="lnkBtn1" runat="server"
Text='<%#Eval("Value")%>'
Visible='<%# Convert.ToBoolean(Eval("Selected")) = False %>'
OnClick="Alphabet_Click"/>
Reason: You are hiding all LinkButtons that are not currently selected. You should be showing them instead.

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

Object reference not set to an instance of an object. - Visual Basic (Web)

So, I'm having a slight problem with my code.
I was working on a small school project (recreation of book library) and encountered a problem which I cannot get a grasp of.
So, the user can search for a list of books, and after the list is populated (via DataList control), a small button "Book now" (Reserve) appears which user can click and reserve his book.
This is the code for the DataList control that resides in "Search.aspx"
<asp:DataList ID="DataList1" runat="server" DataKeyField="knjigaId" DataSourceID="SearchSqlDataSource" CssClass="searchControl">
<ItemTemplate>
<div class="pictureOfFoundBook">
<asp:Image ID="pictureOfFoundBook_imageLink" runat="server" ImageUrl='<%#"~/GetImage.aspx?knjigaId=" & Eval("knjigaId") & "&img=naslovnica" %>' />
</div>
<div class="descriptionOfFoundBook">
Naziv: <asp:Label ID="Label1" runat="server" Text='<%# Eval("naziv") %>' /><br />
Godina izdanja: <asp:Label ID="Label2" runat="server" Text='<%# Eval("godinaIzdanja") %>' /><br />
Broj stranica : <asp:Label ID="brojStranicaLabel" runat="server" Text='<%# Eval("brojStranica") %>' /><br />
Izdavač: <asp:Label ID="NazivIzdavacaLabel" runat="server" Text='<%# Eval("NazivIzdavaca") %>' /><br />
Vrsta tiskovine : <asp:Label ID="NazivVrsteTiskovineLabel" runat="server" Text='<%# Eval("NazivVrsteTiskovine") %>' /><br />
Kategorija: <asp:Label ID="NazivKategorijeLabel" runat="server" Text='<%# Eval("NazivKategorije") %>' /><br /><br />
<asp:HyperLink ID="foundBookEditHL_adminOnly" runat="server" NavigateUrl='<%# "~/admin/knjigeEdit.aspx?knjigaId=" & Eval("knjigaId") %>'>Uredi knjigu</asp:HyperLink><br />
<asp:Button ID="rezervacijeButton" runat="server" Text="Rezerviraj" OnClick="rezervacijaClick" CommandArgument='<%# Eval("knjigaId") %>'/><br />
<asp:Label ID="rezStatusLabel" runat="server"></asp:Label>
<asp:PlaceHolder ID="rezStatusPlaceholder" runat="server"></asp:PlaceHolder>
</div>
<hr />
</ItemTemplate>
</asp:DataList>
I've set the DataList1 control as a Friend sub so I can access the controls in it from another sub;
Friend Sub DataList1_ItemCreated(sender As Object, e As System.Web.UI.WebControls.DataListItemEventArgs) Handles DataList1.ItemCreated
End Sub
I was trying to do the following; on the click of a button "rezervacijeButton", a function "rezervacijaClick" runs, which populates the table in the database.
Protected Sub rezervacijaClick(sender As Object, e As System.EventArgs)
Dim Conn As New System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings("LocalSqlServer").ToString)
Dim cmd As New System.Data.SqlClient.SqlCommand
Dim sql As New StringBuilder
Dim rezstatus As Label = DataList1.FindControl("rezStatusLabel")
sql.Append("INSERT INTO rezervacije(UserName, knjigaId) VALUES (#UserName, #knjigaId)")
Dim buttonsender As Button = sender
cmd.Parameters.AddWithValue("UserName", User.Identity.Name)
cmd.Parameters.AddWithValue("knjigaId", buttonsender.CommandArgument)
Conn.Open()
cmd.CommandText = sql.ToString
cmd.Connection = Conn
cmd.ExecuteNonQuery()
Conn.Close()
buttonsender.Visible = False
rezstatus.Text = "aaa"
'Try
' rezstatus.Text = "testing..."
'Catch ex As Exception
' exlabel.Text = "POGREŠKA"
' exlabel.ForeColor = Drawing.Color.Red
'End
End Sub
The next thing I wanted to do in the function "rezervacijaClick" was to set the text value of the Label (with ID "rezStatusLabel", which resides inside the DataList1 control) to "SOME TEXT" after the "Reserve" button is clicked.
But after the button click, I get the following error :
Object reference not set to an instance of an object.
Line 21:
Line 22: buttonsender.Visible = False
Line 23: rezstatus.Text = "aaa"
Line 24:
Line 25: 'Try
Your rezstatus object is Nothing (null).
This is happening because you aren't looking in the right place for your label.
Each record of data you bind to the DataList will create a new hierarchy of controls, containers that hold the other controls you have defined in your ItemTemplate.
The immediate descendants of DataList1 will be a collection of DataListItem objects and then you will have your controls inside those.
Since we don't know for sure (unless you know you are only binding one record to the DataList) which DataListItem the desired label will be in, we simply walk backwards up the control tree and find the label from there.
Because you are responding to a button click event in your rezervacijaClick method, the parameter sender will be of type Button and will come from rezervacijeButton, so we can use that information to find your label:
Dim clickedButton As Button = CType(sender, Button) 'convert the sender parameter to the correct type: Button
Dim buttonParent As Control = clickedButton.Parent 'get a reference to the button's parent control
Dim rezstatus As Label = CType(buttonParent.FindControl(""), Label) 'find the label by ID and convert it to a Label as the return type of FindControl is Control
I would recommend that, instead of using the Button click event, you use the DataList.ItemCommand event. It will make your life a lot easier. This event fires whenever a Button is clicked within a row of your DataList control.
This way, you get the index passed in through the DataListCommandEventArgs parameter. then you would just need to update your DataList markup to add the event handler:
<asp:DataList ID="DataList1" runat="server" DataKeyField="knjigaId"
DataSourceID="SearchSqlDataSource" CssClass="searchControl"
ItemCommand="DataList1_ItemCommand" >
And your handler code would look like this:
Protected Sub DataList1_ItemCommand(sender As Object, e As System.EventArgs)
Dim Conn As New System.Data.SqlClient.SqlConnection(ConfigurationManager.ConnectionStrings("LocalSqlServer").ToString)
Dim cmd As New System.Data.SqlClient.SqlCommand
Dim sql As New StringBuilder
Dim rezstatus As Label = e.Item.FindControl("rezStatusLabel")
sql.Append("INSERT INTO rezervacije(UserName, knjigaId) VALUES (#UserName, #knjigaId)")
Dim buttonsender As Button = e.Item.FindControl("rezervacijeButton")
cmd.Parameters.AddWithValue("UserName", User.Identity.Name)
cmd.Parameters.AddWithValue("knjigaId", buttonsender.CommandArgument)
Conn.Open()
cmd.CommandText = sql.ToString
cmd.Connection = Conn
cmd.ExecuteNonQuery()
Conn.Close()
buttonsender.Visible = False
rezstatus.Text = "aaa"
End Sub

Find the right value of textbox

I have a problem with inserting data inserting data into database.
<asp:Repeater ID="Repeater1" runat="server" DataSourceID="SqlDataSource1" OnItemDataBound="Repeater1_ItemDataBound">
<ItemTemplate>
<!-- Some other data (text...) -->
<asp:HiddenField ID="HiddenField1" runat="server" Value='<%# Eval("PostId") %>' />
<asp:TextBox ID="txtAddComment" runat="server" CssClass="textbox" Width="200px" />
<asp:Button ID="btnAddComment" runat="server" CssClass="button" Text="Comment" CausesValidation="false" OnClick="btnAddComment_Click"/>
</ItemTemplate>
</asp:Repeater>
Code behind:
Protected Sub btnAddComment_Click(sender As Object, e As EventArgs)
Dim HiddenField1 As HiddenField = DirectCast(Repeater1.Items(0).FindControl("HiddenField1"), HiddenField)
Dim txtAddComment As TextBox = DirectCast(Repeater1.Items(0).FindControl("txtAddComment"), TextBox)
Dim conn As New SqlConnection(ConfigurationManager.ConnectionStrings("ConnectionString").ConnectionString.ToString)
Try
If txtAddComment.Text = "" Then
Exit Sub
Else
conn.Open()
Dim cmd As SqlCommand = conn.CreateCommand()
cmd.CommandText = "INSERT INTO Comments (PostId, UserName, CommentText) VALUES (#PostId, #UserName, #Text)"
cmd.Parameters.Add("PostId", System.Data.SqlDbType.Int).Value = CInt(HiddenField1.Value)
cmd.Parameters.Add("UserName", System.Data.SqlDbType.NVarChar).Value = Context.User.Identity.Name
cmd.Parameters.Add("Text", System.Data.SqlDbType.NText).Value = MakeLink(HtmlRemoval.StripTagsCharArray(txtAddComment.Text))
cmd.ExecuteNonQuery()
End If
Catch ex As SqlException
Finally
conn.Close()
End Try
End Sub
I display some text, under the text there is textbox and button for comments. I am bounding textId in hiddenfield for inserting comments. The code works fine, but I can only add comment for the first row in database displayed by repeater. When I want to add comment for other rows (2, 3...), the page refreshes and the text in the TextBox stay there.
It is problem with this line of code:
Dim txtAddComment As TextBox = DirectCast(Repeater1.Items(0).FindControl("txtAddComment"), TextBox)
The ID from HiddenField is right. But the code doesn't perform because the line above references for the first textbox on the page and his value is null.
When I change the line of code like this:
Dim txtAddComment As TextBox = DirectCast(Repeater1.FindControl("txtAddComment"), TextBox)
It returns an error that Object reference not set to an instance of an object.
How to get the right textbox with right value?
Thanks for the answer
cast the sender to a button that sent it, then get the textbox from the parent. Example:
Protected Sub button_click(ByVal sender As Object, ByVal e As EventArgs)
Dim myButton As button= CType(sender, button)
Dim myTextBox as TextBox = CType(myButton Parent.FindControl("buttonName"), TextBox)
end sub

How to bind DropDownList in Gridview with data NOT from gridview

Half the battle of getting an answer is knowing how to ask the question. I am not certain I am doing a good job of that but this is my best shot.
I'm trying to bind a ddl with data inside a gridview that is NOT coming from the gridview itself. This is within the EditItemTemplate. The purpose for doing so is to give the user, to start, a selected value and a series of other values from a lookup stored procedure.
I'll mention here that I have done this successfully before but using an ObjectDataSource. I am trying to avoid that this time and do it entirely from the code behind for now then move it to a data layer later.
Here is what I have so far...
<asp:GridView ID="usersGrid" runat="server"
DataKeyNames="userID"
AutoGenerateColumns="false" Width="580"
OnRowUpdating="usersGrid_RowUpdating"
OnRowEditing="usersGrid_RowEditing"
OnRowCancelingEdit="usersGrid_RowCancelingEdit" OnRowDeleting="usersGrid_RowDeleting"
>
...
<EditItemTemplate>
<div class="gridName">
<asp:TextBox ID="txtFirstName" Text='<%#Eval("firstName") %>' runat="server" Width="95" />
</div>
<div class="gridName">
<asp:TextBox ID="txtLastName" Text='<%#Eval("lastName") %>' runat="server" Width="95" />
</div>
<div class="gridEmail">
<asp:TextBox ID="txtEmail" Text='<%#Eval("email") %>' runat="server" Width="245" />
</div>
<div class="gridName">
<asp:DropDownList ID="ddl_GetLists"
DataSourceID="GetListData()"
AppendDataBoundItems="true"
DataValueField="listID"
DataTextField="listName"
SelectedValue='<%#Bind("listID") %>'
runat="server"
>
</asp:DropDownList>
</div>
</EditItemTemplate>
....
Protected Sub usersGrid_RowEditing(ByVal sender As Object, ByVal e As GridViewEditEventArgs)
usersGrid.EditIndex = e.NewEditIndex
BindData()
End Sub
....
Private Sub BindData()
Dim conn As New SqlConnection(connectionString)
Dim ad As New SqlDataAdapter("MAINT_DIST_GET_USERS", conn)
Dim ds As New DataSet()
ad.Fill(ds)
GetListData()
usersGrid.DataSource = ds
usersGrid.DataBind()
End Sub
I'm including last two as well as other approaches I've tried and failed.
...
Protected Sub usersGrid_RowDataBound(ByVal sender As Object, ByVal e As GridViewRowEventArgs)
If e.Row.RowState = DataControlRowState.Edit Then
Dim ddl As DropDownList = DirectCast(e.Row.FindControl("ddl_GetLists"), DropDownList)
Dim conn As New SqlConnection(connectionString)
Dim ad As New SqlDataAdapter("MAINT_DIST_GET_LISTS", conn)
Dim ds As New DataSet()
ad.Fill(ds)
ddl.DataSource = ds
ddl.DataBind()
End If
End Sub
Public Function BindDropdown() As DataSet
Dim conn As New SqlConnection(connectionString)
Dim ad As New SqlDataAdapter("MAINT_DIST_GET_LISTS", conn)
Dim ds As New DataSet()
ad.Fill(ds)
ddl_GetLists.DataSource = ds
ddl_GetLists.DataBind()
End Function
I'll also ask why, in the final function, why is the control, ddl_GetLists, not recognized as well? Inside the grid it disappears from the designer but outside of the grid it reappears.
Thank you all for your help.
You have a couple of options. You can use a datasource control, or you can bind the dropdowns in code-behind in the RowDataBound event of the GridView.
I noticed a couple of issues in your code too. In your example you're assigning the DataSourceID incorrectly. The DataSourceID should point to the ID of a datasource control on the page:
<asp:DropDownList ID="ddl_GetLists"
DataSourceID="SqlDataSource1"
AppendDataBoundItems="true"
DataValueField="listID"
DataTextField="listName"
SelectedValue='<%#Bind("listID") %>'
runat="server">
</asp:DropDownList>
<asp:SqlDataSource ID="SqlDataSource1" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnectionString %>"
SelectCommand="SELECT listID, listName FROM SomeTable">
</asp:SqlDataSource>
If you want to do the binding in code-behind, you can do this through the RowDataBound event:
Protected Sub GridView1_RowDataBound(sender As Object, e As GridViewRowEventArgs)
If e.Row.RowType = DataControlRowType.DataRow AndAlso (e.Row.RowState And DataControlRowState.Edit) = DataControlRowState.Edit Then
Dim ddl As DropDownList = TryCast(e.Row.FindControl("ddl_GetLists"), DropDownList)
If ddl IsNot Nothing Then
ddl.DataSource = RetrieveDataSource()
ddl.DataBind()
End If
End If
End Sub
You can simply create a global list of type that you want and set it as null
if you are using linq then just put that source in the DropDownListObject.DataSource
DropDownListObject.DataSource=ObjListSource;
DropDownListObject.DataBind;
Hope it will be helpful.
I see a couple issues.
Protected Sub usersGrid_RowEditing(ByVal sender As Object, ByVal e As GridViewEditEventArgs)
usersGrid.EditIndex = e.NewEditIndex
BindData()
End Sub
Why are you doing this? Why would you bind the grid again on an event on your grid thats already been filled?
You fix this:
In the code page, you define a GetListData() public function (i think you did).
Use DataSource property (if you want to call a function) :
<asp:DropDownList ID="ddl_GetLists"
DataSource='<%# GetListData() %>'
AppendDataBoundItems="true"
DataValueField="listID"
DataTextField="listName"
SelectedValue='<%#Bind("listID") %>'
runat="server" >
</asp:DropDownList>

Resources