Trying to access a property from the parent page on my user control.
Here's the start of my default.asp codebehind:
Partial Class _Default
Inherits System.Web.UI.Page
Private _selectedID As String = "74251BK3232"
Public Property SelectedID() As String
Get
Return _selectedID
End Get
Set(ByVal value As String)
_selectedID = value
End Set
End Property
Here's the start of my user control codebehind:
Partial Class ctrlAddAttribute
Inherits System.Web.UI.UserControl
Dim selectedID As String = Me.Parent.Page.selectedID()
I'm getting the error "selectedID is not a member of System.Web.UI.Page"
Please adivse!
You could access the property when you cast the Page to your actual implementaion called _Default.
Dim selectedID As String = DirectCast(Me.Page,_Default).selectedID()
But that is not the purpose of a Usercontrol(reusability).
Normally you would give the ID from the Controller(page) to the UserControl.
So define a property in the UserControl and set it from the page.
On this way the UserControl would still work in other pages.
Because the user control doesn't belong to the page, you can't access it directly unless you either explicitly set a property in the usercontrol from the including page or create a recursive function that cycles through all of the parent objects until it finds an object of type System.Web.UI.Page.
For the first, you could use a property (I've done this using a property called ParentForm) in the user control:
Private _parentForm as System.Web.UI.Page
Public Property ParentForm() As System.Web.UI.Page ' or the type of your page baseclass
Get
Return _parentForm
End Get
Set
_parentForm = value
End Set
End Property
In the "Parent" page, you would set this property in an event as early as possible. I prefer to use PreLoad because it comes before the load (thus is available when most other controls would need it) and after the init.
Protected Sub Page_PreLoad(ByVal sender as Object, ByVal e as EventArgs) Handles Me.PreLoad
Me.myUserControlID.ParentForm = Me
End Sub
You could also write a function trolls through the parent controls to find the page. Following code is untested so it may require tweaking, but the idea is sound.
Public Shared Function FindParentPage(ByRef ctrl As Object) As Page
If "System.Web.UI.Page".Equals(ctrl.GetType().FullName, StringComparison.OrdinalIgnoreCase) Then
Return ctrl
Else
Return FindParentPage(ctrl.Parent)
End If
End Function
EDIT: You also can't access this property directly because it does not exist within the type System.Web.UI.Page. As #Tim Schmelter recommends, you can either attempt to cast the page to the specific page type _Default or if this is something common to many of your pages, you may need to create a base page class and include your property in that class. Then you can inherit this class instead of System.Web.UI.Page
Public Class MyBasePage
Inherits System.Web.UI.Page
Public Property SelectedID() as Integer
...
End Property
End Class
Then in the page:
Partial Class _Default
Inherits MyBasePage
...
End Class
Related
I am tired of creating a System.Web.UI.LiteralControl everytime I need to add a control to my in webforms. So, I decided that it would help me if I created a custom LiteralControl that initialized with that value.
So, I created this very simple class:
Public Class ScriptLiteralControl
Inherits System.Web.UI.LiteralControl
Private _Text As String
Public Sub New()
Me.InitControl()
End Sub
Private Sub InitControl()
Me._Text = "<script type=""text/none""></script>"
End Sub
Public Overrides Property Text As String
Get
Return Me._Text
End Get
Set(value As String)
Me._Text = value
End Set
End Property
End Class
But when I do this in my webpages:
dim slc as New ScriptLiteralControl
Me.Header.Controls.Add(slc)
Absolutely nothing gets added.
According to the ASP.NET documentation I've read, all I had to do was basically override the Text property in my implementation but that doesn't seem to be working.
Can someone tell me what obscure .net rule I am not following in my implementation?
You shouldn't have to override the Text property. I think that's what's causing your problem. Try this:
Public Class ScriptLiteralControl
Inherits System.Web.UI.LiteralControl
Public Sub New()
Me.Text = "Put your script text here"
End Sub
End Class
I'm trying to find a way in which I can create a collection of various webControl's and then add a "onClick" event handler to these various controls, i've tried creating a reimplementation of "webControl" with a registered "onClick" event but I get a typecast error. Could anyone suggest how I could achieve this.
exception:
Exception Details: System.InvalidCastException: Unable to cast object of type 'System.Web.UI.WebControls.RadioButtonList' to type 'Club.WebControlButton'.
new webControl class:
<System.Security.Permissions.PermissionSetAttribute(System.Security.Permissions.SecurityAction.Demand, Name:="FullTrust")> Public Class WebControlButton
Inherits WebControl
Implements IPostBackEventHandler
' Define the Click event.
Public Event Click As EventHandler
' Invoke delegates registered with the Click event.
Protected Overridable Sub OnClick(ByVal e As EventArgs)
RaiseEvent Click(Me, e)
End Sub
' Define the method of IPostBackEventHandler that raises change events.
Public Sub RaisePostBackEvent(ByVal eventArgument As String) _
Implements IPostBackEventHandler.RaisePostBackEvent
OnClick(New EventArgs())
End Sub
End Class
Private Sub AddOnClickStringsToElements()
Dim divider As Integer = If(onClickElements.Count > 0, onClickElements.Count, 1)
Dim percentIntervals As Integer = 100 / divider
For Each element As Tuple(Of String, WebControl, Integer) In onClickElements
If element.Item3 < 1 Then
element.Item2.Attributes("onClick") = GetAnimateJavascript(percentIntervals)
Else
element.Item2.Attributes("onClick") = GetAnimateJavascript(element.Item3)
End If
//throws typecast exception here
AddHandler CType(element.Item2, WebControlButton).Click, AddressOf UpdatePercent_OnClick
Next
End Sub
It looks like the onClickElements collection contains an actual RadioButtonList control, not a control which derives from your WebControlButton class.
Any control which you are putting into the onClickElements collection must derive from WebControlButton for that casting operation to work e.g.
Public Class MyRadioButtonList
Inherits WebControlButton
Protected Overrides Sub OnInit(ByVal e As System.EventArgs)
MyBase.OnInit(e)
' Create your radio button list here..
End Sub
End Class
An easier way would be to make an interface, such as IClickable...something a bit like this..sorry I didn't type it in VS so not sure if I got the syntax exact.
Public Interface IClickable
Public Event OnClick()
End Interface
Public Class MyRadioButtonList
Inherits RadioButtonList
Implements IClickable
Public Event OnClick Implements IClickable.OnClick
Private Sub RaiseOnClickEvent Handles Me.OnSelectedIndexChanged
RaiseEvent OnClick()
End Sub
End Class
And then..
For Each element As Tuple(Of String, WebControl, Integer) In onClickElements
If TypeOf(element.item2) Is IClickable Then
AddHandler CType(element.Item2, IClickable).OnClick, AddressOf UpdatePercent_OnClick
Else
Throw New Exception("A control of type IClickable was expected")
End If
Next
I want to pass a property of the type System.Uri to an WebControl from inside an aspx page.
Is it possible to pass the property like that:
<MyUserControl id="myusercontrol" runat="server">
<MyUrlProperty>
<System.Uri>http://myurl.com/</System.Uri>
</MyUrlProperty>
</MyUserControl>
instead of:
<MyUserControl id="myusercontrol" runat="server" MyUrlProperty="http://myurl.com/" />
which can't be casted from System.String to System.Uri
EDIT
The control is a sealed class and I don't want to modify it or write an own control. The goal is to set the url-property which is of the type System.Uri and not System.String.
To answer your actual question: no, you can't change the way you pass in the value of a property, like your example shows, without changing the code behind how that property is defined. Now on to your actual issue...
I didn't have any problem passing a string into a property of type URI on my user control and having it be auto converted from string to uri. Are you sure that the Uri you are passing in is valid? If the string you are passing in, like in a databinding scenario, wasn't properly formatted I could see this issue arising maybe.
Sample Code I used to test:
<uc1:WebUserControl ID="WebUserControl1" runat="server" MyUrlProperty="http://www.example.com" />
Code Behind:
Partial Class WebUserControl
Inherits System.Web.UI.UserControl
Public Property MyUrlProperty() As Uri
Get
Dim o As Object = ViewState("m")
If o IsNot Nothing Then
Return DirectCast(o, Uri)
Else
Return Nothing
End If
End Get
Set(ByVal value As Uri)
ViewState("m") = value
End Set
End Property
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Response.Write(MyUrlProperty)
End Sub
End Class
--Peter
I have a base master page that specifies the main layout template of a website. It also handles some logic that changes tabs depending on the section, and also sets page meta information.
I'm dynamically loading nested master pages by looking at the querystring, loading up a record from the database, and setting the nested master page dynamically based on a value found in that record. I need to load dynamic nested master pages for layout and functional differences.
There is additional information in that record that I want to use in the base master page and in the dynamically loaded master page so I can avoid additional database calls.
Currently, I have set up a class that inherits MasterPage to act as the base class for the base master page. I have a shared (static) property that holds the object representing the database call that I want to share between the base master page and the nested, dynamically called master page.
It works, but it seems a little ugly. Are there any other better solutions?
You could always pass the record in the HttpContext.Items collection. Once it is in the Items collection it is available to every thing that can reach the HttpContext for the duration of the request.
Ok, I had to sleep on this one a bit, but I came up with a cleaner solution. I ended up using a base class for the page, instead of a base class for the master page. The base page sets the meta that I was going to set in the base master page.
Public Class PageBase
Inherits Page
Private _DocDetails As FolderDocument
Public Overridable ReadOnly Property DocDetails() As FolderDocument
Get
Return _DocDetails
End Get
End Property
Private Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
If Not Page.IsPostBack() Then
SetMeta()
End If
End Sub
Protected Sub SetMeta()
If DocDetails IsNot Nothing Then
Page.Title = DocDetails.MetaTitle
If DocDetails.MetaKeywords <> String.Empty Then
Dim metaKeywords As New HtmlMeta()
metaKeywords.Name = "Keywords"
metaKeywords.Content = DocDetails.MetaKeywords
Page.Header.Controls.Add(metaKeywords)
End If
If DocDetails.MetaDescription <> String.Empty Then
Dim metaDescription As New HtmlMeta()
metaDescription.Name = "Description"
metaDescription.Content = DocDetails.MetaDescription
Page.Header.Controls.Add(metaDescription)
End If
End If
End Sub
End Class
..And then the aspx page inherits this base page and dynamically sets the master page.
<%# Page Language="VB" Inherits="PageBase" %>
<script runat="server">
Private _DocDetails As FolderDocument
Public Overrides ReadOnly Property DocDetails() As FolderDocument
Get
Return _DocDetails
End Get
End Property
Protected Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs)
_DocDetails = FolderDocuments.GetFolderDocument()
If _DocDetails IsNot Nothing Then
If _DocDetails.MasterPage <> "" Then
Me.MasterPageFile = String.Format("~/templates/{0}.master", _DocDetails.MasterPage)
End If
End If
End Sub
</script>
...and in the dynamically called master page I can reference the page's base class by casting:
Dim parentPage As PageBase = DirectCast(Page, PageBase)
Response.write(parentPage.DocDetails.Title)
I'm getting an error in .net when trying to declare a Public class on my code behind page.
Partial Class _Default
Inherits System.Web.UI.Page
Public someVariable as integer
Public someClass as className
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load [...]
The error I'm getting is BC30508: 'someClass' cannot expose type 'className' in namespace '<Default>' through class '_Default'.
The goal here is accessing the class properties in script blocks on the aspx page like this <%=someClass.classProperty%>
I'm not sure if I'm trying the right methods (I've tried several ways of declaring the public class) or if it can even be done... Thanks for taking a look at it.
Check the protection level of your className type. Did you forget to mark it public?
That error message means you have something that is has restricted access, and you are trying to use it in a way that would allow access outside the restrictions. For example, if your className type is internal or a private child class of _Default, but you add a public member of that type as a property your assembly would expose a type as part of it's interface that is otherwise unusable.
It's almost certainly the declaration of your "className" class. Try setting it to public.
Check the protection level of the _Default class. It might not be setup as a partial class and that will result in your protection level issue that you are seeing.