Answered by:
Popup forms on Master Page

Question
-
User1120190316 posted
My web application has several popup forms used for data input. These forms are invoked from a number of different pages, so I decided to move them onto the Master Page shared by these pages. I have experimented moving one of the popup panels from aspx page to master page, along with the associated ModalPopupExtension tags and some javascript, and I get a compilation error with regard to btnPopTaskSave, the button on the popup that the user would click to save the data and close the form. Here is the error:
Compilation Error
Description: An error occurred during the compilation of a resource required to service this request. Please review the following specific error details and modify your source code appropriately.Compiler Error Message: BC30506: Handles clause requires a WithEvents variable defined in the containing type or one of its base types.
Source Error:
Line 1072: End Function
Line 1073:
Line 1074: Protected Sub btnPopTaskSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles btnPopTaskSave.Click
Line 1075:
Line 1076: 'Get data from popup form pnlTask_Pop--------------------------
What do I need to do to avoid this error?
If I may tack on a second question, how would I reference the ModalPopupExtender from server side vb code to close the popup? I have been using the syntax,
"Dim strTaskName As String = CType(Master.FindControl("txtPopTaskName"), TextBox).Text" to reference other controls on the Master Page. This works for textboxes, but the CType function will not accept ModalPopupExtender as an argument.Thank you for your help.
Monday, April 27, 2020 6:00 AM
Answers
-
User1120190316 posted
Success!
Since last posting here, I have read a couple of articles that recommend creating an Event to run when the data is saved, i.e., after the stored procedure uspTaskPopup_Save has successfully run. Then the panel on the content page can be updated by the event handler which would live on the content page. Here is the relevant code:
The following codebehind on the master page runs when the button on the popup form is clicked:
Protected Sub btnPopTask_Save_Click(sender As Object, e As EventArgs) Handles btnPopTask_Save.Click 'Get data from popup form pnlTask_Pop Dim strTaskID As String = CType(FindControl("hidPopTaskID"), HiddenField).Value.ToString If Not IsNumeric(strTaskID) Then strTaskID = "0" Dim strPostTaskID As String = CType(FindControl("hidPopPostTaskID"), HiddenField).Value.ToString If Not IsNumeric(strPostTaskID) Then strPostTaskID = "0" Dim strOwnerID As String = Session("OwnerID").ToString Dim strTaskName As String = CType(FindControl("txtPopTaskName"), TextBox).Text.Replace("'", "''") Dim strDisplayDate As String = CType(FindControl("txtPopTaskDisplayDate"), TextBox).Text Dim strListDate As String = CType(FindControl("hidPopTaskListDate"), HiddenField).Value.ToString Dim strDeadline As String = CType(FindControl("txtPopTaskDeadline"), TextBox).Text Dim bDone As Boolean = IsDate(CType(FindControl("txtPopTaskDateDone"), TextBox).Text) Dim strTaskNotes As String = CType(FindControl("txtPopTaskNotes"), TextBox).Text.Replace("'", "''") Dim strDateDone As String = CType(FindControl("txtPopTaskDateDone"), TextBox).Text Dim strGoalID As String = CType(FindControl("ddlPopTaskGoal"), DropDownList).SelectedValue.ToString Dim strGoalName As String = CType(FindControl("ddlPopTaskGoal"), DropDownList).SelectedItem.Text Dim intHighPriority As Integer = IIf(CType(FindControl("chkHighPriority"), CheckBox).Checked = True, 1, 0) Dim intIsGoal As Integer = IIf(CType(FindControl("chkIsGoal"), CheckBox).Checked = True, 1, 0) Dim intInactive As Integer = IIf(CType(FindControl("chkInactive"), CheckBox).Checked = True, 1, 0) 'Update database Dim strSQL As String = "execute dbo.uspTaskPopup_Save " & _ strTaskID & _ ", " & strOwnerID & _ ", '" & strTaskName & _ "', '" & strDisplayDate & _ "', '" & strDeadline & _ "', " & strPostTaskID & _ ", " & intHighPriority.ToString & _ ", '" & strTaskNotes.Replace("<br />", vbCrLf) & _ "', '" & strDateDone & _ "', " & intIsGoal.ToString & _ ", " & intInactive.ToString() 'Stored procedure updates tblTask and returns TaskID of edited or added record Dim ReturnVal As Int32 = Convert.ToInt32(SqlHelper.ExecuteScalar(strSQL)) 'If ReturnVal indicates the sql succeeded, raise event that will update the content page If ReturnVal > 0 Then 'Set error message to blank CType(FindControl("lblPopTaskError"), Label).Text = "" 'Close form mpeTaskPop.Hide() 'Let content page know about this RaiseEvent TaskSaved(Me, EventArgs.Empty) Else CType(FindControl("lblPopTaskError"), Label).Text = "An error occurred. Unable to update task." End If End Sub
As you can see, after it runs the stored procedure, it checks the value returned, and if the procedure ran successfully, it returns the ID number of the updated record. If it was successful, the TaskSaved event is raised and the action switches to the event handler in the content file.
Private Sub Master_TaskSaved(ByVal Sender As Object, ByVal e As EventArgs) GetSchedule(calFrom.SelectedDate, calTo.SelectedDate) tvDoList.ExpandAllNodes() 'Update panel containing tvDoList updDoList.Update() End Sub
GetSchedule() is a routine that revises the treeview tvDoList.
I also added a line to the master page's code behind:
Partial Class PPM Inherits System.Web.UI.MasterPage Public Event TaskSaved As EventHandler Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not IsPostBack Then With ScriptManager1 .RegisterAsyncPostBackControl(btnPopTask_Save) End With
...
End Sub
This creates the Event and then causes the btnPopTask_Save button to cause an asynch post-pack.
Finally, I had to add a line of code to the content page's Sub Page_PreInit:
Protected Sub Page_PreInit(sender As Object, e As EventArgs) Handles Me.PreInit AddHandler Master.TaskSaved, AddressOf Master_TaskSaved End Sub
And now it runs. Thank you for your help. I hope the above is helpful to others. I recommend the two articles that provided the information I needed.
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Wednesday, April 29, 2020 3:12 PM
All replies
-
User1535942433 posted
Hi Sheldon Penner,
Compiler Error Message: BC30506: Handles clause requires a WithEvents variable defined in the containing type or one of its base types.Accroding to your description,you could try this way:
Protected Sub btnPopTaskSave_Click(ByVal sender As Object, ByVal e As System.EventArgs) End Sub in aspx <asp:Button ID="btnPopTaskSave" runat="server" Text="manual login" OnClick ="btnPopTaskSave_Click"/>
More details,you could refer to below article:
https://forums.asp.net/t/1366892.aspx?error+Handles+clause+requires+a+WithEvents+variable+
"Dim strTaskName As String = CType(Master.FindControl("txtPopTaskName"), TextBox).Text" to reference other controls on the Master Page. This works for textboxes, but the CType function will not accept ModalPopupExtender as an argument.As far as I think,you could use the DirectCast function,
Just like this:
Dim mploginM As AjaxControlToolkit.ModalPopupExtender = DirectCast(Page.Master.FindControl("ModalPopupExtender1"), AjaxControlToolkit.ModalPopupExtender)
Best regards,
Yijing Sun
Tuesday, April 28, 2020 6:10 AM -
User1120190316 posted
Thank you for your response, Yij Sun.
As you suggested, I removed the Handles clause from my Protected Sub btnPopTaskSave_Click and added the explicit OnClick to the button markup. This time I got a different compilation error: "BC30456: 'btnPopTaskSave_Click' is not a member of 'ASP.ppm_master'." Apparently, the Master page cannot see controls and server code in its attached files. (I may not have made it clear in my original post that the btnPopTaskSave_Click sub is not in the Master page's back end file but in the client page's.) I will experiment with moving the vb code to the Master page's vb file I anticipate a problem of updating controls on the main page, which will be different depending on which main page is attached to the Master page. Is there a way for the Master page to get the name of its current client page and manipulate controls on that page?
Since posting, I discovered a different solution to the second problem I described. I appended "AjaxControlToolkit." to the front of the second argument of the CType function, and CType now knows what I'm talking about. "CType(Master.FindControl("mpeTaskPop"), AjaxControlToolkit.ModalPopupExtender).Hide()"
Tuesday, April 28, 2020 11:36 PM -
User1120190316 posted
Hello again, Yij Sun.
I have moved btnPopTask_Save_Click from the content page's code behind to the master page's code behind. This does seem to be the solution -- everything compiles normally and the popup even pops up!. The problem now is to get the Master page to see the update panels on the Content pages so that, after entering or editing data on the popup form, the changes show up on the content page. I have tried this:
Dim upd = CType(cphMain.FindControl("updDoList"), UpdatePanel)
upd.Update()The code above does not throw any errors, but it does not update the UpdatePanel. (cphMain is the id of the ContentPlaceHolder on the master page that contains the update panel.)
I need to also find a way for the Master page to determine which page is currently its Content page, since the panel to be updated has a different id in each case. (I could, I suppose, give all these update panels the same name, but that strikes me as the kind of shortcut liable to bite me on the butt some time in the future.)
All these problems lead me to suspect that perhaps saving on the Master page is not the recommended solution for using the same popups on several content pages. Previously, I had identical markup and code for each of these popup panels on each page, but I would hate to return to that. Is there a better way to share popups among several pages?
Here is the sub routine that now lives in the master page's code behind:
Protected Sub btnPopTask_Save_Click(sender As Object, e As EventArgs) Handles btnPopTask_Save.Click 'Get data from popup form pnlTask_Pop Dim strTaskID As String = CType(FindControl("hidPopTaskID"), HiddenField).Value.ToString If Not IsNumeric(strTaskID) Then strTaskID = "0" Dim strPostTaskID As String = CType(FindControl("hidPopPostTaskID"), HiddenField).Value.ToString If Not IsNumeric(strPostTaskID) Then strPostTaskID = "0" Dim strOwnerID As String = Session("OwnerID").ToString Dim strTaskName As String = CType(FindControl("txtPopTaskName"), TextBox).Text Dim strDisplayDate As String = CType(FindControl("txtPopTaskDisplayDate"), TextBox).Text Dim strListDate As String = CType(FindControl("hidPopTaskListDate"), HiddenField).Value.ToString Dim strDeadline As String = CType(FindControl("txtPopTaskDeadline"), TextBox).Text Dim bDone As Boolean = IsDate(CType(FindControl("txtPopTaskDateDone"), TextBox).Text) Dim strTaskNotes As String = CType(FindControl("txtPopTaskNotes"), TextBox).Text Dim strDateDone As String = CType(FindControl("txtPopTaskDateDone"), TextBox).Text Dim strGoalID As String = CType(FindControl("ddlPopTaskGoal"), DropDownList).SelectedValue.ToString Dim strGoalName As String = CType(FindControl("ddlPopTaskGoal"), DropDownList).SelectedItem.Text Dim intHighPriority As Integer = IIf(CType(FindControl("chkHighPriority"), CheckBox).Checked = True, 1, 0) Dim intIsGoal As Integer = IIf(CType(FindControl("chkIsGoal"), CheckBox).Checked = True, 1, 0) Dim intInactive As Integer = IIf(CType(FindControl("chkInactive"), CheckBox).Checked = True, 1, 0) 'Update database Dim strSQL As String = "execute dbo.uspTaskPopup_Save " & _ strTaskID & _ ", " & strOwnerID & _ ", '" & strTaskName & _ "', '" & strDisplayDate & _ "', '" & strDeadline & _ "', " & strPostTaskID & _ ", " & intHighPriority.ToString & _ ", '" & strTaskNotes.Replace("<br />", vbCrLf) & _ "', '" & strDateDone & _ "', " & intIsGoal.ToString & _ ", " & intInactive.ToString() 'Stored procedure updates tblTask and returns TaskID of edited or added record Dim ReturnVal As Int32 = SqlHelper.ExecuteScalar(strSQL) Dim nodVal As String = "TaskID=" & strTaskID Dim nd As RadTreeNode = Nothing 'If proc failed, ReturnVal = 0; otherwise, its the TaskID If ReturnVal > 0 Then 'Hide popup form CType(FindControl("mpeTaskPop"), AjaxControlToolkit.ModalPopupExtender).Hide() DoListOutline.GetSchedule(DoListOutline.calFrom.SelectedDate, DoListOutline.calTo.SelectedDate) DoListOutline.tvDoList.ExpandAllNodes() CType(FindControl("lblPopTaskError"), Label).Text = "" 'If a Goal has been edited, update Goal Menu If intIsGoal = 1 Then DoListOutline.tvGoalMenu.DataBind() DoListOutline.updGoalMenu.Update() 'sqlGoalList.DataBind() FindControl("ddlPopTaskGoal").DataBind() DoListOutline.cboAddApptmtProject.DataBind() End If 'Update panel containing tvDoList 'CType(DoListOutline.FindControl("updDoList"), UpdatePanel).Update() Dim upd = CType(cphMain.FindControl("updDoList"), UpdatePanel) upd.Update() Else CType(FindControl("lblPopTaskError"), Label).Text = "An error occurred. Unable to update task." End If End Sub
Wednesday, April 29, 2020 2:02 AM -
User1535942433 posted
Hi Sheldon Penner,
I need to also find a way for the Master page to determine which page is currently its Content page, since the panel to be updated has a different id in each case. (I could, I suppose, give all these update panels the same name, but that strikes me as the kind of shortcut liable to bite me on the butt some time in the future.)Accroding to your description,I don't understand your requirments clearly.What means that master page determine which page is currently its Content page?
The code above does not throw any errors, but it does not update the UpdatePanel. (cphMain is the id of the ContentPlaceHolder on the master page that contains the update panel.)How do you show modalpopup?If you alter the Label text at code behind but calling show() at client side, it may not be successful.I suggest you may change the text by using javascript's innerText method and then show up the popup.
Is there a better way to share popups among several pages?I suggest you could create a a user control with your modal popup. You then can expose the show function publicly from your user control or launch it via javascript when you need to from any form that has the user control.
Besides,I suggest you could post your full codes of front pages to us.It will help us to solve your problems.
Best regards,
Yijing Sun
Wednesday, April 29, 2020 9:36 AM -
User1120190316 posted
Success!
Since last posting here, I have read a couple of articles that recommend creating an Event to run when the data is saved, i.e., after the stored procedure uspTaskPopup_Save has successfully run. Then the panel on the content page can be updated by the event handler which would live on the content page. Here is the relevant code:
The following codebehind on the master page runs when the button on the popup form is clicked:
Protected Sub btnPopTask_Save_Click(sender As Object, e As EventArgs) Handles btnPopTask_Save.Click 'Get data from popup form pnlTask_Pop Dim strTaskID As String = CType(FindControl("hidPopTaskID"), HiddenField).Value.ToString If Not IsNumeric(strTaskID) Then strTaskID = "0" Dim strPostTaskID As String = CType(FindControl("hidPopPostTaskID"), HiddenField).Value.ToString If Not IsNumeric(strPostTaskID) Then strPostTaskID = "0" Dim strOwnerID As String = Session("OwnerID").ToString Dim strTaskName As String = CType(FindControl("txtPopTaskName"), TextBox).Text.Replace("'", "''") Dim strDisplayDate As String = CType(FindControl("txtPopTaskDisplayDate"), TextBox).Text Dim strListDate As String = CType(FindControl("hidPopTaskListDate"), HiddenField).Value.ToString Dim strDeadline As String = CType(FindControl("txtPopTaskDeadline"), TextBox).Text Dim bDone As Boolean = IsDate(CType(FindControl("txtPopTaskDateDone"), TextBox).Text) Dim strTaskNotes As String = CType(FindControl("txtPopTaskNotes"), TextBox).Text.Replace("'", "''") Dim strDateDone As String = CType(FindControl("txtPopTaskDateDone"), TextBox).Text Dim strGoalID As String = CType(FindControl("ddlPopTaskGoal"), DropDownList).SelectedValue.ToString Dim strGoalName As String = CType(FindControl("ddlPopTaskGoal"), DropDownList).SelectedItem.Text Dim intHighPriority As Integer = IIf(CType(FindControl("chkHighPriority"), CheckBox).Checked = True, 1, 0) Dim intIsGoal As Integer = IIf(CType(FindControl("chkIsGoal"), CheckBox).Checked = True, 1, 0) Dim intInactive As Integer = IIf(CType(FindControl("chkInactive"), CheckBox).Checked = True, 1, 0) 'Update database Dim strSQL As String = "execute dbo.uspTaskPopup_Save " & _ strTaskID & _ ", " & strOwnerID & _ ", '" & strTaskName & _ "', '" & strDisplayDate & _ "', '" & strDeadline & _ "', " & strPostTaskID & _ ", " & intHighPriority.ToString & _ ", '" & strTaskNotes.Replace("<br />", vbCrLf) & _ "', '" & strDateDone & _ "', " & intIsGoal.ToString & _ ", " & intInactive.ToString() 'Stored procedure updates tblTask and returns TaskID of edited or added record Dim ReturnVal As Int32 = Convert.ToInt32(SqlHelper.ExecuteScalar(strSQL)) 'If ReturnVal indicates the sql succeeded, raise event that will update the content page If ReturnVal > 0 Then 'Set error message to blank CType(FindControl("lblPopTaskError"), Label).Text = "" 'Close form mpeTaskPop.Hide() 'Let content page know about this RaiseEvent TaskSaved(Me, EventArgs.Empty) Else CType(FindControl("lblPopTaskError"), Label).Text = "An error occurred. Unable to update task." End If End Sub
As you can see, after it runs the stored procedure, it checks the value returned, and if the procedure ran successfully, it returns the ID number of the updated record. If it was successful, the TaskSaved event is raised and the action switches to the event handler in the content file.
Private Sub Master_TaskSaved(ByVal Sender As Object, ByVal e As EventArgs) GetSchedule(calFrom.SelectedDate, calTo.SelectedDate) tvDoList.ExpandAllNodes() 'Update panel containing tvDoList updDoList.Update() End Sub
GetSchedule() is a routine that revises the treeview tvDoList.
I also added a line to the master page's code behind:
Partial Class PPM Inherits System.Web.UI.MasterPage Public Event TaskSaved As EventHandler Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If Not IsPostBack Then With ScriptManager1 .RegisterAsyncPostBackControl(btnPopTask_Save) End With
...
End Sub
This creates the Event and then causes the btnPopTask_Save button to cause an asynch post-pack.
Finally, I had to add a line of code to the content page's Sub Page_PreInit:
Protected Sub Page_PreInit(sender As Object, e As EventArgs) Handles Me.PreInit AddHandler Master.TaskSaved, AddressOf Master_TaskSaved End Sub
And now it runs. Thank you for your help. I hope the above is helpful to others. I recommend the two articles that provided the information I needed.
- Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
Wednesday, April 29, 2020 3:12 PM