Call an aspx method from ascx - asp.net

The ASPX that I have is a partial that has a a master page on it and I would like to replace a textbox with new text.
I have a listbox that is created from the data base in the ASCX. I have a text box in the default.aspx page which I would like to change the test if the selected index has changed. I keep getting the error to delcare class, the class definiton for the defualt.aspx.vb is got a definition is below.
Partial Class _Default
Inherits System.Web.UI.Page
Code that sits on default.aspx.vb
Public Sub test(ByVal val As String)
lbl1LoginPage.Text = val
End Sub
VB ascx code to get the value of the selected index
Protected Sub ListBox3_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles ListBox3.SelectedIndexChanged
Dim test As String = ListBox3.Text
Dim page As _Default = DirectCast(page, _Default)
page.test(test)
End Sub

You can create a Property in aspx page exposing the text box control say "TextBoxControl" then you can access it in you dropdownlist handler as shown below :
Protected Sub ListBox3_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles ListBox3.SelectedIndexChanged
Dim test As String = ListBox3.Text
Dim page As _Default = DirectCast(Me.Page, _Default)
page.TextBoxControl.Text = "Some Text"
End Sub
(I am not well versed with vb.net so syntax may be wrong at some places)

My suggestion is to use a bubble event:
Protected Sub ListBox3_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles ListBox3.SelectedIndexChanged
Dim test As String = ListBox3.Text
// this line is in C#. I don't know how it is in VB
RaiseBubbleEvent( this, new CommandEventArgs( "ListBoxText", test ) );
End Sub
this is all in C#!! here is your method in your aspx-page:
protected override bool OnBubbleEvent( object source, EventArgs args )
{
// you can check in addition whether the source is of type of your user control
if ( args is CommandEventArgs )
{
lbl1LoginPage.Text = ((CommandEventArgs)args ).CommandArgument.ToString();
return true;
}
return base.OnBubbleEvent( source, args );
}

UserControl should not call Parent page. It is not a good design.
Instead, you want to bubble up the event from UserControl to the Parent page.
Here is the example -
Child
<asp:ListBox runat="server" ID="ListBox3"
OnSelectedIndexChanged="ListBox3_SelectedIndexChanged"
AutoPostBack="True">
<asp:ListItem>Item 1</asp:ListItem>
<asp:ListItem>Item 2</asp:ListItem>
</asp:ListBox>
Public Partial Class Child
Inherits System.Web.UI.UserControl
Public Event ListBox3SelectedIndexChanged As EventHandler
Protected Sub ListBox3_SelectedIndexChanged(sender As Object, e As EventArgs)
RaiseEvent ListBox3SelectedIndexChanged(sender, e)
End Sub
End Class
Parent
<%# Register Src="~/Child.ascx" TagName="Child" TagPrefix="uc1" %>
...
<uc1:Child ID="Child1" runat="server"
OnListBox3SelectedIndexChanged="Child1_ListBox3SelectedIndexChanged" />
Protected Sub Child1_ListBox3SelectedIndexChanged(sender As Object,
e As EventArgs)
Dim listBox3 = TryCast(sender, ListBox)
If listBox3 IsNot Nothing Then
Dim selectedText As String = listBox3.SelectedItem.Text
End If
End Sub

Related

Gridview rowcommand event not firing in dynamically added usercontrol

