Class Inheritance from ASCX control - asp.net

i have a problem on inheriting classes that have ASCX markup pages attached to it. See, i wrote the following ASCX markup and Codebehind:
ASCX
<%# Control Language="vb" AutoEventWireup="false" CodeBehind="HeaderBlock.ascx.vb" Inherits="CentralWeb.EMP.UI.HeaderBlock" %>
<h1>
<abbr><%= Me.Label></abbr>
<span>
<asp:Button ID="saveandreturnbutton" Text="Salvar e Voltar..." runat="server" CssClass="saveandback" />
<asp:Button ID="savebutton" Text="Salvar..." runat="server" CssClass="save" />
<asp:Button ID="return_results" Text="Voltar..." runat="server" CssClass="back" />
</span>
</h1>
Codebehind
Namespace EMP.UI
Public Class HeaderBlock
Inherits System.Web.UI.WebControls.UserControl
Protected saveandreturnbutton As Global.System.Web.UI.WebControls.Button
Protected savebutton As Global.System.Web.UI.WebControls.Button
Protected return_results As Global.System.Web.UI.WebControls.Button
Public Overridable Sub TakeAction(ByVal eventId As Integer)
'NOTHING, THIS IS THE BASE CLASS
End Sub
Private Sub saveandreturn_Click(ByVal sender As Object, ByVal e As Global.System.EventArgs) Handles saveandreturnbutton.Click
Me.TakeAction(3)
End Sub
Private Sub savebutton_Click(ByVal sender As Object, ByVal e As Global.System.EventArgs) Handles savebutton.Click
Me.TakeAction(2)
End Sub
Private Sub return_results_Click(ByVal sender As Object, ByVal e As Global.System.EventArgs) Handles return_results.Click
Me.TakeAction(1)
End Sub
End Class
End Namespace
Then, my intention is to use this base class (that have a markup), and inherit it to a non-marked up class, and refer it on a page. Like this:
Namespace EMP.UI
Public Class FrontHeader
Inherits EMP.UI.HeaderBlock
Public Overrides Sub TakeAction(ByVal I As Integer)
'CHILD CLASS ACTIONS HERE
End Sub
End Class
End Namespace
What's wrong on that test?
EDITION
After talking a litle with Tim, i'd like to do somthing like this:
<%# Control Language="vb" AutoEventWireup="false" CodeBehind="HeaderBlock.ascx.vb" Inherits="CentralWeb.EMP.UI.HeaderBlock" %>
<h1>
<abbr><%= Me.Label></abbr>
<span>
<asp:Button ID="saveandreturnbutton" Text="Salvar e Voltar..." runat="server" CssClass="saveandback" />
<asp:Button ID="savebutton" Text="Salvar..." runat="server" CssClass="save" />
<asp:Button ID="return_results" Text="Voltar..." runat="server" CssClass="back" />
</span>
</h1>
<div class="fields">
PLACE HERE CONTROLS DEPENDING ON THE PAGE WHERE THIS CLASS IS...
</div>

[Disclaimer: the original question had no Inherits System.Web.UI.UserControl]
You need to inherit from UserControl:
Public Class HeaderBlock
Inherits System.Web.UI.UserControl
....
But in general i would not inherit a class from a UserControl since that is a frontend control which should not contain too much business logic. If you want to "extend" it you could simply put another UserControl in it. The UserControl can contain one or multiple other controls, so a modular concept.

Related

ASP.NET Webforms Repeater doesn't load custom control properly on button click/postback

