Wednesday, July 4, 2012

How to Create and Use a User Control as a DLL

Introduction

In this section, you will learn how to build a custom control as a DLL. The basic feature of the DLL is we can use it as a usercontol like a .ascx.

How to add a JavaScript file in a DLL

  1. First create a new project and select Class Library project.
  2. Figure 1. Add class Library Project

  3. Add a JavaScript file and in the Properties window, set properties as in figure 2.

  4. Now in the AssemblyInfo.cs file, add the following lines. These are very important lines so add exactly the same name of the js file.
  5. [assembly: System.Web.UI.WebResource("AddUserControl.JSAutoCmp.js",
              "text/javascript", PerformSubstitution = true)] 
  6. Now we write code for creating an autocomplete textbox with a listbox control.
  7. We will create an autotexbox with a listbox. When we type in the textbox our focus automatically will go to the listbox matched item. We write [ToolboxData(@"<{0}:AutoCmp_TextBox runat=""server"" \>")]. By ToolboxData, we specify the tag which is added to the page when this control is dragged form the toolbox to a form. We use AutoCompleteType which enables us to associate an AutoComplete class with the TextBox control.
    [ToolboxData(@"<{0}:AutoCmp_TextBox runat=""server"" \>")]
    public class AutoComplete_TextBox : TextBox
    {
        private string _AutoComplete_ListBoxId = "";
        private string _Selected_Value = "-1";
    
        public AutoComplete_TextBox()
            : base()
        {
            this.AutoCompleteType = AutoCompleteType.Disabled;
        }
    
        [Category("Behavior"), DefaultValue(""),
          Description("The AutoComplete_ListBox's Id which will apear on key press.")]
        public string AutoComplete_ListBoxId
        {
            get { return _AutoComplete_ListBoxId; }
            set { _AutoComplete_ListBoxId = value.Trim(); }
        }
    
        [Category("Behavior"), DefaultValue(""),
          Description("Selected value in assossiated AutoComplete_ListBoxId.")]
        public string Selected_Value
        {
            get
            {
                try
                {
                    if (HttpContext.Current.Request.Form.Count > 0 && _AutoComplete_ListBoxId.Trim() != "")
                        if (HttpContext.Current.Request.Form["SanControls_HdnField"] != null)
                            _Selected_Value = get_SelectedValue(HttpContext.Current.Request.Form["SanControls_HdnField"]);
                        return _Selected_Value;
                    }
                catch { return "-1"; }
            }
            set { _Selected_Value = value; }
        }
    
        private void setCtrl_Attribute(string Attr_name, string value)
        {
            if (Attr_name != null && Attr_name != "" && value != null && value != "")
            {
                if (this.Attributes[Attr_name] != null && this.Attributes[Attr_name] != "")
                {
                    if (this.Attributes[Attr_name].IndexOf(value, StringComparison.OrdinalIgnoreCase) == -1)
                        this.Attributes[Attr_name] = value + ";" + this.Attributes[Attr_name];
                }
                else
                    this.Attributes[Attr_name] = value + ";";
            }
        }
    
        private string get_SelectedValue(string viewState)
        {
            string retVal = _Selected_Value;
            string[] values ={ "|;" };
            if (viewState != null)
            {
                values = viewState.Split(values, StringSplitOptions.None);
                for (int i = 0; i < values.Length; i++)
                {
                    if (values[i].Trim() != "" && values[i].Substring(0, values[i].IndexOf("=")) == this.ClientID)
                    {
                        retVal = values[i].Substring(values[i].IndexOf("=") + 1).Trim();
                        break;
                    }
                }
            }
            return retVal;
        }
    
    
        protected override void AddAttributesToRender(System.Web.UI.HtmlTextWriter writer)
        {
            writer.AddAttribute("SelectedIndex", "-1");
            writer.AddAttribute("SelectedValue", Selected_Value);
            base.AddAttributesToRender(writer);
        }
    
        protected override void OnPreRender(EventArgs e)
        {
            if (AutoComplete_ListBoxId != "")
            {
                setCtrl_Attribute("onkeyup", "SanControls_selectItem()");
                //"return SanControls_showList('" + 
                //  Page.FindControl(AutoCompleteListId).ClientID + "')");
                setCtrl_Attribute("onblur", "SanControls_hideList()");
                setCtrl_Attribute("onkeydown", "checkKey('" + 
                   Page.FindControl(AutoComplete_ListBoxId).ClientID + "')");
                setCtrl_Attribute("onfocus", "SanControls_TextFocus('" + 
                   Page.FindControl(AutoComplete_ListBoxId).ClientID + "')");
            }
    
            Page.RegisterRequiresPostBack(this);
            Page.ClientScript.RegisterClientScriptInclude("SanControlsJS", 
                 Page.ClientScript.GetWebResourceUrl(this.GetType(), "AddUserControl.JSAutoCmp.js"));
            base.OnPreRender(e);
        }
    }
    AutoComplete_ListBoxId: By this we assign the listbox ID to the textbox in which we find the matched value and set focus on this item of the listbox. We call the Page.RegisterRequiresPostBack() method inside (or before) the control's PreRender() event to tell page that our control is interested in receiving postback data. All the client-side functionalities happen in an external JavaScript file. A JavaScript include is rendered by the control in its OnPreRender() method. This line is included in the JavaScript file.
    Page.ClientScript.RegisterClientScriptInclude("SanControlsJS", 
      Page.ClientScript.GetWebResourceUrl(this.GetType(), "AddUserControl.JSAutoCmp.js"));
    Now we will create a listbox in which we find the value of the textbox.
    [ToolboxData(@"<{0}:AutoCmp_ListBox runat=""server"" \>")]
    public class AutoCmp_ListBox : ListBox
    {
        bool isrendered = false;
        public AutoCmp_ListBox()
            : base()
        {
            this.Rows = 7;
    
        }
        protected override void AddAttributesToRender(System.Web.UI.HtmlTextWriter writer)
        {
            isrendered = true;
            writer.AddAttribute("onMouseDown", "SanControls_SelectList();");
            writer.AddAttribute("onDblClick", "SanControls_hideList(true);");
            writer.AddAttribute("onMouseOut", "SanControls_deSelectList();");
            writer.AddAttribute("onMouseUp", "SanControls_deSelectList();");
            writer.AddAttribute("onChange", "SanControls_changeText();");
            base.AddAttributesToRender(writer);
    
        }
    
        protected override void OnPreRender(EventArgs e)
        {
            if (!isrendered)
            {
                if (this.Style.Value != null)
                    this.Style.Value += "position:absolute;visibility:hidden;width:0px";
                    else
                        this.Style.Value = "position:absolute;visibility:hidden;width:0px";
    
                    Page.ClientScript.RegisterClientScriptInclude("SanControlsJS", 
                         Page.ClientScript.GetWebResourceUrl(this.GetType(), "AddUserControl.JSAutoCmp.js"));
                    base.OnPreRender(e);
    
                    if (HttpContext.Current.Request.Form["SanControls_HdnField"] == null)
                        Page.ClientScript.RegisterHiddenField("SanControls_HdnField", "");
                    else
                        Page.ClientScript.RegisterHiddenField("SanControls_HdnField", 
                           HttpContext.Current.Request.Form["SanControls_HdnField"]);
                }
            }
        }
    We build the DLL then add a New Website and add a reference of this DLL. In our aspx page, we register the assembly just as we use user controls.