I have a usercontrol with gridview and rowcommand event.
This usercontrol is added dynamically using LoadControl on a button click of a page. The gridview's rowcommand doesn't fire.
Here is the code that loads the usercontrol on button click:
Protected Sub btnSearch_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnSearch.Click
'<ucTitle:SearchList ID="ucSearchList" runat="server" Visible="false" />
Dim ucSearchList As TitleSearchList = LoadControl("~/Controls/TitleSearchList.ascx")
ucSearchList.ISBN = txtSearchISBN.Text
ucSearchList.LoadTitleSearchList()
pnlSearchResults.Controls.Add(ucSearchList)
End Sub
And here is the code in usercontrol
Public Class TitleSearchList
Inherits System.Web.UI.UserControl
Public Property ISBN As String
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not IsPostBack Then
LoadTitleSearchList()
End If
End Sub
Public Sub LoadTitleSearchList()
Dim _isbn As String = ISBN
Dim titles As New List(Of Title)
titles = New List(Of Title) From {
New Title With {.ISBN = _isbn, .TitleName = "Title check"},
New Title With {.ISBN = _isbn, .TitleName = "Title check"},
New Title With {.ISBN = _isbn, .TitleName = "Title check"},
New Title With {.ISBN = _isbn, .TitleName = "Title check"}
}
gvTitle.DataSource = titles
gvTitle.DataBind()
End Sub
Public Sub gvTitle_Rowcommand(ByVal sender As Object, ByVal e As GridViewCommandEventArgs) Handles gvTitle.RowCommand
If e.CommandName = "TitleDetail" Then
Response.Redirect("TitleSearch.aspx?isbn=" & e.CommandArgument().ToString())
End If
End Sub
End Class
Events in GridViews that are added dynamically in a UserControl get a little ugly. Since UserControls that are added dynamically have to be re-added on the post-back, you have to rebind the GridView DataSource, which makes you lose out on automatically getting those Events fired for you. That being said, you can still pull it off with some parsing of the __EVENTTARGET of the Form.
Add a HiddenField that tells you whether or not you need to re-add the UserControl. Add this in your Page_Load Event Handler:
If CBool(hdnTitleSearchActive.Value) = True Then
AddSearchListToPanel()
End If
Call AddSearchListToPanel() in your btnSearch_Click Event Handler.
Now this implementation of AddSearchListToPanel can be cleaned up some, but this should be good enough to get you going. Note that the Button triggering the GridView Command in my example has the ID of lbtTest. You will have to adjust based on the ID that you are using.
Private Sub AddSearchListToPanel()
Dim ucSearchList As TitleSearchList = LoadControl("~/Controls/TitleSearchList.ascx")
ucSearchList.ISBN = txtSearchISBN.Text
ucSearchList.LoadTitleSearchList()
pnlSearchResults.Controls.Add(ucSearchList)
hdnTitleSearchActive.Value = True
Dim strEventTarget As String = HttpContext.Current.Request.Form("__EVENTTARGET")
If Not strEventTarget Is Nothing AndAlso strEventTarget.Contains("gvTitle$") AndAlso _
strEventTarget.Contains("$lbtTest") Then
'Value example = gvTitle$ctl02$lbtTest
Dim intRowNumber As Integer = (CInt(strEventTarget.Substring(11, 2)) - 1)
Dim lbtCommandSource As LinkButton = CType(CType(ucSearchList.FindControl("gvTitle"), GridView).Rows(intRowNumber).FindControl("lbtTest"), LinkButton)
Dim objCommandEventArguments As New CommandEventArgs(lbtCommandSource.CommandName, lbtCommandSource.CommandArgument)
Dim objGridViewCommandEventArgs As New GridViewCommandEventArgs(lbtCommandSource, objCommandEventArguments)
ucSearchList.gvTitle_Rowcommand(lbtCommandSource, objGridViewCommandEventArgs)
End If
End Sub

How to create a User Control on button click in asp.net using vb

