如何快速实现HTML编辑器.NET组件

如何快速实现HTML编辑器.NET组件



前言

最近由于工作的需要做了一个HTML编辑器,因为时间比较仓促,做得还很不完善,但是在一次调试的过程中偶然发现了一个相当取巧的方法,可以让你在几分钟内实现一个HTML编辑器,希望写出来会对大家有一些借鉴的意义,但由于我自从去年毕业后就再没写过东西,所以文笔不通的地方万望包含。:)


摘要

现在的HTML编辑器主要还是使用JScript技术,MS在这方面有相当完备的支持(比如对一段文字设置加粗只需document.execCommand('bold')),本文主要向大家介绍怎样实现一个HTML编辑器组件(但不会对实现的细节进行过多的描述,具体的JS技术可以查询《JScript 语言参考》)以及怎样实现一个.NET组件。


目录

得到“素材”

封装成ASP.NET组件

添加插件

总结

关于作者

相关连接


** 得到“素材” **

首先我们需要得到一个HTML编辑器的原始代码,网上有不少这类的编辑器,如大名鼎鼎的RichTextBox,DOTNET中华网的DotNetTextBox等等,为了避免版权纠纷,以我所做得为例(暂名:UltraTextBox):在编辑器工具栏的空白地方点击鼠标右键-->查看源代码,如图所示。

把代码拷贝出来保存成一个.htm文件就可以看到效果,是不是感觉很简单的就作了一半?:)

为了以后讲解方面我们把它保存为editor.aspx文件,在这里注意删除掉__VIEWSTATE一段。

然后把相应的图标,CSS文件等保存在相应的位置,否则你的界面会很难看,当然你也可以根据需要自己来做图标。

好了,准备工作基本做完,下面是讲怎样把它封装为.NET组件,方便你在工程中使用。


封装成ASP.NET组件

首先在VS.NET环境里生成一个UltraTextBoxV1组件(也可以称为自定义控件,我习惯称为组件)项目,

