ثبت تصویر در DropDownList توسط ASP.Net

جمعه 22 آبان 1394

در این مقاله نحوه افزودن تصویر به کنترل DropDownList را خواهید آموخت .شاید در ثبت گوگل و یا یاهو دیده اید که پرچم کشورها در کنار نام آنها در DropDownList نمایش داده می شود.

ثبت تصویر در DropDownList توسط ASP.Net

در این مقاله قصد داریم نحوه قرار دادن تصویر در ComboBox را یاد بگیریم .اگر روشی که در رفرنس این مقاله آمده است را مرحله به مرحله انجام دهید نهایتا به نتیجه نخواهید رسید به همین دلیل ما به روش دیگری این کار را انجام خواهیم داد.

ابتدا یک کلاس به نام HtmlSelectImage میسازیم این کلاس از کلاس HtmlSelect ارث بری می کند.بنابراین تمام خصوصیات این کلاس را دارد .این کلاس یک سری متد Virtual دارد که ما آنها را به نحوی که مایلیم در این کلاس جدید پیاده سازی می کنیم .

به کد این کلاس توجه کنید:

using System;
using System.Data;
using System.Text;
using System.Security.Permissions;
using System.Collections;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.HtmlControls;

namespace ComboImg
{

    public class HtmlSelectImage : HtmlSelect
    {

        //Note : If you want to change image height container of HtmlSelectImage change height property of .dd .ddTitle{} in dd.css
        //If you want to change the width , you must set style="width:YYpx" on HtmlSelectImage tag

        private string _currentValue;
        public string currentValue
        {
            get {
                return _currentValue;
            }
            set
            {
                _currentValue = value;
            }
        }
        /// <summary>
        /// Test if the Script manager is not missing for the Sys.WebForms.PageRequestManager manipulation in prerender event
        /// and load script and css
        /// </summary>
        /// <param name="e"></param>
        protected override void OnPreRender(EventArgs e)
        {
            base.OnPreRender(e);

            if (!this.DesignMode)
            {
                // Test for ScriptManager and register if it exists
                // we need it for PageRequestManager manipulation in prerender
                //ScriptManager sm = ScriptManager.GetCurrent(Page);

                //if (sm == null)
                //    throw new HttpException("A ScriptManager control must exist on the current page.");

                //Add js and css files resource
                string cssdd = Page.ClientScript.GetWebResourceUrl(GetType(),"ComboImg.dd.css");
                string scriptJQuery = Page.ClientScript.GetWebResourceUrl(this.GetType(), "ComboImg.jquery-1.3.2.min.js");
                string scriptJQuerydd = Page.ClientScript.GetWebResourceUrl(this.GetType(), "ComboImg.jquery.dd.js");

                HtmlLink lnk = new HtmlLink();
                lnk.Href = cssdd;
                lnk.Attributes["rel"] = "stylesheet";
                lnk.Attributes["type"] = "text/css";

                HtmlGenericControl jq = new HtmlGenericControl("script");
                jq.Attributes.Add("language", "JavaScript");
                jq.Attributes.Add("type", "text/javascript");
                jq.Attributes.Add("src", scriptJQuery);
                jq.Attributes.Add("alt", "scriptJQuery");

                HtmlGenericControl jqdd = new HtmlGenericControl("script");
                jqdd.Attributes.Add("language", "JavaScript");
                jqdd.Attributes.Add("type", "text/javascript");
                jqdd.Attributes.Add("src", scriptJQuerydd);
                jqdd.Attributes.Add("alt", "scriptJQuerydd");

                Page.Header.Controls.Add(jq);
                Page.Header.Controls.Add(jqdd);
                Page.Header.Controls.Add(lnk);

                //Put one time the style whose gives reference to arrow of the combo
                if (!Page.Items.Contains("styleAlreadyPut"))
                {

                    //get url of embedded image
                    string urlImageArrowCombo = Page.ClientScript.GetWebResourceUrl(this.GetType(), "ComboImg.dd_arrow.gif");

                    StringBuilder strStyleArrow = new StringBuilder();

                    strStyleArrow.Append(" .dd .ddTitle span.arrow { ")
                       .Append(" float:right; ")
                       .Append(" display:inline-block; ")
                       .Append(" width:16px; ")
                       .Append(" height:16px; ")
                       .Append(" cursor:pointer; ")
                       .Append(" background-image:url('" + urlImageArrowCombo + "');")
                   .Append(" } ");

                    HtmlGenericControl styleArrow = new HtmlGenericControl("style");
                    styleArrow.Attributes.Add("type", "text/css");

                    jqdd.Controls.Add(
                        new LiteralControl(strStyleArrow.ToString())
                    );

                    Page.Header.Controls.Add(styleArrow);

                    Page.Items.Add("styleAlreadyPut", "styleAlreadyPut");
                
                }



            }
        }

        

