Search code examples
c#asp.netvb.netwebformswebusercontrol

C# Webforms User controls in VB.NET


I have an existing VB.NET web project that requires some new screens (webforms). Due to a number of reasons these new screens are to be developed in C#. Having had a read around it appears that this is indeed possible: Adding C# Web Form to VB Web Application and add c# user control to existing asp.net vb.net project

However I have done a small test of:

  1. VB.NET Solution containing a VB WebForms application project
  2. Added a new C# ASP.NET Project to the solution
  3. Created web user control in C# assembly
  4. Referenced and used web user control in a Default.aspx in 1.

Problem is the user control does not display on the page. What have I missed here. Is this something that is not possible in a VB.NET WebForms app? Below is the relevant code:

Default.aspx

<%@ Page Title="Home Page" Language="VB" MasterPageFile="~/Site.Master" AutoEventWireup="true" CodeBehind="Default.aspx.vb" Inherits="waWithCUserControl._Default" %>
<%@ Register TagPrefix="uac" Namespace="waUserControls" Assembly="waUserControls" %>

<asp:Content runat="server" ID="BodyContent" ContentPlaceHolderID="MainContent">
    <uac:UcTakeTest ID="myUserControl" runat="server" />
</asp:Content>

User Control In Seperate Assembly waUserControls

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="ucTakeTest.ascx.cs" Inherits="waUserControls.UcTakeTest" %>
<link href="//netdna.bootstrapcdn.com/bootstrap/3.0.3/css/bootstrap.min.css" rel="stylesheet">
<script src="//netdna.bootstrapcdn.com/bootstrap/3.0.3/js/bootstrap.min.js"></script>
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.min.css" rel="stylesheet">

    <div class="container">
        <div class="row">
            <div class="col-md-2">
                <div class="list-group">
                    <a href="#" class="list-group-item active">Question</a>
                    <a href="#" class="list-group-item">Question</a>
                    <a href="#" class="list-group-item">Question</a>
                    <a href="#" class="list-group-item">Question</a>
                    <a href="#" class="list-group-item">Question</a>
                    <a href="#" class="list-group-item">Question</a>
                    <a href="#" class="list-group-item">Question</a>
                    <a href="#" class="list-group-item">Question</a>
                    <a href="#" class="list-group-item">Question</a>
                    <a href="#" class="list-group-item">Question</a>
                </div>
            </div>
         </div>
    </div>

Solution

  • You need to postbuild the markup (ASCX files only) from the C# project into your VB Web Application project, and reference those ASCX's instead of the C# ones. Sounds bizarre but believe me it works.

    1 - Add a post-build event to the C# project that copies the UserControl markup (just the .ASCX files) to a folder in your Web Application project; for example, a folder under the root of your web app called "ExternalUserControls"

    (Note that they should have the same Inherits property, i.e. the namespace and classname from the C# project.)

    2 - Make sure the C# project is referenced (sounds like it already is)

    3 - Add control declarations to the <controls> section of <pages> of <system.web> in web.config: -

      <system.web>
      .
      .
      <pages>
        <controls>
          <add tagPrefix="cc" 
               src="~/ExternalUserControls/MyControl.ascx" 
               tagName="MyControl"   />
          <add .... etc
    

    4 - reference the controls in your page thusly: -

    <cc:MyControl id="testControl" runat="server" ..
    

    5 - make sure you Import the correct namespace for the control as defined in the C# project

    6 - Note that sometimes the VS Page Designer will refuse to add a variable for your control, so in order to access your control in the code-behind you will need to add a page-level protected (or whatever VB's equivalent is, I can't remember) variable of the correct type, using the same name as in the page markup (testControl in the example above)

    Let me know if you want an example.