.aspx page design
<%@ Page Language="C#" AutoEventWireup="true"  CodeFile="Default.aspx.cs" Inherits="_Default" %>
<%@ Register Assembly ="AddUserControl" Namespace="AddUserControl" TagPrefix ="SANCtrl"  %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" >
<head runat="server">
    <title>Untitled Page</title>
</head>
<body>
    <form id="form1" runat="server">
    <div>
        <SANCtrl:AutoComplete_TextBox runat ="server" id="sanTextBox" AutoComplete_ListBoxId ="sanListBox" ></SANCtrl:AutoComplete_TextBox>
        <SANCtrl:AutoCmp_ListBox runat ="server" ID ="sanListBox" ></SANCtrl:AutoCmp_ListBox>
    </div>
    </form>
</body>
</html>
Now the .cs page code for setting the texbox's listbox ID for searching and filling the list box with data. When we view this page in browser and type in the texbox, the listbox appears and our focus goes on to the matched item of the list box. We do not require any code for this.
sanTextBox.AutoComplete_ListBoxId = sanListBox.UniqueID;
DataTable dt = new DataTable();
dt.Columns.Add("id");
dt.Columns.Add("Name");
dt.Rows.Add("1.", "Aashish Bhatia");
dt.Rows.Add("2.", "Anoop Bhatia");
dt.Rows.Add("3.", "Diljit Singh");
dt.Rows.Add("4.", "Rajeev Sharma");
dt.Rows.Add("5.", "Sanjay Bhatia");
       
sanListBox.DataTextField = "Name";
sanListBox.DataValueField = "Id";

sanListBox.DataSource = dt;
sanListBox.DataBind();
See the figure below which shows the functionality of the autocomplete text box with listbox.

See this figure of the Solution Explorer in which I display the DLL project and a website page for testing if the js functions are assigned to the ASPX controls or not.

That's all!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Prosan

No comments:

Post a Comment

Could not find a part of the path ... bin\roslyn\csc.exe

I am trying to run an ASP.NET MVC (model-view-controller) project retrieved from TFS (Team Foundation Server) source control. I have added a...