        /// <summary>
        /// Generates options tags
        /// </summary>
        /// <param name="writer"></param>
        protected override void RenderChildren(HtmlTextWriter writer)
        {

            if (DataSource != null)
            {
                
                if (DataSource.GetType() == typeof(DataTable))
                {

                    DataTable source = (DataTable)DataSource;


                    if (source.Rows.Count == 0)
                    {
                        base.RenderChildren(writer);
                        return;
                    }

                    foreach (DataRow dr in source.Rows)
                    {

                        string value = FormatString(dr[0]);
                        string imgPath = FormatString(dr[1]);
                        string text = FormatString(dr[2]);
                        bool selected = currentValue.Equals(value);

                        if (selected)
                            writer.Write("<option value='" + value + "' selected='selected' title='" + imgPath + "'>" + text + "</option>");
                        else
                        {
                            writer.Write("<option value='" + value + "'  title='" + imgPath + "'>" + text + "</option>");
                        }


                        writer.WriteLine();
                    }
                
                }

            }
            else
            {
                base.RenderChildren(writer);
            }
        }


        ///Redefine OnDataBinding of the select without DataTextfiled and Datamember properties
        /// <summary>Raises the <see cref="E:System.Web.UI.Control.DataBinding"></see> event of an <see cref="T:System.Web.UI.HtmlControls.HtmlSelect"></see> control.</summary>
        /// <param name="e">A <see cref="T:System.EventArgs"></see> that contains the event data. </param>
        protected override void OnDataBinding(EventArgs e)
        {
            IEnumerable data = base.GetData();

            currentValue = Value;

            if (data != null)
            {

                DataTable source = ((DataView)data).Table;
                base.Items.Clear();
                ICollection is2 = data as ICollection;
                if (is2 != null)
                {
                    this.Items.Capacity = is2.Count;
                }


                foreach (DataRow dr in source.Rows)
                {

                    string value = FormatString(dr[0]);
                    string imgPath = FormatString(dr[1]);
                    string text = FormatString(dr[2]);
                    

                    ListItem it = new ListItem();
                    it.Enabled = true;
                    it.Text = text;
                    it.Value = value;
                    it.Selected = (value.Equals(currentValue));

                    base.Items.Add(it);
                
                }


            }

            Value = currentValue;
            this.ViewState["_!DataBound"] = true;
            this.RequiresDataBinding = false;
        }

        /// <summary>
        /// Set the jQuery script for the combo at the begining of the page request
        /// </summary>
        /// <param name="writer"></param>
        public override void RenderControl(HtmlTextWriter writer)
        {
            base.RenderControl(writer);
            
            StringBuilder scriptInit = new StringBuilder();


                scriptInit.Append(" <script type=\"text/javascript\"> ")
                 .Append(" Sys.WebForms.PageRequestManager.getInstance().add_endRequest(EndRequestHandler); ")
                 .Append("    function EndRequestHandler(sender, args) { ")
                 .Append("       if (args.get_error() == undefined) { ")
                 .Append("            setImageComBo_" + this.ID + "(); ")
                 .Append("       }  ")
                 .Append("     } ")
                 .Append("   function setImageComBo_"+this.ID+"() { ")
                 .Append("       $(document).ready(function() { ")
                 .Append("               $('#"+this.ClientID +"').msDropDown();                       ")
                 .Append("       });  ")
                 .Append("   }  ")
                 .Append("   setImageComBo_" + this.ID + "();    ")
            .Append("</script>");

                writer.Write(scriptInit.ToString());

        }

