ASP.NET 颜色选取器Web服务器控件

分享于 

14分钟阅读

Web开发

  繁體
ColorPickerDemo.png

介绍

很难为 ASP.NET 找到合适的颜色选取器控件。 然而,有很多纯JavaScript颜色选取器控件。 我决定接受其中一个并将它的转换为 ASP.NET web服务器控件。 作为基础,我采用了 dhtmlgoodies高级颜色选择器。

项目设置

首先,让我们做一个新项目-> ASP.NET 服务器控件。 默认情况下,项目的NAME 将与默认命名空间的NAME 相同。 我调用了项目 WebControls,并将 ServerControl1.cs 命名为 ColorPicker.cs。 我将默认命名空间更改为 Karpach.WebControls,以及汇编 NAME。 然后,我将 dhtmlgoodies 提供的图像。JavaScript和样式添加到项目中。

CustomControlSolutionFiles.gif

然后,单击文件的每个属性,并将生成操作从内容更改为嵌入资源。 我还重新命名了一些文件。

AssemblyInfo.cs

我注册了所有这样的资源:

[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.SliderHandle.gif",
 "img/gif")][assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.TabCenterActive.gif",
 "img/gif")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.TabLeftActive.gif",
 "img/gif")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.TabLeftInactive.gif",
 "img/gif")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.TabRightActive.gif",
 "img/gif")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.TabRightInactive.gif",
 "img/gif")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Images.ColorPickerIcon.jpg",
 "img/jpeg")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Styles.ColorPicker.css",
 "text/css")]
[assembly: System.Web.UI.WebResource("Karpach.WebControls.Javascript.ColorPicker.js",
 "text/js")]

你可能已经注意到,System.Web.UI.WebResource,第一个参数具有以下签名:

[Assembly Name].[Folder].[File Name]

这非常重要,因为即使在MSDN中它也没有记录。

ColorPicker.cs

为了为控件启用验证器,你需要指定服务器控件类的ValidationProperty 属性。

[DefaultProperty("Color"),ValidationProperty("Color")]

我修改了 ToolboxData 以如下所示:

[ToolboxData("<{0}:ColorPicker runat="server">")]

接下来,我在 Visual Studio 工具箱中想要一个定制的icon。 在 ToolboxData 之后,我添加了以下行:

[System.Drawing.ToolboxBitmap(typeof(ColorPicker),"Images.color_picker_icon.jpg")]

其中第一个参数是控件类型,第二个参数是在 AssemblyInfo.cs 中使用的icon 文件 NAME。

最初的颜色选取器有两个JavaScript文件: color_functions.js。 我将它们合并在一个文件中,即。 那些文件里有很多。 我将所有的东西组合在一个JavaScript类中,公开了一些 public 属性和一个 public 函数 ShowColorPicker

function ColorPicker(options)
{
 // Public propertiesthis.FormWidgetAmountSliderHandleImage = options.FormWidgetAmountSliderHandleImage;
 this.TabRightActiveImage = options.TabRightActiveImage;
 this.TabRightInactiveImage = options.TabRightInactiveImage;
 this.TabLeftActiveImage = options.TabLeftActiveImage;
 this.TabLeftInactiveImage = options.TabLeftInactiveImage;
 this.AutoPostBack = options.AutoPostBack;
 this.AutoPostBackReference = options.AutoPostBackReference;
 this.PopupPosition = options.PopupPosition;
 // Public methodsthis.ShowColorPicker = function(inputObj, formField)
 {
 //..... }
 // Private variables//.. ..// Private functions//.. ..}

经过一些反馈之后,我不得不修复 JavaScript,以支持 ASP.NET AJAX UpdatePanelModalPopup 扩展程序。

然后,我需要将DLL中存储的资源加载到JavaScript类中。 这是 OnPreRender的最佳事件:

// Javascriptstring colorFunctions = Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker),
 "Karpach.WebControls.Javascript.ColorPicker.js");
Page.ClientScript.RegisterClientScriptInclude("ColorPicker.js", colorFunctions);// Create ColorPicker objectstring script = string.Format(@"var colorPicker_{0} = new ColorPicker({{
FormWidgetAmountSliderHandleImage : '{1}',
TabRightActiveImage : '{2}',
TabRightInactiveImage : '{3}',
TabLeftActiveImage : '{4}',
TabLeftInactiveImage : '{5}',
AutoPostBack : {6},
AutoPostBackReference :""{7}"",
PopupPosition : {8}
}}); 
", ClientID
, Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), 
 "Karpach.WebControls.Images.SliderHandle.gif")
, Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), 
 "Karpach.WebControls.Images.TabRightActive.gif")
, Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), 
 "Karpach.WebControls.Images.TabRightInactive.gif")
, Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), 
 "Karpach.WebControls.Images.TabLeftActive.gif")
, Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), 
 "Karpach.WebControls.Images.TabLeftInactive.gif") 
, AutoPostBack?"true":"false", Page.ClientScript.GetPostBackEventReference(this,"")
, (int)PopupPosition
 );
Page.ClientScript.RegisterStartupScript(Page.GetType(), 
 String.Format("InitColorPicker_{0}", ClientID), script, true);if (!DesignMode && Page.Header!= null)
{
 RegisterCSSInclude(Page.Header);
}

其中,RegisterCSSInclude 是以下 helper 方法:

privatevoid RegisterCSSInclude(Control target)
{
 // CSS bool linkIncluded = false;
 foreach (Control c in target.Controls)
 {
 if (c.ID == "ControlPickerStyle")
 {
 linkIncluded = true;
 }
 }
 if (!linkIncluded)
 {
 HtmlGenericControl csslink = new HtmlGenericControl("link");
 csslink.ID = "ControlPickerStyle";
 csslink.Attributes.Add("href", Page.ClientScript.GetWebResourceUrl
 (typeof(ColorPicker), "Karpach.WebControls.Styles.ColorPicker.css"));
 csslink.Attributes.Add("type", "text/css");
 csslink.Attributes.Add("rel", "stylesheet");
 csslink.EnableViewState = false;
 target.Controls.Add(csslink);
 }
}

然后我重写 WebControl 类的Render 事件,以呈现控件 HTML。

