10

First, I am new to ASP.NET

In order to reuse my dropdown list across different forms on different pages, I was advised that to use User Control to accomplish this. So I did some reading about user control and attempted to play around with it, but couldn't get it work since I am new to ASP.NET. Get this error:

Cannot access a non-static member of outer type 'ASP.Vendor' via nested type 'ASP.Vendor._Default'

1) I create a Controls\Vendor.ascx file

<% @ Control Language="C#" ClassName="Vendor" %>
<%@ Import Namespace="System.Data" %>
<%@ Import Namespace="System.Data.SqlClient" %>
<%@ Import Namespace="System.Web.UI" %>
<%@ Import Namespace="System.Web.UI.WebControls" %>
<%@ Import Namespace="System.Configuration" %>
<%@ Import Namespace="System.Linq" %>
<%@ Import Namespace="System.Collections.Generic" %>

<script runat="server">

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            FillVendor();
        }
    }


    private void FillVendor()
    {
        string strConn = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
       System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection(strConn);
        SqlCommand cmd = new SqlCommand();
        cmd.Connection = conn;
        cmd.CommandType = CommandType.Text;
        cmd.CommandText = "SELECT VendorID, VendorName FROM Vendor";
        DataSet objDs = new DataSet();
        SqlDataAdapter dAdapter = new SqlDataAdapter();
        dAdapter.SelectCommand = cmd;;
        conn.Open();
        dAdapter.Fill(objDs);
        conn.Close();

        if (objDs.Tables[0].Rows.Count > 0)
        {
            VendorList.DataSource = objDs.Tables[0];
            VendorList.DataTextField = "VendorName";
            VendorList.DataValueField = "VendorID";
            VendorList.DataBind();
            VendorList.Items.Insert(0,"-- Select --");
        } else {
             lblMsg.Text = "No Vendor Found";
        }
    }
}
</script>
<asp:DropDownList ID="VendorList" runat="server" AutoPostBack="True" >
</asp:DropDownList>

2) I create a Tes2.aspx page with this code to see if I can pull that Vendor dropdown list, but no luck.

<%@ Page Language="C#" %>
<%@ Register TagPrefix="uc" TagName="Vendor" 
    Src="Controls\Vendor.ascx" %>
<html>
<body>
Testing
<form runat="server">
    <uc:Vendor id="VendorList" 
        runat="server" 
        />
</form>
</body>

Obviously, I am new and must doing thing wrong. Can someone please help me or give me an example of a dropdown list in user control and how to include it in a form? Thanks!

3 Answers 3

2

The first problem I see is that you are inheriting from Page inside your UserControl:

public partial class _Default : System.Web.UI.Page

Inherit from UserControl instead.

// notice that I also renamed the class to match the control name
public partial class Vendor : System.Web.UI.UserControl

Using a Codebehind File

As @x0n pointed out, your user control code can be placed in a codebehind file (automatically created when you create a user control inside Visual Studio). User controls typically consist of a markup portion (.ascx), a codebehind (.ascx.cs), and a designer file (.ascx.designer.cs). HTML markup goes into the ASCX file, and binding code goes into the codebehind.

I'd suggest saving your code, deleting your current user control, and re-adding it through Visual Studio.

Sample Project Structure
enter image description here

Markup (ASCX) File

<%@ Control Language="C#" AutoEventWireup="true" CodeBehind="VendorListControl.ascx.cs" Inherits="MyNamespace.VendorListControl" %>
<asp:DropDownList runat="server" ID="ddlVendorList" />
<asp:Label runat="server" ID="lblMessage" />

Codebehind

using System;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;

namespace MyNamespace
{
    public partial class VendorListControl : System.Web.UI.UserControl
    {
        protected void Page_Load( object sender, EventArgs e ) {
            if( !IsPostBack ) {
                FillVendors();
            }
        }

        private void FillVendors() {
            string strConn = ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;
            System.Data.SqlClient.SqlConnection conn = new System.Data.SqlClient.SqlConnection( strConn );

            SqlCommand cmd = new SqlCommand();
            cmd.Connection = conn;
            cmd.CommandType = CommandType.Text;
            cmd.CommandText = "SELECT VendorID, VendorName FROM Vendor";

            DataSet objDs = new DataSet();
            SqlDataAdapter dAdapter = new SqlDataAdapter();
            dAdapter.SelectCommand = cmd; ;
            conn.Open();
            dAdapter.Fill( objDs );
            conn.Close();

            if( objDs.Tables[0].Rows.Count > 0 ) {
                this.ddlVendorList.DataSource = objDs.Tables[0];
                this.ddlVendorList.DataTextField = "VendorName";
                this.ddlVendorList.DataValueField = "VendorID";
                this.ddlVendorList.DataBind();
                this.ddlVendorList.Items.Insert( 0, "-- Select --" );
            }
            else {
                this.lblMessage.Text = "No Vendor Found";
            }
        }
    }
}

Alternate Method - Remove Class Declaration

If you don't want to add a codebehind file for some reason, remove the class declaration altogether and just include the code inside it.

<script runat="server">
    protected void Page_Load(object sender, EventArgs e){
        if (!IsPostBack){
            FillVendor();
        }
    }

    // etc
</script>

As a side note, I would put the data access logic in a separate class for proper separation/reuse, but the structure you've outlined should work once you've corrected the aforementioned problems.

Sign up to request clarification or add additional context in comments.

7 Comments

That's not entirely it - by placing the class definition in a <script runat=server> tag, _Default also becomes a nested class inside the runtime compiled ASCX class.
true, the class declaration should be removed altogether unless a code-behind is added.
It works! Thank you Tim for providing detail info which really helped me to got it to work.
I got it working to display the Dropdown list, but now I don't know what is the ID for the dropdown list. When I view the "Form Details" I see this "<select id="VendorList_ddlVendorList" name="VendorList$ddlVendorList" value="2">", but this not the right ID when I try to do the Insert Record, any idea?
@Milacay What do you mean by "Form Details" - where did you find that?
|
0

Don't place the definition of the class inside the ASCX itself. Create a separate CS file and reference the separate file with the CodeBehind attribute on the <%@ Control ... directive. The ASP.NET runtime will compile your ASCX and CS at first access.

Comments

0

Are you using Visual Studio? If so, you should use the templates provided as it makes it a lot easier and you'd have avoided this problem all together. For example, to add a user control you can right-click the folder you want to put it in (this is in the Solution Explorer) and go Add -> New Item. Then select Web User Control, give it a name and click Add.

4 Comments

Thanks everyone for helping, especially @Tim. I finally got it working. Appreciated!
I got it working to display the Dropdown list, but now I don't know what is the ID for the dropdown list.
Can you be more specific? Are you trying to use the ID in the C# code or with javascript?
@Milacay I just saw your comment to Tim: .Net changes the ID before it gets to the client so that there are no conflicts. So the ID you use in your C# code is "ddlVendorList" but if you are trying to get at the drop down list in the browser it will be different (like the "VendorList_ddlVendorList")

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.