How to access controls and variables, across Class and Code-behind? - asp.net

i have ASP.NET page, its code-behind, and a Class file:
Folder1/page.aspx (asp.net page), it contains a label:
<asp:Label runat="server" ID="Label1" Visible="false"></asp:Label>
Folder1/page.aspx.vb (code-behind), it calls connection.vb like this:
Dim x As New Connection
Protected Sub button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles button1.Click
x.checkusernameExists(TextBoxUsername.Text)
' I try to access `Boolean variable` Flag from Class file but I can't.
End Sub
App_Code/connection.vb (a class file that i created):
Public Class Connection
Public Sub checkusernameExists(ByVal username1 As String)
Dim flag as Boolean
' I try to access here `Label1.text` & `Label1.visible` to work on it but I can't.
End Sub
End Class
My Questions
1 - How can I access the Label1 from the ASP.NET page in Connection.vb?
2 - How can I access the Boolean variable from Connection.vb in page.aspx.vb (code behind)?
I am really stuck in this.
Thank you.

Use (public) properties or method parameters.
You have to ask yourself following: why should a class that is responsible for a connection(i assume to database) have access to your GUI at all? Don't hardlink different layers with each other, otherwise you won't be able to use them alone.
I would suggest to let the connection class do it's work and that is not to modify your frontend. Instead the controller (the aspx page) should manage it's GUI and call the connection class, using the return value to determine what to do next with the Label.
So return a Boolean to indicate if the user is valid:
Public Class Connection
Public Shared Function checkusernameExists(ByVal username1 As String)As Boolean
Dim userExists As Boolean
' acces db to check if the username exists '
Return userExists
End Sub
End Class
in your page:
Protected Sub button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles button1.Click
Dim userExists As Boolean = Connection.checkusernameExists(TextBoxUsername.Text)
Label1.Visible = userExists
If Label1.Visible Then Label1.Text = "Hello again " & TextBoxUsername.Text
End Sub

make flag as property and set this property in checkusernameExists function
Public Class Connection
Public Property Flag as Boolean
Public Sub checkusernameExists(ByVal username1 As String)
// set flag here
Flag = True // or whateever value returned from the database
' I try to access here `Label1.text` & `Label1.visible` to work on it but I can't.
End Sub
End Class
and access this instance level property in page.aspx.vb file
Dim x As New Connection
Protected Sub button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles button1.Click
x.checkusernameExists(TextBoxUsername.Text)
Label1.Visible= x.Flag;
' I try to access `Boolean variable` Flag from Class file but I can't.
End Sub

You can use Function to return value and pass label as parameter.
Public Function SaveChanges(ByRef Label1 As Label, ByVal username1 As String) As Boolean
{
Return True
}
It would be better if you pass the label properties to function instead of passing the object of label as it couple up two classes.

Related

How to persist an object in webform