        /// <summary>
        /// Helper method
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public static string FormatString(object o)
        {
            if(o == null || o == DBNull.Value)
                return "";

            return o.ToString();
        }

        /// <summary>
        /// Helper method
        /// </summary>
        /// <param name="o"></param>
        /// <returns></returns>
        public static bool FormatBool(object o)
        {
            if (o == null || o == DBNull.Value)
                return false;

            return bool.Parse(o.ToString());
        }    
    }
} 

در کلاس OnPreRender چک میشود که آیا ScriptManager وجود دارد یا خیر .و اگر وجود دارد آن را به رفرنس های پروژه اضافه می کند.چرا به ScriptManager نیاز داریم ؟ به این دلیل که در تابع OnPreRender ویژگی های PageRequestManager بازنویسی خواهند شد.در خطوط بعدی این تابع اسکریپت ها و Css به ابتدای صفحه اضافه می شوند .یعنی اگر این کامپوننت به صفحه اضافه شود به صورت خودکار اسکریپت ها و استایل های گفته شده به ابتدای صفحه اضافه میشوند.

در تابع RenderChildren یک DataTable در نظر گرفته شده است .در این DataTable به ترتیب اطلاعات از سورسی که به کامپوننت جدید ما وصل است خوانده شده و در این DataTable ریخته میشود.بعد از اینکه پروژه ضمیمه را اجرا کنید و در FireBugموس را بر روی این کامپوننت قرار دهید می بینید که اطلاعات را از حالتی که همیشه سراغ داشتیم و در آن  DropDownlist تبدیل به یک Select و اطلاعات آن تبدیل به option های این Select میشد، به حالت دیگری که تصویر در کنار نام قرار دارد تبدیل کرده است .

کد مربوط به صفحه به صورت زیر است

<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="defualt.aspx.cs" Inherits="WebApplication2.defualt" %>
<%@ Register TagPrefix="cc1" Namespace="ComboImg" Assembly="ComboImg" %>
<!DOCTYPE html>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title></title>
   

</head>
<body  style="background-color:burlywood">
    <a href="http://www.barnamenevisan.org"> <h3>برنامه نویسان مرجع تخصصی برنامه نویسان</h3></a>
    <br />
    <br />

    <form id="form1" runat="server">
        <asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
        <div> </div>  
        <cc1:HtmlSelectImage id="DropDownList1" style="width:200px;" runat="server" ></cc1:HtmlSelectImage>

    </form>

</body>
</html>

فقط دقت کنید که در قسمت Refrence های پروژه classlibrary که برای ایجاد کامپوننت جدید نوشته بودیم را اضافه کنیم و همچنین در بالا صفحه هم کد زیر را برای افزودن این منبع به پروژه احتیاج داریم .

<%@ Register TagPrefix="cc1" Namespace="ComboImg" Assembly="ComboImg" %>

برای این که این کامپوننت جدید حاوی اطلاعات باشد در قسمت کد این کد ها را می نویسیم

  public partial class defualt : System.Web.UI.Page
    {
        SqlConnection con = new SqlConnection("Data Source=.;Initial Catalog=DB;User ID=sa;Password=123");  
        protected void Page_Load(object sender, EventArgs e)
        {
            if (!IsPostBack)
            {
                data();
                
            }  
        }
        public void data()
        {
            SqlDataAdapter da = new SqlDataAdapter("select Id,Image,name from t", con);
            DataTable dt = new DataTable();
            da.Fill(dt);
            DropDownList1.DataSource = dt;            
            DropDownList1.DataBind();
        }

بعد از اجرای پروژه شکل زیر را خواهید دید.

افزودن تصویر به dropDown در MVC بسیار ساده تر است .در مقالهDropDown یا Combobox تصویری درmvc قرار دادن تصویر در DropDown آموزش داده شده است .

فایل های ضمیمه

برنامه نویسان

نویسنده 3355 مقاله در برنامه نویسان

کاربرانی که از نویسنده این مقاله تشکر کرده اند

در صورتی که در رابطه با این مقاله سوالی دارید، در تاپیک های انجمن مطرح کنید