using (PlaceHolder plh = new PlaceHolder())
{
 if (DesignMode || Page.Header == null)
 RegisterCSSInclude(plh);
 Table table = new Table();
 table.CellPadding = 0;
 table.CellSpacing = 0;
 table.Rows.Add(new TableRow());
 table.Rows[0].Cells.Add(new TableCell());
 table.Rows[0].Cells.Add(new TableCell());
 table.Rows[0].Cells.Add(new TableCell());
 table.Rows[0].Cells[1].Style.Add(HtmlTextWriterStyle.PaddingRight, "5px");
 HtmlGenericControl txt = new HtmlGenericControl("input");
 txt.EnableViewState = false;
 txt.Attributes.Add("maxlength", "15");
 txt.Attributes.Add("size", "15");
 txt.Attributes.Add("value", Color);
 txt.Attributes.Add("id", ClientID);
 txt.Attributes.Add("name", UniqueID);
 txt.Attributes.CssStyle.Value = "height:17px;padding:2px;";
 table.Rows[0].Cells[0].Controls.Add(txt);
 HtmlGenericControl colorBar = new HtmlGenericControl("div");
 colorBar.EnableViewState = false;
 colorBar.Attributes.CssStyle.Add(HtmlTextWriterStyle.Height, "21px");
 colorBar.Attributes.CssStyle.Add(HtmlTextWriterStyle.Width, "5px");
 colorBar.Attributes.CssStyle.Add("border", "solid 1px #7f9db9");
 colorBar.Attributes.CssStyle.Add(HtmlTextWriterStyle.BackgroundColor, Color);
 table.Rows[0].Cells[1].Controls.Add(colorBar);
 HtmlInputImage btn = new HtmlInputImage();
 btn.Src = Page.ClientScript.GetWebResourceUrl(typeof(ColorPicker), 
 "Karpach.WebControls.Images.ColorPickerIcon.jpg");
 btn.Attributes.Add("onclick", string.Format("colorPicker_{0}.ShowColorPicker
 (this,document.getElementById('{1}'));return false;", ClientID, ClientID));
 btn.Attributes.CssStyle.Add(HtmlTextWriterStyle.ZIndex, "1");
 HtmlGenericControl container = new HtmlGenericControl("div");
 container.EnableViewState = false;
 container.Controls.Add(btn);
 container.Attributes.CssStyle.Add(HtmlTextWriterStyle.Position, "static");
 container.Attributes.CssStyle.Add(HtmlTextWriterStyle.Display, "block");
 table.Rows[0].Cells[2].Controls.Add(container);
 plh.Controls.Add(table);
 plh.RenderControl(output);
}

有几种方法可以保存颜色选取器的postback 值。 然而,我认为最好的方法是实现 IPostBackDataHandler 接口。

publicbool LoadPostData(string postDataKey,NameValueCollection postCollection)
{
 String presentValue = Color;
 String postedValue = postCollection[postDataKey];
 if (presentValue == null ||!presentValue.Equals(postedValue))
 {
 Color = postedValue;
 returntrue;
 }
 returnfalse;
}publicvirtualvoid RaisePostDataChangedEvent()
{
 OnColorChanged(EventArgs.Empty);
}publicvoid OnColorChanged(EventArgs e)
{
 if (ColorChanged!= null)
 ColorChanged(this, e);
}

LoadPostData 方法将在每个 postback 过程中调用,当 postback 窗体具有密钥 this.UniqueID的标记时。 你可以看到 上面,呈现的输入标记具有 NAME 属性 this.UniqueID

通过重写 LoadControlStateSaveControlStateColorPicker 属性存储在 ControlState 中:

protectedoverridevoid LoadControlState(object savedState)
{
 Color = (string)(savedState as object[])[0];
 AutoPostBack = (bool)(savedState as object[])[1];
 PopupPosition = (PopupPosition)(savedState as object[])[2];
}protectedoverrideobject SaveControlState()
{
 object []saveState = new object[3];
 saveState[0] = Color;
 saveState[1] = AutoPostBack;
 saveState[2] = PopupPosition;
 return (object)saveState;
}

你需要调用 RegisterRequiresControlState 方法来控制参与控制状态,否则和 SaveControlState 不会触发。

protectedoverridevoid OnInit(EventArgs e)
{
 base.OnInit(e);
 Page.RegisterRequiresControlState(this);
}

Build.proj

现在,final touch: JavaScript和CSS的缩小。 我使用了 Yahoo YUI 压缩器和微软。 下面是 final MSbuild file:

<?xmlversion="1.0"encoding="utf-8"?><ProjectToolsVersion="3.5"xmlns="http://schemas.microsoft.com/developer/msbuild/2003"><PropertyGroup><MSBuildCommunityTasksPath>..References</MSBuildCommunityTasksPath><ProjectName>WebControls</ProjectName> 
 </PropertyGroup><TargetName="Compress"><MessageText="Create temp files.. ."/><CopySourceFiles=".$(ProjectName)JavascriptColorPicker.js"DestinationFiles=".$(ProjectName)JavascriptColorPicker.js.full"/> 
 <CopySourceFiles=".$(ProjectName)StylesColorPicker.css"DestinationFiles=".$(ProjectName)StylesColorPicker.css.full"/> 
 <ExecCommand=
"java -jar yuicompressor-2.4.2.jar --type js. $(ProjectName)
 JavascriptColorPicker.js.full>. $(ProjectName)JavascriptColorPicker.js"/><ExecCommand=
"java -jar yuicompressor-2.4.2.jar --type css. $(ProjectName)Styles
 ColorPicker.css.full>. $(ProjectName)StylesColorPicker.css"/></Target><ImportProject=".ReferencesMSBuild.Community.Tasks.targets"/><TargetName="Build"DependsOnTargets="Compress"><MessageText="Building Project"/><MSBuildProjects="./$(ProjectName)/$(ProjectName).sln"Properties="Configuration=Release;Platform=Any CPU"/> 
 </Target></Project>

现在你甚至不需要 Visual Studio 来编译 DLL。 你所需要的是安装. NET 2.0,然后下面的控制台脚本将执行编译:

%SystemRoot%Microsoft.NETFrameworkv2.0.50727MSBuild.exe Build.proj/t:Build

每个请求 below,我添加了 PopupPosition 属性,因此你可以指定 ColorPicker popup ( 左上,右上,左下角,右下角- 默认)的位置。

我还添加了 AutoPostBack 属性和 ColorChanged 事件。


WEB  Server  控制  COL  asp  asp-net  
相关文章