I have a lable I want to update on a web form page from another class. I created an instance of that class then referenced a public method to do the update since I was unable to access the lable control directly. But when it reaches the public method it seems as if the controls were initialized and are not recognizable.
*...' calling class*
dim kws as new form2class
kws.setErrorLable("ERROR FOUND" & ex.message.tostring)
.....
called class
public sub serrorLable(Byval msg as string)
label10.text=msg
end sub
Am I missing something here? Thanks in advance
You can access the current page like this:
Page currentPage = (Page)HttpContext.Current.Handler;
Depending on where the label is in the page, you may need to use recursion to find the Label, but the above code will get you to the current page.
Related
So, i want to do what I feel should be such a simple task... pass in a parameter to a constructor using Autofac!
However, I have managed to get a work around working, but just dont think this is correct, I feel i am chaning too much of the recommended code from the Autofac guides
I am more than happy for answers in C# or VB.net it doesnt matter, the location of code is all the same
So, here is my setup (im not fussed about neatness, just trying to get this to work for now)
In my global.asax I have:
'***Note, the autofac guide had this a a private shared, see below for why i changed it***
' Provider that holds the application container.
Public Shared _containerProvider As IContainerProvider
' Instance property that will be used by Autofac HttpModules
' to resolve And inject dependencies.
Public ReadOnly Property ContainerProvider As IContainerProvider Implements IContainerProviderAccessor.ContainerProvider
Get
Return _containerProvider
End Get
End Property
then within my global.asax within application_start I have:
***again, note, originally I was using IMyClass when registering type... not sure this or that is correct***
Dim builder As New ContainerBuilder()
builder.RegisterType(Of MyClass)().As(Of MyClass)().InstancePerLifetimeScope()
'... continue registering dependencies...
' Once you're done registering things, set the container
' provider up with your registrations.
_containerProvider = New ContainerProvider(builder.Build())
As you can see, origianly the _containerProvider was just public, but I have had to make it "Shared" for this to work, this feels wrong right away!
so, now, in my webForm1.aspx.vb I have this:
Public Property MyClass2 As IMyClass
Private _myClass As IMyClass
Now, because I have adjusted the global to "registerType" to use the actual object, not the interface (which, again seems wrong having to change that too), means now my webform public property is not being set (but, because of my work around, i dont need that anyway)
Also, note the private _myClass... this is for my workaround
so, now in my Webform init method, i have the following:
WebForm1.aspx.vb*
_myClass = [Global]._containerProvider.RequestLifetime.Resolve(Of MyClass)(New TypedParameter(GetType(HttpRequest), Request))
which now instantiates my _myClass with the parameter correctly injected in... this is great, whoopadeedoo
...but... I dont think this is correct.
Now, when I didnt need to pass in a parameter to the construtor, it all worked nice, didnt need to change any of the code from the autofac guide, it just worked, set the public property on my webform.aspx page fine, was really nice.
But, as soon as I start to work with a paramter being passed into the construtor, it seems everything needs to be tweaked so it will work? is this correct?
I have even tried the deligate guide from autofac, but that also doesnt work for me at all by doing this within my webForm.aspx page:
Dim container As ILifetimeScope = [Global]._containerProvider.RequestLifetime
Dim myClassFactory As MyClass = container.Resolve(Of MyClass.Factory)
Dim myClassholding As MyClass = myClassFactory.Invoke("ABC")
even tried without the "Invoke", but "cannot be indexed because it has no default property"
Just incase it helps, here is "myClass"
Private _myID as integer
Public Delegate Sub Factory(myID As integer)
Sub New()
End Sub
Sub New(myID As integer)
_myID = myID
End Sub
Public Sub DoSomething() Implements IDfCookieManager.DoSomething
'do something with myID
End Sub
I know I can pass the id in as a parameter to DoSomething, but i want to understand how to pass this into the constructor
so, my questions:
If this is not how to do this (which I am hoping its not correct), how would I do this without needing to change all the global setup??
Is it best to use a deligate factory or just resolve?
do I really need to change the global container to be shared/static, so that i can access the container from within my code?
So, there are two ways, but firstly, shouldnt need to mess around with how Autofac suggests setting up the ContainerProvider in global.asax... i can keep it as non shared (not static), and to access this value I do the following:
Dim cpa As IContainerProviderAccessor = (CType(HttpContext.Current.ApplicationInstance, IContainerProviderAccessor))
Dim scope As ILifetimeScope = cpa.ContainerProvider.RequestLifetime
Also, in our webform.aspx page, Public Property MyClass As IMyClass should not be added when we need to pass in parameters to the constructor when resolving (otherwise it will be resolved before we try to manually resolve it!
1: Passing in using TypedParameter
Here is my adjusted code to pass in the parameters using resolve (including the lines above):
Dim cpa As IContainerProviderAccessor = (CType(HttpContext.Current.ApplicationInstance, IContainerProviderAccessor))
Dim scope As ILifetimeScope = cpa.ContainerProvider.RequestLifetime
Dim myClass As MyClass = scope.Resolve(Of IMyClass)(New TypedParameter(GetType(Integer), 123))
Also, having the public property at the top of my WebForm1.aspx needed to be removed, because that will auto resolve, meaning, if i try to "resolve" the object manually, it has already been automatically resolved by autofac (which is why i thought my code wasnt working initially), and has already instantiated the object with the empty constructor!
2: Using a Deligate Factory
the line Public Delegate Sub Factory(myID As integer) isnt correct, it should use a function for Autofac to automaticly set this up! so should be: Public Delegate Function Factory(myID As integer) as MyClass
In Global.asax, I just need to add this builder.RegisterType(Of MyClass)().InstancePerLifetimeScope(), because we require a parameter and using a factory, we cant append the .As(Of IMyClass)
Finally, our webform1.aspx.vb just needs this:
Dim cpa As IContainerProviderAccessor = (CType(HttpContext.Current.ApplicationInstance, IContainerProviderAccessor))
Dim scope As ILifetimeScope = cpa.ContainerProvider.RequestLifetime
Dim myClassFactory As MyClass.Factory = scope.Resolve(Of MyClass.Factory)
_myClass = myClassFactory.Invoke(123)
however, I tweaked that slightly to this:
Dim cpa As IContainerProviderAccessor = (CType(HttpContext.Current.ApplicationInstance, IContainerProviderAccessor))
Dim scope As ILifetimeScope = cpa.ContainerProvider.RequestLifetime
Dim myClass As MyClass = scope.Resolve(Of MyClass.Factory).Invoke(123)
I need your help for an issue about inheritance.
In a project of mine I am using a the SyndicationFeed .net class to read several feed a make a ul of its elements.
For every element I want to show the feed's image as well, so I wanted to assign the same ImageUrl property of the feed to the single item.
So I started by creating a derived class:
Public Class SyndicationItemWImage
Inherits SyndicationItem
Private mItemImage As Uri
Public Property ItemImage As Uri
Get
Return mItemImage
End Get
Set(value As Uri)
mItemImage = value
End Set
End Property
End Class
Then I would initialize the object and populate it
Dim BlogsPostsWImage As List(Of SyndicationItemWImage)
BlogsPostsWImage = New List(Of SyndicationItemWImage)
…
[initialize SyndFeed]
…
BlogsPostsWImage.AddRange(SyndFeed.Items.ToList.GetRange(0, 10))
Where SynFeed is a well working SyndicationFeed object.
Unfortunately I get an error that the cast is invalid:
System.InvalidCastException: Unable to cast object of type 'System.Collections.Generic.List1[System.ServiceModel.Syndication.SyndicationItem]' to type 'System.Collections.Generic.IEnumerable1[lucamauricom.SyndicationItemWImage]'. at lucamauricom._default.Page_Load(Object sender, EventArgs e)
I do not understand why: shouldn't the cast from a parent class to a child one be allowed?
I think I am missing something fundamental here… not sure what.
Thanks for any help you can provide.
Unfortunately nobody appears to be able to help me with this, so I went on attacking the problem from another angle: I now have an alternative method to accomplish the same goal. I am answering my own question here to document it.
Starting from the same SynFeed as above, I filled a temporary List and then I added an ElementExtension:
Dim TempItems As New List(Of SyndicationItem)
If SyndFeed.Items.Count >= CurrentFeed.TotalElements Then
TempItems.AddRange(SyndFeed.Items.ToList.GetRange(0, CurrentFeed.TotalElements))
Else
TempItems.AddRange(SyndFeed.Items.ToList)
End If
For Each CurrItem As SyndicationItem In TempItems
CurrItem.ElementExtensions.Add("favico", "", SingleFeed.Descendants("//bits.wikimedia.org/favicon/wikipedia.ico")
Next
FeedItems.AddRange(TempItems)
The ElementExtension is called favico, it contains no namespace and has value //bits.wikimedia.org/favicon/wikipedia.ico.
This way, I added the data as a sort of "custom field" that can be easily read on the ASPX page like this:
<img src='<%#CType(Container.DataItem, SyndicationItem).ElementExtensions.ReadElementExtensions(Of String)("favico", "").Item(0).ToString%>' height="16" />
I still cannot figure out what is wrong with the derived class of my original idea, but this second way of dealing with the issue is probably better within the context of Syndication class.
I have many aspx pages which inherits a base Class.
base class has a method name "GetGroupID", This method returns different data depends which page i am on, now few pages need to override this method (which is fine).
Problem:
I have user control which is placed in almost all pages, now this user control Accessess GetGroupID method from page base class, which is fine as long as i know page class name, since I have so many pages, one base class and one user control...it would be niceif I can get Page Class name from UserControl and execute the base method dynamically.
Curreny I have following code which works within UserControl
Dim c As homepage = CType(Me.Page, homepage)
Call c.getGroupID
However in above example I know the Page Class name (homepage), but lets say i am on a different page which has a classname "portal", it would be impossible for me to keep track of so many pages.
I would like to excute the method in base class within user control, and I would like to override this method for certain pages.
please advise.
You could let the base-page implement a custom interface, for example IGroupable with a method GetgroupId. Then you only have to know in the UserControl that it's Page is IGroupable(either directly or through inheritance) and you know for sure that it has a method GetgroupId.
Public Interface IGroupable
Function GetGroupId() As Int32
End Interface
Class BasePage
Inherits Page
Implements IGroupable
Public Overridable Function GetGroupId() As Integer Implements IGroupable.GetGroupId
Return 1
End Function
End Class
Class ChildPage
Inherits BasePage
' default implementation of GetGroupId from base page '
End Class
Class SpecialPage
Inherits BasePage
' override it here since it has a different implementation than in the base page '
Public Overrides Function GetGroupId() As Integer
Return 2
End Function
End Class
You get the id in the UserControl in this way:
Class UserControl1
Inherits UserControl
Dim id As Int32 = DirectCast(Me.Page, IGroupable).GetGroupId()
End Class
I've created a function in my vb class file that creates dynamic tables. I'm planning to use this to create tables dependent on a button being clicked. The function references a placeholder in my aspx page but I'm getting "placeHolder1 is not declared".
How can I access controls on my form from my class file?
Thanks
Class file snippet as follows:
Public Shared Function CreateTable() As Table
'handle either total or breakdown
Select Case format
Case "breakdown"
placePayDetails.Controls.Clear()
Dim tblPayDetails As Table = New Table()
placePayDetails.Controls.Add(tblPayDetails)
etc
According to your updated version of the question, your CreateTable function needs to receive a placePayDetails (presumably of type ContentPlaceHolder) as parameter.
The page calling this function needs to have this place holder defined somewhere in the markup.
Example:
Public Shared Function CreateTable(byVal placePayDetails as ContentPlaceHolder) As Table
'handle either total or breakdown
Select Case format
Case "breakdown"
placePayDetails.Controls.Clear()
Dim tblPayDetails As Table = New Table()
placePayDetails.Controls.Add(tblPayDetails)
the class file has no concept of your page. if you have a function in your class where you want the results of that function to return to the page, on the aspx backend have the function's results returned to as string and then set the contents
Dim tblPayDetails As Table = DoSomething()
placePayDetails.Controls.Add(tblPayDetails)
how can i access a public function in an .ascx file using C#?
Thanks
If the function is not static you will need to first obtain an instance of the class containing the function and then invoke the function on this instance. For example:
<%
// obtain an instance of the type containing the function
Foo instance = new Foo();
// invoke the function on this instance
string result = instance.Bar();
%>
Obviously it would be better to do this in the code behind file instead of polluting your markup.
Like other public functions in .NET Framework - via object reference. But sometimes Visual Studio doesn't automatically see your User Control's public members. Try to rebuild your user control and the site if IntelliSense window doesn't show it to you.
Where are you calling the function from? The containing page? Masterpage? Parent control? The control itself? Regardless, you'll need to somehow obtain a reference to the control instance (unless the method is static) in order to invoke this method. And the type of your reference must match that of the class that defines the method.
Edit:
MyControl myControl = (MyControl)Page.FindControl("Id_Of_The_Control");
if (myControl != null)
{
myControl.TheMethod();
}
if you don't want to add your ascx control into a placeholder programmatically, just implement IAttributeAccessor and IUserControlDesignerAccessor interfaces to your user control class like;
public partial class yourascxclassname: System.Web.UI.UserControl, IAttributeAccessor, IUserControlDesignerAccessor
you can access only public members of your ascx control.