ASP.NET 2.0服务器控件之复合控件样式2
点击次数:28 次 发布日期:2008-11-26 12:18:42 作者:源代码网
|
源代码网推荐 源代码网推荐 在上一节中,说明了有关实现复合控件样式的内容,但是,那种实现方法只能实现子控件部分的样式,并且缺乏逻辑性和组织性。本小节介绍的实现复合控件样式属性的方法有效避免了以上问题。它实现了多重委托的属性,即对每个子控件分别定义Width、Height等样式,更进一步的讲,即实现每个子控件对应的Style类型的复杂样式属性,例如,TextBoxStyle、ButtonStyle。通过这种方式子控件的样式属性就上传为顶层属性,以便于设置子控件的外观。 源代码网推荐 源代码网推荐 显而易见,实现子控件的样式属性上传的关键是实现Style类型的复杂样式属性。为此,开发人员必须为复杂样式属性提供自定义视图状态管理。需要读者注意的是,复合控件的视图状态与普通控件视图状态有所不同。由于复合控件包含子控件,因此,相应的视图状态中既包括父控件的视图状态,也包括子控件对应的复杂样式属性的视图状态。例如,上文实例中控件的视图状态即包含3个部分:父控件自身的视图状态、ButtonStyle的视图状态和TextBoxStyle的视图状态。除此之外,具体的实现过程与实现普通的复杂属性基本一致。 源代码网推荐 源代码网推荐 不知读者是否还记得上一篇文章中的那个复合控件,即由一个文本框TextBox和一个按钮Button组成的复合控件CompositeEvent。在此,我们对该控件添加设置了控件的顶层样式属性ButtonStyle和TextBoxStyle。下面列举了控件类CompositeEvent的源代码。 源代码网推荐 源代码网推荐 using System; 源代码网推荐 using System.Web.UI; 源代码网推荐 using System.Web.UI.WebControls; 源代码网推荐 using System.ComponentModel; 源代码网推荐 using System.ComponentModel.Design; 源代码网推荐 namespace WebControlLibrary{ 源代码网推荐 public class CompositeEvent : CompositeControl { 源代码网推荐 //声明变量 源代码网推荐 private Button _button; 源代码网推荐 private TextBox _textBox; 源代码网推荐 private static readonly object EventSubmitKey = new object(); 源代码网推荐 //声明样式变量 源代码网推荐 private Style _buttonStyle; 源代码网推荐 private Style _textBoxStyle; 源代码网推荐 //定义属性ButtonText,用于指定按钮上的文字 源代码网推荐 [Bindable(true), Category("Appearance"), DefaultValue(""), Description("获取或设置显示显示在按钮上的文字")] 源代码网推荐 源代码网推荐 public string ButtonText { 源代码网推荐 get { EnsureChildControls(); return _button.Text; } 源代码网推荐 set { EnsureChildControls(); _button.Text = value; } 源代码网推荐 } 源代码网推荐 //定义属性Text,表示文本框的输入 源代码网推荐 源代码网推荐 [Bindable(true), Category("Appearance"), DefaultValue(""), Description("获取或设置文本框输入文本")] 源代码网推荐 public string Text { 源代码网推荐 get { 源代码网推荐 EnsureChildControls(); 源代码网推荐 return _textBox.Text; 源代码网推荐 } 源代码网推荐 set { 源代码网推荐 EnsureChildControls(); 源代码网推荐 _textBox.Text = value; 源代码网推荐 } 源代码网推荐 } 源代码网推荐 // 定义ButtonStyle属性 源代码网推荐 [ Category("Style"), Description("Button的样式属性"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(true), PersistenceMode(PersistenceMode.InnerDefaultProperty) ] 源代码网推荐 源代码网推荐 public virtual Style ButtonStyle { 源代码网推荐 get { 源代码网推荐 if (_buttonStyle == null) { 源代码网推荐 _buttonStyle = new Style(); 源代码网推荐 if (IsTrackingViewState) { 源代码网推荐 ((IStateManager)_buttonStyle).TrackViewState(); 源代码网推荐 } 源代码网推荐 } 源代码网推荐 return _buttonStyle; 源代码网推荐 } 源代码网推荐 } 源代码网推荐 //定义TextStyle属性 源代码网推荐 源代码网推荐 [ Category("Style"), Description("设置TextBox的样式属性"), DesignerSerializationVisibility(DesignerSerializationVisibility.Content), NotifyParentProperty(true), PersistenceMode(PersistenceMode.InnERProperty) ] 源代码网推荐 源代码网推荐 public virtual Style TextBoxStyle { 源代码网推荐 get { 源代码网推荐 if (_textBoxStyle == null) { 源代码网推荐 _textBoxStyle = new Style(); 源代码网推荐 if (IsTrackingViewState) { 源代码网推荐 ((IStateManager)_textBoxStyle).TrackViewState(); 源代码网推荐 } 源代码网推荐 } 源代码网推荐 return _textBoxStyle; 源代码网推荐 } 源代码网推荐 } 源代码网推荐 // 实现事件属性结构 源代码网推荐 public event EventHandler Submit { 源代码网推荐 add { Events.AddHandler(EventSubmitKey, value); } 源代码网推荐 remove { Events.RemoveHandler(EventSubmitKey, value); } 源代码网推荐 } 源代码网推荐 // 实现OnSubmit 源代码网推荐 protected virtual void OnSubmit(EventArgs e) { 源代码网推荐 EventHandler SubmitHandler = (EventHandler)Events[EventSubmitKey]; 源代码网推荐 if (SubmitHandler != null) { 源代码网推荐 SubmitHandler(this, e); 源代码网推荐 } 源代码网推荐 } 源代码网推荐 源代码网推荐 // 重写ICompositeControlDesignerAccessor接口的RecreateChildContrls方法 源代码网推荐 protected override void RecreateChildControls() { EnsureChildControls(); } 源代码网推荐 //重写CreateChildControls方法,将子控件添加到复合控件中 源代码网推荐 protected override void CreateChildControls() { 源代码网推荐 Controls.Clear(); 源代码网推荐 _button = new Button(); 源代码网推荐 _textBox = new TextBox(); 源代码网推荐 _button.ID = "btn"; 源代码网推荐 //_button.Click += new EventHandler(_button_Click); 源代码网推荐 _button.CommandName = "Submit"; 源代码网推荐 this.Controls.Add(_button); 源代码网推荐 this.Controls.Add(_textBox); 源代码网推荐 } 源代码网推荐 // 重写OnBubbleEvent方法,执行事件冒泡 源代码网推荐 protected override bool OnBubbleEvent(object source, EventArgs e) { 源代码网推荐 bool handled = false; 源代码网推荐 if (e is CommandEventArgs) { 源代码网推荐 CommandEventArgs ce = (CommandEventArgs)e; 源代码网推荐 if (ce.CommandName == "Submit") { 源代码网推荐 OnSubmit(EventArgs.Empty); 源代码网推荐 handled = true; 源代码网推荐 } 源代码网推荐 } 源代码网推荐 return handled; 源代码网推荐 } 源代码网推荐 //重写Render方法,呈现控件中其他的HTML代码 源代码网推荐 protected override void Render(HtmlTextWriter output) { 源代码网推荐 AddAttributesToRender(output); 源代码网推荐 if (_textBoxStyle != null) { 源代码网推荐 _textBox.ApplyStyle(TextBoxStyle); 源代码网推荐 } 源代码网推荐 if (_buttonStyle != null) { 源代码网推荐 _button.ApplyStyle(ButtonStyle); 源代码网推荐 } 源代码网推荐 output.AddAttribute(HtmlTextWriterAttribute.Border, "0px"); 源代码网推荐 output.AddAttribute(HtmlTextWriterAttribute.Cellpadding, "5px"); 源代码网推荐 output.AddAttribute(HtmlTextWriterAttribute.Cellspacing, "0px"); 源代码网推荐 output.RenderBeginTag(HtmlTextWriterTag.Table); 源代码网推荐 output.RenderBeginTag(HtmlTextWriterTag.Tr); 源代码网推荐 output.RenderBeginTag(HtmlTextWriterTag.Td); 源代码网推荐 _textBox.RenderControl(output); 源代码网推荐 output.RenderEndTag(); 源代码网推荐 output.RenderBeginTag(HtmlTextWriterTag.Td); 源代码网推荐 _button.RenderControl(output); 源代码网推荐 output.RenderEndTag(); 源代码网推荐 output.RenderEndTag(); 源代码网推荐 output.RenderEndTag(); 源代码网推荐 } 源代码网推荐 //复杂样式属性的状态管理,重写3个相关方法LoadViewState、 SaveViewState、TrackViewState 源代码网推荐 源代码网推荐 protected override void LoadViewState(object savedState) { 源代码网推荐 if (savedState == null) { 源代码网推荐 base.LoadViewState(null); 源代码网推荐 return; 源代码网推荐 } 源代码网推荐 if (savedState != null) { 源代码网推荐 object[] myState = (object[])savedState; 源代码网推荐 if (myState.Length != 3) { throw new ArgumentException("无效的ViewState"); } 源代码网推荐 base.LoadViewState(myState[0]); if (myState[1] != null) { 源代码网推荐 ((IStateManager)TextBoxStyle).LoadViewState(myState[1]); 源代码网推荐 } 源代码网推荐 if (myState[2] != null) { 源代码网推荐 ((IStateManager)ButtonStyle).LoadViewState(myState[2]); 源代码网推荐 } 源代码网推荐 } 源代码网推荐 } 源代码网推荐 源代码网推荐 protected override object SaveViewState() { 源代码网推荐 object[] myState = new object[3]; 源代码网推荐 myState[0] = base.SaveViewState(); 源代码网推荐 myState[1] = (_textBoxStyle != null) ? ((IStateManager)_textBoxStyle).SaveViewState() : null; 源代码网推荐 myState[2] = (_buttonStyle != null) ? ((IStateManager)_buttonStyle).SaveViewState() : null; 源代码网推荐 for (int i = 0; i < 3; i++) { 源代码网推荐 if (myState[i] != null) { return myState; } 源代码网推荐 } 源代码网推荐 return null; 源代码网推荐 } 源代码网推荐 protected override void TrackViewState() { 源代码网推荐 base.TrackViewState(); 源代码网推荐 if (_buttonStyle != null) { 源代码网推荐 ((IStateManager)_buttonStyle).TrackViewState(); 源代码网推荐 } 源代码网推荐 if (_textBoxStyle != null) { 源代码网推荐 ((IStateManager)_textBoxStyle).TrackViewState(); 源代码网推荐 } 源代码网推荐 } 源代码网推荐 } 源代码网推荐 } 源代码网推荐 源代码网推荐 如果读者看过前面的文章,那么应该对以上代码不陌生。限于篇幅,本文不对先前说明过的内容进行讲解,而重点说明有关样式冒泡的内容。 源代码网推荐 源代码网推荐 与样式冒泡相关的内容可以分成三个部分:一是定义Style类型的复杂样式属性:ButtonStyle和TextBoxStyle;二是在Render方法中为子控件应用复杂样式属性;三是实现复杂样式属性的自定义视图状态管理部分。以上三个部分的实现,实际是实现子控件样式上传过程中最为关键的三个步骤。前两个部分的实现比较简单,在此就不多加说明。下面重点说明最后一个部分的实现。 源代码网推荐 源代码网推荐 第三部分主要实现复杂样式属性的自定义状态管理。在TrackViewState方法中,分别对基类、_textBoxStyle和_buttonStyle调用TrackViewState。在SaveViewState方法中,首先定义一个myState对象数组,然后按顺序将基类、TextBox和Button的视图状态数据保存到myState中并返回。在LoadViewState方法中,实现将所保存的状态数据(savedState)的第一部分加载入基类,第二部分加载给TextBoxStyle,第三部分加载给ButtonStyle,之所以按照如此顺序加载是与SaveViewState方法中的保存顺序对应的。 源代码网推荐 源代码网推荐 下面是CompositeEvent控件的应用代码片断。请读者注意的是:ButtonStyle和TextBoxStyle都是作为内部嵌套形式属性而标记,用户通过设置样式属性即可完成对子控件的外观设置。 源代码网推荐 源代码网推荐 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.ASPx.cs" Inherits="_Default" %> 源代码网推荐 <%@ ReGISter TagPrefix="Sample" Assembly="WebControlLibrary" Namespace="WebControlLibrary" %> 源代码网推荐 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> 源代码网推荐 <script runat="server"> 源代码网推荐 void demo1_Submit(object sender, EventArgs e) 源代码网推荐 { 源代码网推荐 lbMessage.Text = "您刚才输入的是:" + demo1.Text; 源代码网推荐 } 源代码网推荐 </script> 源代码网推荐 <html XMLns="http://www.w3.org/1999/xhtml"> 源代码网推荐 <head id="Head1" runat="server"> 源代码网推荐 <title>为复合控件实现样式</title> 源代码网推荐 </head> 源代码网推荐 <body> <form id="form1" runat="server"> 源代码网推荐 <div> 源代码网推荐 <Sample:CompositeEvent ID="demo1" runat="server" ButtonText="提交" OnSubmit="demo1_Submit"> 源代码网推荐 <TextBoxStyle Width="198px" Height="20px" BorderWidth="1px" BackColor="orange"> 源代码网推荐 </TextBoxStyle> 源代码网推荐 <ButtonStyle Width="84px" Height="24px" BorderWidth="1px" BorderStyle="dotted"></ButtonStyle> 源代码网推荐 </Sample:CompositeEvent> 源代码网推荐 <br /> 源代码网推荐 <asp:Label ID="lbMessage" runat="server"> 源代码网推荐 </asp:Label> </div> 源代码网推荐 </form> 源代码网推荐 </body> 源代码网推荐 </html> 源代码网推荐 源代码网推荐 下面列举了示例应用效果图。 源代码网推荐 源代码网推荐 源代码网推荐 做人要厚道,请注明转自酷网动力(www.ASPCOOL.COM)。 源代码网推荐 源代码网供稿. |
