带图像的ASP.NET 组合框控件

分享于 

12分钟阅读

Web开发

  繁體
static 模式 DropdownlistImage

drop.JPG

动态数据绑定动态模式 DropdownlistImage

drop.JPG

介绍

查找可以包含图像和文本的自由和兼容(。使用所有浏览器) dropdownlist是非常困难的。 然而,我查看了jQuery开源组件,发现jQuery开发人员对他们开发的几个小部件做了出色的工作。 jQuery是一个强大的JavaScript框架,具有非常漂亮和优化的小部件。

我在简单的HTML页面中找到了他们的dropdownlist图像示例,我决定尝试创建一个可以伸缩的HTML控件,它封装了。 简单示例的URL是 http://marghoobsuleman.com/jquery-image-dropdown

使用代码

基本组件是一个非常简单的基本 HtmlSelect ( System.Web.UI.Htmlcontrols 命名空间)。 我扩展了这个类以添加特定的行为。

开始时,我将组件的资源添加到程序集( JavaScript文件,CSS文件和扩展 HtmlSelect 类的箭头图像) 中。 i PreRender 方法的重写,这些资源,并且在 AssemblyInfo.cs 文件中添加了引用。 这里是微软推荐的。 所有这些资源必须是"嵌入式资源"。

下面的代码显示了一个特殊情况: 如何显示嵌入在程序集中的图片并在CSS代码中调用它。 开始时,HtmlSelect的箭头图像在 dd.css 中引用,如下所示:

.dd. ddTitlespan.arrow 
{ 
 float:right; 
 display:inline-block; 
 width:16px; 
 height:16px; 
 cursor:pointer;background-image:url('arrow_d.gif');}

因为图片的URL不是 arrow_d.gif,所以 ASP.NET 无法用这个声明显示 arrow_d.gif。 如果要显示这里图片,则必须执行以下三个步骤:

步骤: 你必须使用 ClientScript 对象的GetWebResourceUrl 方法获取图像 URL:

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

( 在本示例中,图片位于程序集的root 处)。 如果图片位于名为""的程序集目录中," AssemblyName.dd_arrow.gif"将成为" AssemblyName.toto.dd_arrow.gif"。

收费:提取CSS文件名并将它的放入服务器端,以便在样式中注入图像 URL:

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);

如果你希望在页面中添加大量 HtmlSelect 图像,则必须由所有 HtmlSelect 图像控件共享页面的header 中添加的样式。 那么测试 Page.Items.Contains("styleAlreadyPut")) 是必需的,用于一次添加样式。 OnPreRender 事件是添加像我刚才解释过的资源。 下面是代码:

/// Test if the Script manager is not missing/// for the Sys.WebForms.PageRequestManager manipulation in prerender event/// and load script and cssprotectedoverridevoid 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)
 thrownew HttpException("A ScriptManager control" + 
 "must exist on the current page.");
 //Add js and css files resourcestring 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 comboif (!Page.Items.Contains("styleAlreadyPut"))
 {
 //get url of embedded imagestring 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");
 }
 }
}

我覆盖了 OnDataBinding 方法,因为 HtmlSelect的基本 OnDataBinding 只在定义 DataValueFieldDataTextField 时进行特定处理。 ( 观察带有反射器( 那是你最好的朋友- )的OnDataBinding的源代码)。)

,我们不使用这些属性,因为不需要它们,需要使用绑定 DataTable的值创建一个 ListItem。 要查看的final 点是 currentValue 属性,它允许在数据绑定之前保存当前选择的值,以便以后检索。

///Redefine OnDataBinding of the select///without DataTextfiled and Datamember propertiesprotectedoverridevoid 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)
 {
 stringvalue = 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;
}

使用反射器,我查看了 HtmlSelect 类的RenderChildren 方法的实现。 在我的例子中,我做了两个区别:

  • 没有数据绑定:调用 RenderChildren 基类。
  • 使用数据绑定:重写 RenderChildren 实现以生成具有正确格式的选项标记。

正确的格式是 "项目文本"。

结论是,如果要对这里组合进行处理,必须提供具有三个列的DataTable:

  • 项目值
  • 图像路径
  • 项的文本

以下是 RenderChildren 实现:

/// Generates options tagsprotectedoverridevoid 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)
 {
 stringvalue = FormatString(dr[0]);
 string imgPath = FormatString(dr[1]);
 string text = FormatString(dr[2]);
 bool selected = currentValue.Equals(value);
 if (selected)
 writer.Write("" + text + "");
 else {
 writer.Write("" + text + "");
 }
 writer.WriteLine();
 }
 }
 }
 else {
 base.RenderChildren(writer);
 }
}

RenderControl 添加了一个脚本,它允许使用强大的jQuery框架初始化 dropdownlist。 要初始化 dropdownlist,必须执行以下jQuery语句: $(document).ready(function() { $('#dropdownlistId').msDropDown(); } 但是,如果只执行这些语句,ASP.NET 将在加载阶段遇到JavaScript错误。

Arnold是一个 JQuery ASP.NET 开发人员,他在 ASP.NET 中使用JQuery的解决方案在这里是。 解决方案很简单:在请求AJAX事件结束时执行这个脚本。

/// Set the jQuery script for the combo at the beginning of the page requestpublicoverridevoid 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.ID +"').msDropDown(); ")
. Append(" }); ")
. Append(" } ")
. Append(" setImageComBo_" + this.ID +"(); ")
. Append("</script>");
 writer.Write(scriptInit.ToString());
}

Points of Interest

我学会了在 ASP.NET 中封装一个jQuery组件。 我邀请你尝试开发更多的jQuery ASP.NET 网页控件;它们非常有用而且非常漂亮。

我期待你的建议。

历史记录

  • 28th 2009年09月: 初始帖子
  • 29th 2009年09月: 更新源代码

COM  图像  asp  asp-net  images  dropdownlist  
相关文章