I'd like to use a custom control within a repeater with access to the data item of the repeater from within the custom control. This works fine when loading the page, but when binding data to the repeater from a button click event it will not work.
Over the past fwe days I have tried so many different approaches, using ViewStates, Session, disabling ViewState, doing things with and without update panels but I always end at the same issue.
For some reason when binding data on the repeater in the button click event handler the "AssignedValue" property of the custom control will not be set, which works on page load without postback.
I am confused, as the repeater item is present but the custom control is loaded without it being assigned to "AssignedValue". How else would I bind a different data set to the repeater when clicking a button?
Any ideas how I can solve this issue?
Demo solution download: https://drive.google.com/file/d/10TvaCr0p6wPkQ6HoA0PnjwXgYgVJEKp8/view?usp=sharing or see the code below.
Default.aspx
<%# Page Title="Home Page" Language="VB" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.vb" Inherits="WebApplication1._Default" %>
<%# Register TagPrefix="test" Src="~/WebUserControl1.ascx" TagName="ctrl" %>
<asp:Content ID="BodyContent" ContentPlaceHolderID="MainContent" runat="server">
<asp:UpdatePanel runat="server">
<ContentTemplate>
<asp:Repeater runat="server" ID="rptTest" ItemType="WebApplication1.Test">
<ItemTemplate>
<div>
<test:ctrl runat="server" AssignedValue="<%# Item.Value %>" /> (Item: <%# Item.Value %>)
</div>
</ItemTemplate>
</asp:Repeater>
<br />
<asp:LinkButton runat="server" ID="btnLoadMore" OnClick="btnLoadMore_Click">Load More!</asp:LinkButton>
</ContentTemplate>
</asp:UpdatePanel>
</asp:Content>
Default.aspx.vb
Public Class _Default
Inherits Page
Protected Sub Page_Load(ByVal sender As Object, ByVal e As EventArgs) Handles Me.Load
If Not IsPostBack Then
rptTest.DataSource = Test.Set1
rptTest.DataBind()
End If
End Sub
Protected Sub btnLoadMore_Click(sender As Object, e As EventArgs)
rptTest.DataSource = Test.Set2
rptTest.DataBind()
End Sub
End Class
Test.vb
Public Class Test
Public Property Value As String
Public Shared Property Set1 As Test() = {New Test() With {.Value = "a"}, New Test() With {.Value = "b"}}
Public Shared Property Set2 As Test() = {New Test() With {.Value = "c"}, New Test() With {.Value = "d"}}
End Class
WebUserControl1.aspx
<%# Control Language="vb" AutoEventWireup="false" CodeBehind="WebUserControl1.ascx.vb" Inherits="WebApplication1.WebUserControl1" %>
Value: <asp:Literal runat="server" ID="litValue" />
WebUserControl.aspx.vb
Public Class WebUserControl1
Inherits System.Web.UI.UserControl
Public Property AssignedValue As String
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
litValue.Text = AssignedValue
End Sub
End Class
What I expect:
Value: a (Item: a)
Value: b (Item: b)
*Click on Load More!*
Value: c (Item: c)
Value: d (Item: d)
What I get:
Value: a (Item: a)
Value: b (Item: b)
*Click on Load More!*
Value: (Item: c)
Value: (Item: d)
Hi I have looked at your code and i think i know what the problem is.
in the WebUserControl1.ascx.vb you assign a value on Page_load so it works the first time but then on the binding the second time you don't assign a value so you need to add the assignment below WebUserControl1 prerender. Please let me know if it works. Fingers crossed.
Public Class WebUserControl1
Inherits System.Web.UI.UserControl
Public Property AssignedValue As String
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
litValue.Text = AssignedValue
End Sub
Private Sub WebUserControl1_PreRender(sender As Object, e As EventArgs) Handles Me.PreRender
litValue.Text = AssignedValue
End Sub
End Class
I'm not sure if this will help but I had a problem with repeaters before in UpdatePanels and was getting a pull page reload instead of a partial one so losing data.
The repeaters don't seem to handle client ids very well so it caused me problems.
I added ClientIDMode="AutoID" to the repeaters attributes which fixed the problem for me.
It may be worth a try. Somebody else may be able to explain this technically better thank me.

Handles clause requires a WithEvents Callback

Error in CallbackUpdateSchema.Callback
BC30506 Visual Basic AND ASP.net Handles clause requires a WithEvents variable defined in the containing type or one of its base types. Callback
Imports DevExpress.Xpo
Imports DevExpress.Data.Filtering
Imports DevExpress.Xpo.DB
Public Class UpdateSchema
Inherits System.Web.UI.Page
Dim uow As UnitOfWork
Private Sub Page_Init(sender As Object, e As EventArgs) Handles Me.Init
uow = XpoHelper.GetNewUnitOfWork
End Sub
Protected Sub CallbackUpdateSchema_Callback(source As Object, e As DevExpress.Web.CallbackEventArgs) Handles CallbackUpdateSchema.Callback
uow.UpdateSchema()
uow.CreateObjectTypeRecords()
End Sub
End Class
<%# Page Language="vb" AutoEventWireup="false" CodeBehind="UpdateSchema.aspx.vb" %>
<%# Register assembly="DevExpress.Xpo.v18.2, Version=18.2.6.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a" namespace="DevExpress.Xpo" tagprefix="dx" %>
<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<dx:ASPxButton ID="ASPxButtonUpdateSchema" runat="server" AutoPostBack="False" Text="Update Schema">
<ClientSideEvents Click="function(s, e) {CallbackUpdateSchema.PerformCallback();}" />
</dx:ASPxButton>
<dx:ASPxCallback ID="CallbackUpdateSchema" runat="server" ClientInstanceName="CallbackUpdateSchema">
</dx:ASPxCallback>
</div>
</form>
</body>
</html>
Use the overridable method OnInit
https://learn.microsoft.com/en-us/dotnet/api/system.web.ui.page.oninit?view=netframework-4.8#System_Web_UI_Page_OnInit_System_EventArgs_
Events are meant for users. For sub-classing, you should use overridable methods instead.
Protected Overrides Sub OnInit(e As EventArgs)
MyBase.OnInit()
uow = XpoHelper.GetNewUnitOfWork
End Sub

VB ASP.NET 4.0 - Adding Example to new web project

I'm trying to learn ASP.NET (after many years of using classic ASP, jQuery, Ajax etc). I've installed VS 2010 and have IIS running on my W7 64bit PC.
I've created a new web project (in a folder called C:\ASP.NET Testing\ASP.NET 4.0 Examples) called ASP.NET-4.0.
I can compile the project fine and run the default page etc.
I am trying to load in a simple example from a book (ASP.NET 4.0 In Practice). So, I've created a sub folder CH01, and then copied in the .aspx and .aspx.vb files.
When I debug this, I get
Description: An error occurred during the parsing of a resource required to service this request. Please review the following specific parse error details and modify your source file appropriately.
Parser Error Message: Could not load type 'ASP.NET_4._0.Global_asax'.
Source Error:
Line 1: <%# Application Codebehind="Global.asax.vb" Inherits="ASP.NET_4._0.Global_asax" Language="vb" %>
in the browser window.
The sample code (which has been downloaded from the website) is :
<%# Page Language="VB" AutoEventWireup="false" CodeFile="1-4.aspx.vb" Inherits="_1_4" %>
<html>
<head>
<title>Listing 1.4</title>
</head>
<body>
<form id="Form1" runat="server">
<div>
<asp:literal id="ResponseText" runat="server" />
<br />
Enter your name:
<asp:textbox runat="server" ID="Name" />
<br />
<asp:button runat="server" Text="Click Me" ID="ClickButton" OnClick="HandleSubmit" />
</div>
</form>
</body>
</html>
and
Partial Class _1_4
Inherits System.Web.UI.Page
Sub HandleSubmit(ByVal sender As Object, ByVal e As EventArgs)
ResponseText.Text = "Your name is: " & Name.Text
End Sub
End Class
In VS, I also get an error message highlighting the ResponseText.Text = "Your name is: " & Name.Text
'ResponseText' is not declared. It may be inaccessible due to its protection level.
Global.asxa file
Imports System.Web.SessionState
Public Class Global_asax
Inherits System.Web.HttpApplication
Sub Application_Start(ByVal sender As Object, ByVal e As EventArgs)
' Fires when the application is started
End Sub
Sub Session_Start(ByVal sender As Object, ByVal e As EventArgs)
' Fires when the session is started
End Sub
Sub Application_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
' Fires at the beginning of each request
End Sub
Sub Application_AuthenticateRequest(ByVal sender As Object, ByVal e As EventArgs)
' Fires upon attempting to authenticate the use
End Sub
Sub Application_Error(ByVal sender As Object, ByVal e As EventArgs)
' Fires when an error occurs
End Sub
Sub Session_End(ByVal sender As Object, ByVal e As EventArgs)
' Fires when the session ends
End Sub
Sub Application_End(ByVal sender As Object, ByVal e As EventArgs)
' Fires when the application ends
End Sub
End Class
I'm obviously missing something really simple, but I don't get it. I can't see any instructions as to anything which I need to set within VS.
Thanks.
This page works OK if I add from VS. In effect the same page as I'm copying in from the examples, but with slight changes to the page tag. It alos has a .designer.vb page which was automatically generated by VS.
14.aspx
<%# Page Language="vb" AutoEventWireup="false" CodeBehind="14.aspx.vb" Inherits="ASP.NET_4._0._14" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<title>Listing 1.4</title>
</head>
<body>
<form id="Form1" runat="server">
<div>
<asp:literal id="ResponseText" runat="server" />
<br />
Enter your name:
<asp:textbox runat="server" ID="Name" />
<br />
<asp:button runat="server" Text="Click Me" ID="ClickButton" OnClick="HandleSubmit" />
</div>
</form>
</body>
</html>
14.aspx.vb
Public Class _14
Inherits System.Web.UI.Page
Sub HandleSubmit(ByVal sender As Object, ByVal e As EventArgs)
ResponseText.Text = "Your name is: " & Name.Text
End Sub
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
End Sub
End Class
14.aspx.designer.vb
'------------------------------------------------------------------------------
' <auto-generated>
' This code was generated by a tool.
'
' Changes to this file may cause incorrect behavior and will be lost if
' the code is regenerated.
' </auto-generated>
'------------------------------------------------------------------------------
Option Strict On
Option Explicit On
Partial Public Class _14
'''<summary>
'''Form1 control.
'''</summary>
'''<remarks>
'''Auto-generated field.
'''To modify move field declaration from designer file to code-behind file.
'''</remarks>
Protected WithEvents Form1 As Global.System.Web.UI.HtmlControls.HtmlForm
'''<summary>
'''ResponseText control.
'''</summary>
'''<remarks>
'''Auto-generated field.
'''To modify move field declaration from designer file to code-behind file.
'''</remarks>
Protected WithEvents ResponseText As Global.System.Web.UI.WebControls.Literal
'''<summary>
'''Name control.
'''</summary>
'''<remarks>
'''Auto-generated field.
'''To modify move field declaration from designer file to code-behind file.
'''</remarks>
Protected WithEvents Name As Global.System.Web.UI.WebControls.TextBox
'''<summary>
'''ClickButton control.
'''</summary>
'''<remarks>
'''Auto-generated field.
'''To modify move field declaration from designer file to code-behind file.
'''</remarks>
Protected WithEvents ClickButton As Global.System.Web.UI.WebControls.Button
End Class
Check you global.asax on the root of your website. There seems to be something wrong with the class name/namespace. I don't think it has anything to do with the file you added, but rather with something you probably moved or removed by mistake.

Visual Basic subprocedure issue

I'm working on some .NET code in visual studio web developer and I'm having an issue. When I double click on a button in design view, instead of loading a subprocedure, all it does is highlight this: <asp:Button ID="btnEnter" runat="server" Text="Enter" onclick="btnEnter_Click" />
When I try to run that just to see what happens, I get this error:
Line 8: <asp:Button ID="btnEnter" runat="server"
Compiler Error Message: BC30456: 'btnEnter_Click' is not a member of 'ASP.default_aspx'.
If I erase the onclick="btnEnter_Click" and run it, it works. Either way though, when I double click the button / element, shouldn't it create a subprocedure for me that looks something like?
Protected Sub TextBox1_TextChanged(sender As Object, e As EventArgs)
End Sub
I've tried entering that manaully but the keywords don't turn blue or any sort of color, and when I run it, it just shows up as text on the webform with my other elements. Here is all I have so far:
<%# Page Title="Home Page" Language="VB"%>
<form id="form1" runat="server">
<asp:Label ID="Label1" runat="server" Text="Enter a person's name below"></asp:Label>
<p>
<asp:TextBox ID="txtStudentName" runat="server"></asp:TextBox>
</p>
<p>
<asp:Button ID="btnEnter" runat="server"
Text="Enter" onclick="btnEnter_Click" />
</p>
<p>
<asp:Button ID="btnDisplay" runat="server" Text="Display all and exit" />
</p>
<p>
<asp:Label ID="lbl2" runat="server" Text=" "></asp:Label>
</p>
<p>
<asp:Label ID="lbl3" runat="server" Text=" "></asp:Label>
</p>
<p>
<asp:Label ID="lbl4" runat="server" Text=" "></asp:Label>
</p>
<p>
<asp:Label ID="lbl5" runat="server" Text=" "></asp:Label>
</p>
</form>
Edit:
When I enter my code inside the default.aspx.vb file, it highlights keywords and such, but it can't reference the elements I created in the design view.
Partial Class _Default
Inherits System.Web.UI.Page
End Class
Class Lab1
Protected Sub TextBox1_TextChanged(sender As Object, e As EventArgs)
End Sub
Public Const length As Integer = 3
Shared counter2 As Integer = 0
Public Shared studentList As String() = New String(2) {}
Protected Sub btnEnter_Click(sender As Object, e As EventArgs)
Label1.Text = "Enter a person's name"
Dim studentName As [String] = txtStudentName.Text
If studentList.Length <= length Then
If txtStudentName.Text <> "" Then
Dim match As [Boolean] = True
Dim i As Integer = 0
While counter2 >= i
If studentList(i) IsNot Nothing Then
If studentList(i).ToUpper() = txtStudentName.Text.ToUpper() Then
match = False
Label1.Text = "This name has already been used"
End If
End If
i += 1
End While
If match = True Then
studentList(counter2) = txtStudentName.Text
counter2 += 1
End If
End If
End If
End Sub
End Class
Your Page declaration seems to say you are using inline style:
<%# Page Title="Home Page" Language="VB"%>
Which means your code is/should be within aspx file itself in a script runat="server" tag:
<%# Page Language="VB" %>
<!DOCTYPE html>
<script runat="server">
Protected Sub Button1_Click(sender As Object, e As EventArgs)
'Do something
End Sub
</script>
<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
<title></title>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:Button ID="Button1" runat="server" OnClick="Button1_Click" Text="Button" />
</div>
</form>
</body>
</html>
However, your other code indicates you seem to want to use code-behind model, where you have .vb files (e.g. foo.aspx.vb)
The Page is declared like this for web sites (for web applications it will say CodeBehind="foo.aspx.vb"):
<%# Page Language="VB" AutoEventWireup="false" CodeFile="foo.aspx.vb" Inherits="foo" %>
You will find a foo.asp.vb file in your project
it's class name will be the name of your file (foo)
your code should be scoped to this class (I'm not sure what Class Lab1 in your post above is for....
foo.aspx.vb:
Partial Class foo
Inherits System.Web.UI.Page
Protected Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
'Do something
End Sub
End Class
The "fix" is for you to:
choose which model you want to write code: inline or code-behind
declare the Page appropriately
for inline, your code will be in the aspx file itself
for code-behind, your code will live, and should be encapsulated within the Class file of the page.
The Page declaration actually says so:
CodeFile="foo.aspx.vb" is the file where the code is
Inherits="foo" is the Partial Class in the file (Partial Class foo)
Try this
Private Sub btnEnter_Click(sender As Object, e As System.EventArgs) Handles btnEnter.Click
End Sub
Here, btnEnter_Click is your event name and use the Handles keyword at the end of a procedure declaration to cause it to handle events raised by an object variable

How do you expose a Panel as a property in a User Control?

I have a user control with a panel on it:
CustomControl.ascx
<%# Control Language="vb" CodeBehind="CustomControl.ascx.vb" %>
<asp:Panel ID="myPanel" runat="server"></asp:Panel>
I'd lke to expose that panel as a property that I can use at design time.
CustomControl.ascx.vb
<ParseChildren(True), PersistChildren(False)> _
Partial Public Class CustomControl
Inherits System.Web.UI.UserControl
#Region "Members and Properties"
<PersistenceMode(PersistenceMode.InnerProperty)> _
Public Property SomePanel() As Panel
Get
Return myPanel
End Get
Set(ByVal value As Panel)
myPanel= value
End Set
End Property
#End Region
Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
Response.Write(myPanel.HasControls.ToString())
End Sub
End Class
And then bring the control onto a page like so:
<ucl:CustomControl runat="server">
<SomePanel>
<asp:Label ID="lblText" AssociatedControlID="txtBox" runat="server"></asp:Label>
<asp:TextBox id="txtBox" runat="server"></asp:TextBox>
</SomePanel>
</ucl:CustomControl>
When I run the page, HasControls is true but nothing is rendered. What am I doing wrong?
You could achieve a similar effect by designing your user control as a template control. It's not that hard to set up, if you choose to go the template route.
Check out this brief tutorial to determine if control templates are suitable for you:
http://msdn.microsoft.com/en-us/library/36574bf6.aspx

Resources