update page text using web user control - asp.net

I am building an application where a page will load user controls (x.ascx) dynamically based on query string.
I have a validation summary on the page and want to update it from the User Controls. This will allow me to have multiple controls using one Validation Summary. How can I pass data between controls and pages.
I know I can define the control at design time and use events to do that but these controls are loaded dynamically using Page.LoadControl.
Also, I want to avoid using sessions or querystring.

Found a way of doing this:
Step 1: Create a Base User Control and define Delegates and Events in this control.
Step 2: Create a Public function in the base user control to Raise Events defined in Step1.
'SourceCode for Step 1 and Step 2
Public Delegate Sub UpdatePageHeaderHandler(ByVal PageHeading As String)
Public Class CommonUserControl
Inherits System.Web.UI.UserControl
Public Event UpdatePageHeaderEvent As UpdatePageHeaderHandler
Public Sub UpdatePageHeader(ByVal PageHeadinga As String)
RaiseEvent UpdatePageHeaderEvent(PageHeadinga)
End Sub
End Class
Step 3: Inherit your Web User Control from the base user control that you created in Step1.
Step 4: From your Web User Control - Call the MyBase.FunctionName that you defined in Step2.
'SourceCode for Step 3 and Step 4
Partial Class DerievedUserControl
Inherits CommonUserControl
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
MyBase.PageHeader("Test Header")
End Sub
End Class
Step 5: In your page, Load the control dynamically using Page.LoadControl and Cast the control as the Base user control.
Step 6: Attach Event Handlers with this Control.
'SourceCode for Step 5 and Step 6
Private Sub LoadDynamicControl()
Try
'Try to load control
Dim c As CommonUserControl = CType(LoadControl("/Common/Controls/Test.ascx", CommonUserControl))
'Attach Event Handlers to the LoadedControl
AddHandler c.UpdatePageHeaderEvent, AddressOf PageHeaders
DynamicControlPlaceHolder.Controls.Add(c)
Catch ex As Exception
'Log Error
End Try
End Sub

Assuming you're talking about asp's validator controls, making them work with the validation summary should be easy: use the same Validation Group. Normally, I derive all usercontrols from a base class that adds a ValidationGroup property whose setter calls a overriden method that changes all internal validators to the same validation group.
The tricky part is making them behave when added dynamically. There are some gotchas you should be aware of, mainly concerning the page cycle and when you add them to your Page object. If you know all the possible user controls you'll use during design time, I'd try to add them statically using EnableViewState and Visible to minimize overhead, even if there are too many of them.

Related

VB.Net: call sub from shared sub

I have some Ajax on a web page that feeds some data to a server-side VB.Net method. Once that data is in the server-side method, I need to call another server-side method to use the data I just collected. Here is a really simplified example:
' This method gets the input from the Ajax code on the web page.
<System.Web.Services.WebMethod> _
Public Shared Sub GetAwesome(VBInputText As String)
Dim strTest As String = VBInputText
' Now that we have collected input from the user,
' we need to run a method that does a ton of other stuff.
DisplayAwesome(VBInputText)
End Sub
Protected Sub DisplayAwesome(AwesomeIn As String)
' The real app does a lot more than this. For this example, it
' just sets the text of a literal.
litAwesomeResult.Text = AwesomeIn
End Sub
Of course, in the above example DisplayAwesome(VBInputText) gives me the 'Cannot refer to an instance member...' error. So, is it possible now to call Protected Sub DisplayAwesome from Public Shared Sub GetAwesome? I'm hoping to stay close to this sort of solution because it would play very well with the app as it is already written by another coworker.
unfortunately you cannot do this, Since the page method DisplayAwesome is defined as Protected and you requires an instance of the class to access the Protected method. But changes in another instance will not reflect in the current UI. another thing you can do is Make DisplayAwesome as Shared, but this time you cannot access the UI elements inside the shared function.
The thing you can do in this situation is, return data to the called method(in front end) and handle the litAwesomeResult.Text there
Call sub with name of Form Class like this:
FormName.DisplayAwesome(VBInputText)
In VB.Net, you can call the method not shared from a shared method with Name of Form Class by default instance, because The default instance is an object Form type that the VB application framework create and manage it, when the form is added to the project.
For more info see this :
VB.NET Default Form Instances

vb global variable to be accesses by different classes

I am new to VB and am working on an asp.net VB web application.
I have a partial class called s_new.aspx.vb which is the vb page behind the page s_new.aspx.
In this page there are a series of select dropdowns, which when selected lead to different options becoming available eg different select boxes appearing and or with different options.
One particular select box accesses a method in a different class (webcontrols).
My problem is that I need the web controls class to change its behavior based on a certain selection made in the s_new.aspx.vb page.
If I was using C# I would create a global variable and use that as a decision maker, but I cant seem to to this in VB.
below is a snippet of the code I am using:
Partial Class s_new
Protected Sub fldSourceofFunds_SelectedIndexChanged(ByVal sender As Object, ByVal e As System.EventArgs) Handles fldSourceofFunds.SelectedIndexChanged
Select Case fldSourceofFunds.SelectedIndex
Case 1
####
Case 2
###
Case 3
do something and set the variable
End Select
End Sub
Partial Class Webcontrols
Private Sub ReloadChildren()
If (variable from s_new has certain value) Then
ResetChildren()
Select Case PaymentMethodValue.ToLower.Trim
Case "payment via provider/platform"
Case "payment direct from client"
Case "payment via provider/platform and payment direct from client"
End Select
End if
End Sub
End Class
This is an existing project and I need to minimize the changes I make to the project, eg I am not able to make large changes to the structure to accommodate this change. As I said above, this would be a simple solution in C# and I assume it is simple here to.

