下一步,将给pimedouttextbox控件新增两个属性。其中,我们设想,当用户在文本框中输入或者文本框获得焦点时,文本框的颜色有变化,所以命名新的属性BackColoron;当控件失去焦点时,文本框的颜色命名为backcoloroff。
line 1: private Color _colOff; line 2: [Category( "Appearance" ), Description( "The background color when the control loses focus" )] line 3: public Color BackColorOff line 4: { line 5: get{return _colOff;} line 6: set{_colOff = value line 7: } line 8: private Color _colOn; line 9: [Category( "Appearance" ), Description( "The background color when the control has the focus" )] line 10: public Color BackColorOn line 11: { line 12: get{return _colOn; } line 13: set{_colOn = value;} line 14: } |
上面的代码,是典型的对属性的赋值和存取的语句了,相信大家都很熟悉了。要提及一点的是,第2行和第9行的category和descriptiton属性,是该控件的属性窗口中,对backcoloron和backcoloroff两个属性的一个描述。注意,我们使用了color类,这样比较方便,可以用vs.net自带的颜色选择器,而不用输入颜色的十六进制值。
接着,下面是比较重要的部分。在这个新的控件, 我们将用重载一个AddAttributesToRender()的方法输出新的内容到浏览器中。其中,将加入对客户端的onfocus和onblur事件的响应。另外,要注意的是,当在VS.NET创建该控件时,会自动调用该方法,所以我们可以在设计期间对其中的属性进行设置。
line 1: protected override void AddAttributesToRender( HtmlTextWriter writer ) line 2: { line 3: base.AddAttributesToRender( writer ); line 4: //only add the client-side javascript for design mode or IE line 5: if( inDesignMode() || System.Web.HttpContext.Current.Request.Browser.Type.IndexOf( "IE" ) > -1 ) line 6: { line 7: writer.AddAttribute( "onFocus", "JavaScript:this.style.backgroundColor='" + ColorTranslator.ToHtml( _colOn ) + "';" ); line 8: if( _colOff.Equals( Color.Empty ) ) line 9: { line 10: _colOff = this.BackColor; line 11: } line 12: writer.AddAttribute( "onBlur", "JavaScript:this.style.backgroundColor='" + ColorTranslator.ToHtml( colOff ) + "';" ); line 13: } line 14: } |
其中第3行的目的是,调用基类,继承原有的文本框的属性。AddAttributesToRender的方法使用HtmlTextWriter流作为参数。在第9,第12行,分别通过调用HTML文本流的AddAttribute方法增加其客户端的输出。其中传入了两个参数,第一个参数是HTML的属性,第二个是属性对应的值。它们经过浏览器输出后,变为<input type="text" >的形式。
因为浏览器使用的是十六进制的颜色,所以我们采用ColorTranslator类去将.NET的颜色类型转换为浏览器中能识别的颜色类型(第7和第12行)。在第8行,先检查_coloroff属性是否没被赋值,如果没赋值,则backcoloroff的颜色设置为原来文本框的背景色。
而在第5行,我们检查浏览器的类型是否支持onfocus和onblur事件,并且由于想在VS.NET的设计时就能对控件的属性进行改变,所以增加了一个判断的函数indesignmode:
line 1: private bool inDesignMode() line 2: { line 3: bool blnOut = false; line 4: if( object.ReferenceEquals( System.Web.HttpContext.Current, null ) ) line 5: { line 6: blnOut = true; line 7: } line 8: else line 9: { line 10: blnOut = false; line 11: } line 12: return blnOut; line 13: } |
在上面代码的第4行,通过判断如果HttpContext实例是否为null,如果为null的话,则证明当前是处于VS.NET的设计模式下,没响应HTTP请求。接下来,我们测试一下所做的控件。