using System;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.ComponentModel;
//设置该组件的标记前缀
[assembly:TagPrefix("gOODiDEA.UltraTextBoxV1", "UTBV1")]
namespace gOODiDEA.UltraTextBoxV1
{
//添加类声明
[
DefaultProperty("Text"),
ValidationProperty("Text"),
ToolboxData("<{0}:UltraTextBoxV1 runat=server>

"),
ParseChildren(false),
Designer("gOODiDEA.UltraTextBoxV1.UltraTextBoxV1Designer")
]
public class UltraTextBoxV1: System.Web.UI.Control, IPostBackDataHandler
{
private static readonly object ValueChangedEvent = new object();
//声明一个代理用于处理值被改变的事件,当组件的值更改时发生ValueChanged事件
public event EventHandler ValueChanged
{
add
{
Events.AddHandler(ValueChangedEvent, value);
}
remove
{
Events.RemoveHandler(ValueChangedEvent, value) ;
}
}
//触发值被改变事件的方法
protected virtual void OnValueChanged(EventArgs e)
{
if( Events != null )
{
EventHandler oEventHandler = ( EventHandler )Events[ValueChangedEvent] ;
if (oEventHandler != null) oEventHandler(this, e);
}
}
//处理回发数据
bool IPostBackDataHandler.LoadPostData( string postDataKey, System.Collections.Specialized.NameValueCollection postCollection )
{
if ( postCollection[postDataKey] != Text )
{
Text = postCollection[postDataKey];
return true;
}
return false;
}
//告诉应用程序该组件的状态已更改
void IPostBackDataHandler.RaisePostDataChangedEvent()
{
OnValueChanged( EventArgs.Empty );
}

//我们对一个编辑器主要需要实现下面4个属性,Text,Width,Height,BasePath。

//Text属性:(从编辑器得到值和把值赋给编辑器)
[Bindable(true),DefaultValue("")]
public string Text
{
get
{
object o = ViewState["Text"];
return ( o == null ) ? String.Empty : ( string )o;
}
set
{
ViewState["Text"] = value;
}
}

//Width属性:(编辑器的宽)
[Bindable(true),Category("Appearence"),DefaultValue("100%")]
public Unit Width
{
get
{
object o = ViewState["Width"];
return ( o == null ) ? Unit.Parse( "100%" ) : ( Unit )o ;
}
set
{
ViewState["Width"] = value ;
}
}

//Height属性:(编辑器的高)
[Bindable(true),Category("Appearence"),DefaultValue("385px")]
public Unit Height
{
get
{
object o = ViewState["Height"];
return ( o == null ) ? Unit.Parse( "385px" ) : ( Unit )o ;
}
set
{
ViewState["Height"] = value ;
}
}

//BasePath属性:(第一步保存的editor.aspx的路径以及以后做的插件的路径)
[Bindable(true),DefaultValue("../UltraTextBoxV1Sys/Plug-Ins/")]
public string BasePath
{
get
{
object o = ViewState["BasePath"];
return (o == null) ? "../UltraTextBoxV1Sys/Plug-Ins/" : (string)o;
}
set
{
ViewState["BasePath"] = value;
}
}

//接下来是最重要的怎样把本组件和Editor.aspx结合起来,这里使用的是iframe技术:
//覆盖Render方法,运行时输出:
protected override void Render(HtmlTextWriter output)
{
System.Web.HttpBrowserCapabilities oBrowser = Page.Request.Browser ;
//对应的IE版本必须是5.5或以上的版本
if (oBrowser.Browser == "IE" && oBrowser.MajorVersion >= 5.5 && oBrowser.Win32)
{
string sLink = BasePath + "Editor.aspx?FieldName=" + UniqueID;
//如果不使用SetTimeout则会提示找不到对象
output.Write(
"

1<iframe =="" \\\').value',1000);\"="" document.getelementbyid(\\\'{4}="" frameborder='\"no\"' height='\"{2}\"' id='\"{5}\"' onblur='\"{4}.value' onload="\&quot;javascipt:setTimeout('{5}.HtmlEdit.document.body.innerHTML" scrolling='\"no\"' src='\"{0}\"' width='\"{1}\"' {5}.htmledit.document.body.innerhtml\"=""></iframe>

",
sLink,
Width,
Height,
Text,
UniqueID,
ID + "_editor"
) ;
//存储编辑器的值
output.Write(
"

1<input id='\"{0}\"' name='\"{0}\"' type='\"hidden\"' value='\"{1}\"'/>

",
UniqueID,
System.Web.HttpUtility.HtmlEncode(Text) ) ;
}
}
}

//接下来给该组件实现一个设计时的界面:
public class UltraTextBoxV1Designer : System.Web.UI.Design.ControlDesigner
{
public UltraTextBoxV1Designer(){}
public override string GetDesignTimeHtml()
{
UltraTextBoxV1 oControl = ( UltraTextBoxV1 )Component ;
return String.Format(
"

1<table bgcolor='\"#f5f5f5\"' border='\"1\"' bordercolor='\"#c7c7c7\"' cellpadding='\"0\"' cellspacing='\"0\"' height='\"{1}\"' width='\"{0}\"'><tr><td align='\"center\"' valign='\"middle\"'>UltraTextBox 1.1 - <b>{2}</b></td></tr></table>

",
oControl.Width,
oControl.Height,
oControl.ID ) ;
}
}
}

至此组件部分就基本做完,把它编译后的Dll拷贝你的项目文件夹下,在工具栏-->组件里添加它,你就可以直接拖放进你的页面,在你的工程中使用。


添加插件

这里举两个例子来说明怎样给该编辑器添加插件:
如果你要给编辑器添加一些功能,如上传图片,插入标签等,则首先应该给它添加一个图标:

1<div class="Btn" language="javascript" onclick="UTB_InsertImg()" title="上传图片">
2<img class="Ico" height="16" src="..\images\img.gif" width="16"/>
3</div>
1<div class="Btn" language="javascript" onclick="UTB_InsertExcel()" title="插入EXCEL表格">
2<img class="Ico" height="16" src="..\images\insertexcel.gif" width="16"/>
3</div>

然后在JScript代码里添加UTB_InsertImg(),UTB_InsertExcel()的实现:
function UTB_InsertImg()
{
//只能在编辑模式下使用
if ( ! UTB_validateMode() )
return;
HtmlEdit.focus();
//在当前光标处创建一个区域用于插入图片
var range = HtmlEdit.document.selection.createRange();
//用模式对话框打开上传页面,把返回值插入到编辑器中
var arr = showModalDialog(""uploadface.aspx"", """", ""dialogWidth:430px;dialogHeight:280px;help:0;status:0"");
if (arr != null)
{
//得到的返回值应该是形如:

1<img src="http://dev.csdn.net/Develop/ArticleImages/18/18769/CSDN_Dev_Image_2003-6-2833511.jpg"/>

range.pasteHTML( arr );
}
HtmlEdit.focus();
}

function UTB_InsertExcel()
{
if (!UTB_validateMode())
return;
HtmlEdit.focus();
//在这里其实就是插入一个Microsoft Office Web Components(MSOWC)组件
var range = HtmlEdit.document.selection.createRange();
range.pasteHTML(""

1<object classid="clsid:0002E510-0000-0000-C000-000000000046" codebase="file:\\\Bob\software\office2000\msowc.cab" height="250" id="Spreadsheet1" width="100%"><param name="HTMLURL" value=""/><param ""&lt;x:width&gt;15240&lt;="" &gt;&lt;x:height&gt;7620&lt;="" &lt;="" &lt;x:defaultrowheight&gt;210&lt;="" &lt;x:maxheight&gt;80%&lt;="" &lt;x:protectcontents&gt;false&lt;="" &lt;x:standardwidth&gt;2389&lt;="" .5pt="" border-top:solid="" class="wc4590F88" height="&quot;14&quot;&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;&lt;/body&gt;&lt;/html&gt;'" name="HTMLData" office="" silver'&gt;&lt;x:caption&gt;microsoft="" silver;border-bottom:solid="" silver;border-left:solid="" silver;border-right:solid="" spreadsheet&lt;="" value='&lt;html xmlns:x="urn:schemas-microsoft-com:office:excel"xmlns="http://www.w3.org/TR/REC-html40"&gt;&lt;head&gt;&lt;style type="text/css"&gt;&lt;!--tr{mso-height-source:auto;}td{black-space:nowrap;}.wc4590F88{black-space:nowrap;font-family:宋体;mso-number-format:General;font-size:auto;font-weight:auto;font-style:auto;text-decoration:auto;mso-background-source:auto;mso-pattern:auto;mso-color-source:auto;text-align:general;vertical-align:bottom;border-top:none;border-left:none;border-right:none;border-bottom:none;mso-protection:locked;}--&gt;&lt;/style&gt;&lt;/head&gt;&lt;body&gt;&lt;!--[if gte mso 9]&gt;&lt;xml&gt;&lt;x:ExcelWorkbook&gt;&lt;x:ExcelWorksheets&gt;&lt;x:ExcelWorksheet&gt;&lt;x:OWCVersion&gt;9.0.0.2710&lt;/x:OWCVersion&gt;&lt;x:Label Style=' width='"56"&gt;&lt;tr' x:caption&gt;="" x:defaultrowheight&gt;="" x:excelworkbook&gt;&lt;="" x:excelworksheet&gt;&lt;="" x:excelworksheets&gt;="" x:height&gt;""+="" x:label&gt;&lt;x:name&gt;sheet1&lt;="" x:leftcolumnvisible&gt;="" x:maxheight&gt;&lt;x:maxwidth&gt;80%&lt;="" x:maxwidth&gt;&lt;="" x:name&gt;&lt;x:worksheetoptions&gt;&lt;x:selected="" x:protectcontents&gt;="" x:standardwidth&gt;="" x:str&gt;&lt;col="" x:toprowvisible&gt;&lt;x:leftcolumnvisible&gt;0&lt;="" x:width&gt;&lt;x:toprowvisible&gt;0&lt;="" x:worksheetoptions&gt;="" xml&gt;&lt;![endif]--&gt;&lt;table=""/> <param name="DataType" value="HTMLDATA"/> <param name="AutoFit" value="0"/><param name="DisplayColHeaders" value="-1"/><param name="DisplayGridlines" value="-1"/><param name="DisplayHorizontalScrollBar" value="-1"/><param name="DisplayRowHeaders" value="-1"/><param name="DisplayTitleBar" value="-1"/><param name="DisplayToolbar" value="-1"/><param name="DisplayVerticalScrollBar" value="-1"/> <param name="EnableAutoCalculate" value="-1"/> <param name="EnableEvents" value="-1"/><param name="MoveAfterReturn" value="-1"/><param name="MoveAfterReturnDirection" value="0"/><param name="RightToLeft" value="0"/><param name="ViewableRange" value="1:65536"/></object>

"");
HtmlEdit.focus();
}

关于怎样实现上传图片在这里就不多讲,CSDN上这类帖子太多了。只是要注意一点,因为使用的是模式对话框,所以在该页面不能有回发事件,操作最好在iframe里做。


总结

谢谢你能看到这里,至此一个简单的HTML编辑器就制作完成了,本文主要讲述了如何得到一个HTML编辑器的代码,如何把它封装成一个.NET组件以及通过两个列子讲解了给它添加插件的方法。从上面的步凑你可以看出制作一个HTML编辑器其实很简单,虽然借鉴了一些别人的代码,但如果你仔细分析一下那些JS脚本,你就会豁然开朗的,如果你有更好的想法希望能告诉我。


关于作者

作者:袁剑(gOODiDEA)

电子邮件:[email protected]


相关连接

http://www.htjj.com/yj/sample/utbv1.aspx

Published At
Categories with Web编程
Tagged with
comments powered by Disqus