Storing and restoring properties in ASP.NET derived control

I have created an ASP.NET class derived from the standard WebControls.TextBox, with the intention of adding extra properties that will persist between post-backs. However, I cannot figure how to get the values in these properties to persist.
I have tried setting the value of the properties into the controls ViewState as part of the PreRender handler, but the value is then not accessible in the Init handler on the post-back, because the ViewState has not yet been setup.
I could look for the ViewState value in the Load handler of the control, but if the page/usercontrol that is using the control asks for the properties value during its Load handler, the control hasn't yet reached it's Load handler, and it therefore not there.
My current class looks something like this...
Public Class MyTextBox
Inherits TextBox
Private _myParam As String = ""
Public Property MyParam As String
Get
Return _myParam
End Get
Set(value As String)
_myParam = value
End Set
End Property
Private Sub MyTextBox_Init(sender As Object, e As EventArgs) Handles Me.Init
If Page.IsPostBack Then
_myParam = ViewState("myParam")
End If
End Sub
Private Sub MyTextBox_PreRender(sender As Object, e As EventArgs) Handles Me.PreRender
ViewState("myParam") = _myParam
End Sub
End Class
I must be missing something really simple, such as whether there is an attribute I can set against the property.
UPDATE
Thanks to #AVD pointing out that I really had very little clue about the ViewState and the Init / Load stages, I finally figured it all out.
If you have the time (and if you're doing any major ASP.NET work, you need to make the time) please read the Understand ASP.NET View State document that #AVD pointed me to. It will explain a lot.
However, what it didn't explain is if you place your control within a <asp:Repeater>, you may as well throw all the rules out of the window... and that is exactly the problem I was experiencing.
In the end, the way I managed to get it to work was to use a <asp:PlaceHolder> control within the repeater, create an instance of my control within the ItemDataBound handler of the repeater, and then add the control to the <asp:PlaceHolder>... all done within the Init section (which fortunately I'm able to do).
As Andrew found out in this previous question you can end up in a chicken/egg situation, where you need to create the controls in the Init, but you won't know what controls you need until the Load.
(I have still made AVD's answer the correct one, because in the context of my original question, it is absolutely correct).
You have to store/retrieve value to/from ViewState within the properties accessors.
Public Property MyParam As String
Get
If IsNothing(ViewState("myParam")) Then
return string.Empty
End IF
Return ViewState("myParam").ToString()
End Get
Set(value As String)
ViewState("myParam") = value
End Set
End Property

How to set master page on page preinit based on custom user control method result

I have a user control that checks if a certain query string and session value are present then returns a boolean based on that, if it's true I want to set the master page.
The page is throwing an Object reference exception when it tries to call the method EditUser1.UserAuthorization(). Why is this happening? I imagine that the method doesn't exist at that point in the stack.
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
If EditUser1.UserAuthorization(True) Then
Page.MasterPageFile = "APERSEmpCont.master"
End If
End Sub
I just found out from here, that the page controls haven't been initialized at the point of the preinit, so that method doesn't exist at that moment. I'll have to move the method to the page level to make it work.

Add Multiple User Control of the Same Type to a Page

Similar questions to this one have been asked but none seem to address my exact situation here's what I am trying to do.
I have a user control that manages student info. i.e. FirstName, LastName, Address etc.
I have a webpage/form that has a button on it. "Add Student". What I want to accomplish is for a new StudentInfo control to be added to the webform after each click.
My current code looks something like this
Private Sub btnAddStudent_Click(sender as object, ByVal e As System.EventArgs)
Dim lStudentInfo as Control
LoadControl("~/StudentInfo.ascx")
Me.placeholder1.controls.add(lStudentInfo)
End Sub
With this code only one StudentInfo control is added and upon pressing the "Add" button again a new StudentInfo control isnt added below the first one and the text/data entered within the first control is cleared.
Thanks in advance for any assistance.
What is happening is that every time you do a postback your previous control was lost. Remember, every postback uses a brand new instance of your page class. The instance you added the control to last time was destroyed as soon as the http request finished — possibly before the browser even finished loading it's DOM.
If you want a control to exist for every postback you have to add it on every postback.
Additionally, if you want ViewState to work for the control you need to add it before the Load event for the page. This means either on Init or PreInit.
Private Sub btnAddStudent_Click(sender as object, ByVal e As System.EventArgs)
Me.placeholder1.controls.add(LoadControl("~/StudentInfo.ascx"))
Session("NewStudentControls") += 1
End Sub
Protected Sub Page_Init(sender as object, e as system.eventargs)
For i As Integer = 1 To Session("NewStudentControls")
Me.placeholder1.controls.add(LoadControl("~/StudentInfo.ascx"))
Next
End Sub

Resources