The control that I want to use is already registered in my page.
<%# Register Src="~/MEDCONTROLS/statform.ascx" TagPrefix="uc1" TagName="statform" %>
and i am displaying it in my page using this code. (using different id's && different TempHosp#)
<uc1:statform runat="server" TempHospNum="ER101" ID="statform1" />
<uc1:statform runat="server" TempHospNum="ER102" ID="statform2" />
<uc1:statform runat="server" TempHospNum="ER103" ID="statform3" />
Now what I need to do is, on the click button event, it will create a new user control, actually same user control but only different id and different property eg.
EDIT
Protected Sub btnAddUserControl_Click(sender As Object, e As EventArgs) Handles btnAddUserControl.Click
'Generate user control with a TempHospnum = "ER104" and id="statform4"
End Sub
Now it is adding BUT in page.init only, NOT on Button_click
'NOT WORKING
Protected Sub btnNewBed_Click(sender As Object, e As EventArgs) Handles btnNewBed.Click
Dim myControl As statform = Page.LoadControl("~/MEDCONTROLS/statform.ascx")
myControl.ID = "statform13"
myControl.TempHospNum = "ER113"
myControl.ERBedNumber = "Bed13"
form1.Controls.Add(myControl)
myControl.Visible = True
End Sub
'This is working but this is not what I needed
Protected Sub Page_Init(sender As Object, e As EventArgs) Handles Me.Init
Dim myControl As statform = Page.LoadControl("~/MEDCONTROLS/statform.ascx")
myControl.ID = "statform13"
myControl.TempHospNum = "ER113"
myControl.ERBedNumber = "Bed13"
form1.Controls.Add(myControl)
myControl.Visible = True
End Sub
Use a variable which references the class name of the user control, and use Page.LoadControl.
You can interact with any properties you add to the user control class definition.
dim myControl as YourUserControlClassName = Page.LoadControl("~/yourlayoutfilepath/yourUserControlFile.ascx")
myControl.ID="stratFormX"
Me.Controls.Add(myControl)

Visual Studio Have to Click Button Twice

I'm trying to write code that will, at the click of a button, push a string variable onto a page and then open that page. The trouble that I am running into is that variable, a button's text, is nested within a gridview, making accessing it difficult. It is also difficult because I am importing it from an SQL database into the Gridview, so I cannot access it directly from there either. It works with my current code if I use the button's onClick event, but then for some reason I have to click the button twice in order for it to work. I have read on here to instead use the onPreRender event, but that interferes with pushing the string variable onto the page, and I can't have that. Is there any other way to get rid of having to click the button twice that doesn't involve the onPreRender event?
Here is the code:
Imports System.Data.SqlClient
Imports System.IO
Partial Class PartsLookup
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Private Function FindControlRecursive(ByVal RootControl As Control, ByVal ControlID As String) As Control
If RootControl.ID = ControlID Then
Return RootControl
End If
For Each controlToSearch As Control In RootControl.Controls
Dim controlToReturn As Control = FindControlRecursive(controlToSearch, ControlID)
If controlToReturn IsNot Nothing Then
Return controlToReturn
End If
Next
Return Nothing
End Function
Protected Sub Button1Click(ByVal sender As Object, ByVal e As System.EventArgs)
Dim clickedButton As Button = sender
MsgBox(clickedButton.Text)
Dim ControlText As Control = FindControlRecursive(GridView1, clickedButton.ID)
Dim ControlText1 As Button = ControlText
Dim MachineNumber As String = ControlText1.Text
If MachineNumber = "" Then
ControlText1.Visible = False
End If
Dim SpecificPart() As String = {String that is the files contents, the middle of which is where the variable will be pushed to}
Dim path As String = "File path where the variable is to be pushed to"
File.WriteAllLines(path, SpecificPart)
clickedButton.PostBackUrl = "~/PartNumberPages/PartTemplate.aspx"
End Sub
End Class

Using parameters in a code behind vb.net file on a DataSource to prevent injection attacks

We would like to change the following coding so it will use parameters to prevent injection attacks.
Here is the code in the Public Class area:
Public Class Parents1
Inherits System.Web.UI.Page
Dim theTableAdapter As New DataSetParentsSummaryTableAdapters.ParentsSummaryTableAdapter
Here is what we have in the page_load:
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
GridViewParentsSummary.DataSource = theTableAdapter.GetData("ALL")
End Sub
Here is the code used to load a GridView with data from a Search button click:
Protected Sub ButtonSearch_Click(sender As Object, e As EventArgs) Handles ButtonSearch.Click
GridViewParentsSummary.DataSource = theTableAdapter.GetData(TextBoxSearch.Text)
End Sub
Can you show the needed code required to use parameters?

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.

Resources