I have a Custom.ascx file that is used on a number of pages. Custom.ascx contains a couple of controls and a button called cmdCustomPageButton.
When the user click on cmdCustomPageButton, cmdCustomPageButton executes a Protected Sub that gets some data from a database.
Page1.aspx that is using Custom.ascx has its own set of controls and procedures that it executes. It contains a button called cmdPage1Button and a procedure called RetriveData that is being called by other procedures as well within Page1.aspx.
When cmdPage1Button is clicked it calls RetriveData. RetriveData is only applicable to Page1.aspx. Page2.aspx and Page3.aspx both has a procedure similar to RetriveData but is only relevant to its own page.
Try to explain using code
Custom.ascx
Public Class Custom
Protected Sub cmdCustomPageButton_Click(Byval sender as Object, ByVal e as EventArgs) Handels cmdCustomPageButton_Click
//Code that gets data from the database
End Class
Page1.aspx
Public Class Page1
Protected Sub cmdPage1Button_Click(Byval sender as Object, ByVal e as EventArgs) Handels cmdPage1Button_Click_Click
//Some code
RetriveData()
End Sub
Sub RetriveData()
//Some code
End Sub
End Class
The question.
How do I call the different RetriveData procedure form the relevant pages being it Page1, Page2 or Page3 when cmdCustomPageButton is clicked ??
Please refer this link below which has a better idea to a query similar to yours.
Calling a method in parent page from user control
In short, create a event delegate in your user control and handle the event in each of your page where the user control is used. Incase if the button in user control is clicked, the event will be fired in the respective parent page and you can call the RetriveData method in that event. Sorry, if your query was misunderstood.
The MyUserControl.ascx page code.
Public Class MyUserControl
Inherits System.Web.UI.UserControl
Public Event UserControlButtonClicked As EventHandler
Private Sub OnUserControlButtonClick()
RaiseEvent UserControlButtonClicked(Me, EventArgs.Empty)
End Sub
Protected Sub TheButton_Click(ByVal sender As Object, ByVal e As EventArgs)
' .... do stuff then fire off the event
OnUserControlButtonClick
End Sub
End Class
The Default.aspx page code
Public Class _Default
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs)
' hook up event handler for exposed user control event
AddHandler MyUserControl.UserControlButtonClicked, AddressOf Me.MyUserControl_UserControlButtonClicked
End Sub
Private Sub MyUserControl_UserControlButtonClicked(ByVal sender As Object, ByVal e As EventArgs)
' ... do something when event is fired
End Sub
End Class
All credit gos to clklachu for pointing me in the right direction.
Conversion done by the following website link
Thanks
Related
Im trying to create buttons on page load and have event controls to those. Im able to create the buttons but the event doesnt seem to be triggered when the button is clicked instead it throws an error stating multiple controls with id found.I think this has something to do with postback and unique ID creation for the buttons. can some one point me as to what to be added along with this?
Sub createbutton()
Dim but As New Button
but.Text = "save"
but.ID = "but"
AddHandler but.Click, AddressOf Button_Click
Me.form1.Controls.Add(but)
End Sub
The event control for this is as below.
Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
' Handle your Button clicks here
MsgBox("done")
End Sub
Im getting the error
Multiple controls with the same ID '1' were found
The subroutine createbutton works on page load as follows.
Public Class Default3
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load ' to gen page on load ;)
createbutton()
End Sub
Help is appreciated , Thanks :)
i think you are a guy who worked a lot with VB 6.0
Control array feature is available in VB 6.0
in VB.net everything is depend upon control ID.
if you don't have specific requirement like ID should be same then i suggest pls append prefix and incremental ID would resolve your issue.
Let me know if you have some specific requirements
Thanks
Asif
Corrected Code, Instead of ID it's name which allow uniqueness
Public Class Form1
Private Sub Button_Click(ByVal sender As System.Object, ByVal e As System.EventArgs)
' Handle your Button clicks here
MsgBox("done")
End Sub
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
createbutton()
End Sub
Sub createbutton()
Dim but As New Button
but.Text = "save"
but.Name = "but"
AddHandler but.Click, AddressOf Button_Click
Me.Controls.Add(but)
End Sub
End Class
The following method is return an error: 'Event init cannot be found' and get error on System.Web.UI.Page
Visual Studio 2010, framework 3.5
Public Class_default
Inherits System.Web.UI.Page
Private Sub Page_Init(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Init
End Sub
I am not VB.NET expert (I am writing on C#) but i can say that the cause of the problem is that you need to override OnInit method instead of Page_Init.
So, you need to use the following code:
Public Class _Default
Inherits System.Web.UI.Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
Protected Friend Overrides Sub OnInit(ByVal e As EventArgs)
MyBase.OnInit(e)
End Sub
End Class
I think Maxim is correct, however you can also add your event handler by doing:
AddHandler Me.Init, AddressOf Page_Init
I think that's right, sorry my VB is pretty rusty.
Well,
I assume you are using AutoEventWireup="true" in your markup but you have also marked your handler with the Handles keyword.
AutoEventWireup won't work, its not able to access private members of your class directly.
Set AutoEventWireup="false" and save its needless performance penalty, the handler should still fire because it explicitly Handles the Page.Init event.
Since you're handling the event explicitly you are also free to change the name of the event handler and remove the ugly _.
The majority of your Crystal Reports code is likely in the Page_Load event. If you move it to the Page_Init you'll find it works correctly.
Question in Brief*
When raising an event in a top level master page through one or more nested master pages, do you need to catch the event in the nested master page(s) and re-raise it? If not, what is the better approach to take?
* This is the question I'm hoping to have answered on SO.SE - the rest is just for more background information to help explain it.
Detailed Question, with Examples
An event in a masterpage (let's call it "TopLevel.master") needs to fire through all nested master pages (let's assume there's just one and call it "MidLevel.master") to the page itself (Page.aspx). What I'm doing (below) works fine, but I'm concerned that I'm using the wrong approach and this will end up biting me in the derriere at some point in the future (e.g. when I come to maintain the code). It may also be a more costly approach, as several additional events are being created where they may not be needed.
Each nested master page and the page itself has a #MasterType declaration, so public properties, methods and events of the master pages are available via the code behind.
So far, I have something along the lines of (simplified for brevity):
TopLevel.master:
' A public event available from this master page
Public Event MyEvent(sender As Object, e As EventArgs)
' A function that can be called via "Master.DoSomething" to initiate the process
Public Sub DoSomething(someArgs As Object)
Me._DoSomething(someArgs)
End Sub
' A local function that starts the process. SomeEventFiringObject is
' just an object that fires an event when the process is complete.
Private Sub _DoSomething(someArgs As Object)
_someEventFiringObject.DoSomething(someArgs)
End Sub
' A local function that handles the process-complete event fired by
' SomeEventFiringObject and fires my public masterpage event
Private Sub Me_HandleEvent(sender As Object, e As EventArgs) Handles _someEventFiringObject.HasDoneSomething
RaiseEvent MyEvent(sender, e)
End Sub
MidLevel.master:
' Handle the event from the masterpage.
Private Sub Page_Init(sender As Object, e As EventArgs) Handles Me.Init
AddHandler Master.MyEvent, AddressOf Master_MyEvent
End Sub
' A public event available from this master page
' NOTE: This is essentially the same event as in the TopLevel master page.
Public Event MyEvent(sender As Object, e As EventArgs)
' A function that can be called via "Master.DoSomething" to initiate the process
' NOTE: Just passing this up to the TopLevel master page.
Public Sub DoSomething(someArgs As Object)
Master.DoSomething(someArgs)
End Sub
' A local function that re-raises the event from this master page
' NOTE: Handler added on Page.Init.
Private Sub Master_MyEvent(sender As Object, e As EventArgs)
RaiseEvent MyEvent(sender, e)
End Sub
Page.aspx:
' EDIT: This needs to be done on Page.Init as well.
Private Sub Page_Init(sender As Object, e As EventArgs) Handles Me.Init
AddHandler Master.MyEvent, AddressOf Master_MyEvent
End Sub
' Some process initiation (button click in this example could be anything)
' The master page does the deed and will eventually raise the MyEvent event.
Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
Master.DoSomething(someArgs)
End Sub
' The page handles the master MyEvent event (which is actually from MidLevel.master)
Private Sub Master_MyEvent(sender As Object, e As EventArgs)
' Finally I can do something with this event
End Sub
The Question:
It seems to me that there must be some way to access the MyEvent event fired in the TopLevel master page without having to effectively catch it in the MidLevel master page, then create a new event and copy it to send it on, but I can't seem to work it out. Is there a way to do this? Or is the approach I've taken valid enough?
My concern is that I actually have two layers of master pages within MidLevel.master, so there seems to be a lot of copied code and several events being created for seemingly no reason other than to pass the event on.
Ok, the first that you need is to create interface describing common functionality of your master pages. Something like this:
public interface IMaster
{
event EventHandler MyEvent;
}
The in top master page inherited from this interface define your event:
private static readonly object MyEventObject = new object();
public event EventHandler MyEvent
{
add
{
Events.AddHandler(MyEventObject, value);
}
remove
{
Events.RemoveHandler(MyEventObject, value);
}
}
private void RaiseMyEvent()
{
var handler = Events[MyEventObject] as EventHandler;
if (handler != null)
{
handler(this, EventArgs.Empty);
}
}
Then define event in nested master page but delegate adding it to invocation list to parent
public event EventHandler MyEvent
{
add
{
((IMaster)Master).MyEvent += value;
}
remove
{
((IMaster)Master).MyEvent -= value;
}
}
After all these steps you may use this event on page:
protected void Page_Init(object sender, EventArgs e)
{
((IMaster)Master).MyEvent += new EventHandler(WebForm3_MyEvent);
}
VB.NET version without interface
Top Master:
<asp:Button runat="server" Text="Click Me" OnClick="FireMyEvent" />
Private ReadOnly MyEventObject As Object = New Object()
Public Custom Event MyEvent As EventHandler
AddHandler(value As EventHandler)
Events.AddHandler(MyEventObject, value)
End AddHandler
RemoveHandler(value As EventHandler)
Events.RemoveHandler(MyEventObject, value)
End RemoveHandler
RaiseEvent(sender As Object, e As System.EventArgs)
Dim handler As EventHandler = TryCast(Events.Item(MyEventObject), EventHandler)
If Not handler Is Nothing Then
handler(Me, EventArgs.Empty)
End If
End RaiseEvent
End Event
Protected Sub FireMyEvent(sender As Object, e As EventArgs)
RaiseEvent MyEvent(Me, EventArgs.Empty)
End Sub
Nested master:
Public Custom Event MyEvent As EventHandler
AddHandler(value As EventHandler)
AddHandler DirectCast(Master, TopMaster).MyEvent, value
End AddHandler
RemoveHandler(value As EventHandler)
RemoveHandler DirectCast(Master, TopMaster).MyEvent, value
End RemoveHandler
RaiseEvent(sender As Object, e As System.EventArgs)
End RaiseEvent
End Event
Content page
Protected Sub Page_Load(sender As Object, e As EventArgs)
AddHandler DirectCast(Master, MasterPage2).MyEvent, AddressOf Foobar
End Sub
Private Sub Foobar(sender As Object, e As EventArgs)
Response.Write("MyEvent handled from top master page at " & DateTime.Now.ToLongTimeString())
End Sub
Hi i have a user control that contains a button. I want to Over ride a custom function on click of that button like
Protected Sub btnUploadSpreadSheet_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnUploadSpreadSheet.Click
MyMethod()
End Sub
Public Overridable Sub MyMethod()
' this i want to over ride
End Sub
and in my page where i have added my control when i tried to over ride
Protected Overrides Sub MyMethod ()
End Sub
It is not finding that sub in the base class.
That's because the page is not a child of your UserControl(your page does not inherit from it) and this is the wrong approach anyway. Look up "Inheritance in Visual Basic": http://msdn.microsoft.com/en-us/library/5x4yd9d5%28v=vs.90%29.aspx
What you apparently want is to handle a custom UserControl's event in your page:
Your UserControl:
Class ExcelSheetUploader
Inherits UserControl
Public Event Uploaded(ctrl As ExcelSheetUploader)
Protected Sub btnUploadSpreadSheet_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnUploadSpreadSheet.Click
RaiseEvent Uploaded(Me)
End Sub
End Class
Now you can handle it in your page:
Protected Sub ExcelSheetUploader_Uploaded(ctrl As ExcelSheetUploader) Handles ExcelSheetUploader1.Uploaded
' Do something .... '
End Sub
MSDN: RaiseEvent
You cannot do this because your page is not extending the user control. Only in such a situation your implementation would be suitable
You can not directly override the methods or properties if some class
(e.g. Page) does not inherit You custom Class(Control). If you want to
do some functionality on some event on the page or button click then
create the public methods on the UserControl that raise some event or
execute some code.
Note - Must follow the page - life cycle.
Check this little code snippet that may be helpful to understand.
Private Class MyControl
Inherits NavronChartControl.UserControls.MyControlBase
Protected Overrides Sub OnChartTypeChanged(chartType As UserControls.ChartType)
MyBase.OnChartTypeChanged(chartType)
End Sub
///Call this OnChartTypeChanged(...) using some method
/// Or Create your public methods for your functionality
End Class
///Method at Parent Control
'OnChartTypeChanged is method that raise the event with argument
Protected Overridable Sub OnChartTypeChanged(chartType As ChartType)
'ChartTypeChang is an Event
RaiseEvent ChartTypeChanged(chartType)
End Sub
Check the Programming ASP.NET- Custom and User Controls 's Handling events in VB.NET section.
MSDN - Raising an Event - you can create your own custom event argument that hold some data that you want to pass through event. e.g. e.X
How can I call the Sub on the content page?
On the content page, there is let's say this:
Public Sub MySub()
End Sub
On the master page I have this:
Dim cph As ContentPlaceHolder = CType(Page.Form.FindControl("ContentPlaceHolder1"), ContentPlaceHolder)
Why do you need this? You can't be sure to have a particular contentpage. A Masterpage's purpose is re-usability and therefore many pages should use it. Why you need to access a special page?
What you could do is, add an event to the Masterpage, raise it when necessary and handle it in the ContentPage. For example...
in Master:
Partial Public Class ERPMaster
Inherits System.Web.UI.MasterPage
Public Event MasterLoaded(ByVal master As MasterPage)
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
RaiseEvent MasterLoaded(Me)
End Sub
In Content:
Private Sub Page_PreInit(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.PreInit
AddHandler DirectCast(Master, ERPMaster).MasterLoaded, AddressOf MasterLoaded
End Sub
Private Sub MasterLoaded(ByVal master As MasterPage)
MySub()
End Sub
Public Sub MySub()
End Sub
I assume that you are using ASP.NET?
Do you have a MasterType directive at the top of the content page file? If so, you can simply call functions on the master page using the following syntax:
Master.MySub()
The Master property of the content page is already typed to the page specified in the MasterType directive, so you can easily access any of the functions that it defines.
See MSDN for more information on interacting with master and client pages: http://msdn.microsoft.com/en-us/library/c8y19k6h(v=VS.100).aspx