As I'm self taught my VB coding is not bad but my use of OOP is poor. I'm sure this can be done but I have not found out how yet.
I am building a webforms app which needs to grab data about a user from AD. I have a Person Class which I can use as follows
Public Class _Default
Inherits System.Web.UI.Page
Dim LoggedOnPerson As Person 'Added here so available throughout class
Private strLoggedOnUser As String
Private strADDomain As String
Private strADUserID As String
Public Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
strLoggedOnUser = Request.ServerVariables("LOGON_USER").ToUpper
strADDomain = strLoggedOnUser.Split("\")(0)
strADUserID = strLoggedOnUser.Split("\")(1)
If Not IsPostBack Then
'Dim LoggedOnPerson As Person *** changed to
LoggedOnPerson = New Person
'Get details from AD for logged on user
LoggedOnPerson.GetDetails(strADDomain, strADUserID)
'Store in Session
Session("LoggedOnUser") = LoggedOnUser
'This will now give me access to details such as
'LoggedOnPerson.EmailAddress
'LoggedOnPerson.GivenName
'LoggedOnPerson.TelephoneNo etc.
Else
'Postback so pull in details from Session
LoggedOnUser = Session("LoggedOnUser")
End If
End Sub
End Class
My problem is that I cannot access LoggedOnPerson in other events. e.g.
Public Sub SaveDetails()
Dim email As String = LoggedOnPerson.Email
'This now produces correct result. No error that LoggedOnPerson is not declared
End Sub
I of course get LoggedOnPerson is not declared error. How can I get around this.
You have created the object of "Person" inside Page_Load event. Take it outside and declare at the class level. Also add that object to view state/session state on Page_Load event and typecast it to "Person" class inside other events.

adding events to programatically added controls in web user control

I am trying to put a - what seems - very simple web user control
basically i want it to render as a dropdownlist/checkboxlist or radiolist based on a property
but also want to be able to work out what is selected
i was trying the following - but cant seem to work out how to attach to the selectedindexchanged of the listcontrol so that i can set the selectd value(s)
its not helping that my VB is not up to much but am forced to use it in this instance
its not even giving me the intellisense for the event..
Public Options As List(Of Options)
Public ControlRenderType As ControlRenderType
Public IncludeFreeOption As Boolean
Public SelectedOptions As List(Of Options)
Protected Sub Page_Init(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Init
Dim c As ListControl
Select Case (ControlRenderType)
Case STGLib.ControlRenderType.CheckBoxList
c = New CheckBoxList()
Case STGLib.ControlRenderType.DropdownList
c = New DropDownList()
Case STGLib.ControlRenderType.RadioButtonList
c = New RadioButtonList()
Case Else
Throw New Exception("No Render Type Specified")
End Select
For Each opt In Options
Dim li = New ListItem(opt.Description, opt.ID)
c.Items.Add(li)
Next
c.SelectedIndexChanged += ..?? or something
Page.Controls.Add(c)
End Sub
can anyone explain please - it is of course quite possible that I am going about this in completely the wrong way..
thanks
First create a Sub or a Function to handle the IndexChange of the object that you have created dynamically and make sure that the signature of the Sub is something like this
Sub myOwnSub(ByVal sender As Object, ByVal e As EventArgs)
...
... Handle your event here
...
End Sub
Then after you create your object add the following code
Dim obj as ListBox
AddHandler obj.SelectedIndexChanged, AddressOf myOwnSub

VB.net/Asp.net loading a control programatically with a public property to be set

I have a vb.net asp application where I'm loading a control (from another control on a page). I want to set a variable between the two controls when it loads.
This is where I load the control:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim AuditControl As Control = LoadControl("~/controls/auditcompanies.ascx")
phCompanies.Controls.Add(AuditControl)
End Sub
On the control that's being loaded i've exposed the item i want to change as a property
Public Property resultType() As String
Get
Return m_resultType
End Get
Set(ByVal value As String)
m_resultType = value
End Set
End Property
Basically all it is doing is setting a parameter for my table adaptor
Public Sub Load_Data()
dtblog = New dsDECorp.ClientInfoDataTable
dtblog = tablog.GetAudits(m_resultType)
For Each rClient As dsDECorp.ClientInfoRow In dtblog
CID = rClient.ClientID
ClientName = rClient.CompanyName
Next
dtblog.Dispose()
End Sub
How do I pass the parameter through the property from the first control to the second when it loads?
Thanks
Tom
I'm a C# guy so forgive me if I make any syntax errors but the following should work for you:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Dim AuditControl As Control = LoadControl("~/controls/auditcompanies.ascx")
Dim AuditControlType As Type = AuditControl.GetType()
Dim AuditField As FieldInfo = AuditControlType.GetField("resultType")
AuditField.SetValue(AuditControlType, "Your Value")
phCompanies.Controls.Add(AuditControl)
End Sub

Populate TextBox From Public Property From Code-Behind

I am trying to use a property from the code-behind to populate a textbox instead of using in the code-behind textbox.text=. I am using vb.net. Here is the code for the aspx page:
<asp:Content ID="Content2" ContentPlaceHolderID="MainContentPlaceHolder" runat="server">
<asp:TextBox runat="server" ID="roleTextBox" Text='<%# CurrentRole.Name%>'></asp:TextBox>
</asp:Content>
Here is the code behind code:
Imports Compass.UI.components
Imports Compass.Core.Domain
Imports Compass.Core.Domain.Model
Namespace app.administration.Roles
Partial Public Class edit
Inherits ClaimUnlockPage
Private _roleRepository As IRoleRepository
Private _roleId As Integer
Private _role As Role
Public Property CurrentRole() As Role
Get
Return _role
End Get
Set(ByVal value As Role)
_role = value
End Set
End Property
Public Property RoleRepository() As IRoleRepository
Get
Return _roleRepository
End Get
Set(ByVal value As IRoleRepository)
_roleRepository = value
End Set
End Property
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
LoadRole()
End Sub
Private Sub LoadRole()
_roleId = Config.RequestVal("id", Request)
_role = _roleRepository.GetById(_roleId)
End Sub
End Class
End Namespace
When I run the page the text box is empty.
I didn't see roleTextBox.text=value in your code! in LoadRole or anywhere.
And if you try to bind it, you need a static class for Role.
Just for testing try to add the following line in LoadRole
Private Sub LoadRole()
_roleId = Config.RequestVal("id", Request)
_role = _roleRepository.GetById(_roleId)
roleTextBox.text =CrrentRole.Name;
End Sub
if the roleTextBox is still empty then the CurrentRole.Name is empty.
As far as I know you can't bind a property of a control like this (I wish you could but I've never been able to figure out or find an example how to). The way I've always done it is create a protected function to return e.g.
Protected Function GetCurrentRoleName() As String
Return CurrentRole.Name
End Function
And in your markup bind like so
Text='<%# GetCurrentRoleName() %>'
You have to DataBind the container-control which contains your Textbox(f.e. a GridView,UserControl,etc.). So at least your aspx-page must be databound.
"When called on a server control, this method resolves all data-binding expressions in the server control and in any of its child controls."
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Me.CurrentRole = New Role("Administrator")
Me.DataBind() '!!!!!!!
End Sub
Private _currentRole As Role
Protected Property CurrentRole() As Role
Get
Return _currentRole
End Get
Set(ByVal value As Role)
_currentRole = value
End Set
End Property
Public Class Role
Public Sub New(ByVal name As String)
Me.Name = name
End Sub
Public Name As String
End Class
Then you can use your aspx-code to set the TextBox'-text property.

Putting an object in session via a property in ASP.NET

This seems like it might be a bad idea, but I can't figure out why:
I have a class, cXYZ, with properties A, B and C. It also has a method 'sGetData' that loads those three properties from the database, and a method 'sSaveData' which saves it back.
class cXYZ
public property A as string...
public property B as string...
public property B as string..
public sub sGetData()...
public sub sSaveData()...
end class
A webform has the following property:
private property xyz() as cXYZ
get
return session("myXYZ")
end get
set (value as cXYZ)
session("myXYZ")=value
end set
end property
And the following events:
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
if not ispostback() then
xyz=new cXYZ()
end if
end sub
Protected Sub ButtonLoad_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ButtonLoad.Click
//Can now reference the class
txtA.text=xyz.A
txtB.text=xyz.B
txtC.text=xyz.C
end sub
Protected Sub ButtonSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ButtonSave.Click
//Can now reference the class
xyz.A=txtA.text
xyz.B=txtA.text
xyz.C=txtC.text
xyz.sSaveData()
end sub
I can see some overhead with serializing/deserializing for each property reference- it might be worth doing this:
Protected Sub ButtonSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles ButtonSave.Click
dim localxyz as cXYZ=xyz
localxyz .A=txtA.text
localxyz .B=txtA.text
localxyz .C=txtC.text
xyz=localxyz
end sub
Other than that, views on why this is good or bad? The class is not large, it maintains the form state. Webforms suck, etc is not very useful..
I would improve that little bit:
private _xyz as cXYZ = nothing
private property xyz() as cXYZ
get
if _xyz is nothing then _xyz = TryCast(session("myXYZ"), cXYZ)
return _xyz
end get
set (value as cXYZ)
_xyz = value
session("myXYZ")=_xyz
end set
end property
I think its ok. I would addicionaly keep a variable to store the object to improve performance.
Something like this:
private _xyz as cXYZ = nothing
private property xyz() as cXYZ
get
if not _xyz is nothing then
return _xyz
else
return session("myXYZ")
end if
end get
set (value as cXYZ)
_xyz = value
session("myXYZ")=value
end set
end property
As long as your object is serializable you are OK.
Just don't hold any unmanaged object references in your session - otherwise you'll get into trouble once you move away from 'in process' session state to a web farm.

Resources