1. Trang chủ
  2. » Công Nghệ Thông Tin

Professional ASP.NET 3.5 in C# and Visual Basic Part 131 doc

10 150 0

Đang tải... (xem toàn văn)

THÔNG TIN TÀI LIỆU

Nội dung

Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1261 Chapter 26: User and Server Controls If (_currentView = 1) Then template = View2 End If Dim p As New Panel() Controls.Add(p) If (Not template Is Nothing) Then template.InstantiateIn(p) End If End Sub End Class C# [Designer(typeof(MultiRegionControlDesigner))] [ToolboxData("<{0}:MultiRegionControl runat= \ "server \ " width= \ "100% \ " > "+ "</{0}:MultiRegionControl > ")] public class MultiRegionControl : CompositeControl { // Define the templates that represent 2 views on the control private ITemplate _view1; private ITemplate _view2; // These properties are inner properties [PersistenceMode(PersistenceMode.InnerProperty), DefaultValue(null)] public virtual ITemplate View1 { get { return _view1;} set { _view1 = value;} } [PersistenceMode(PersistenceMode.InnerProperty), DefaultValue(null)] public virtual ITemplate View2 { get { return _view2;} set { _view2 = value;} } // The current view on the control; 0= view1, 1=view2, 2=all views private int _currentView = 0; public int CurrentView { get { return _currentView;} set { _currentView = value;} } protected override void CreateChildControls() { Controls.Clear(); ITemplate template = View1; if (_currentView == 1) template = View2; Panel p = new Panel(); Controls.Add(p); 1261 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1262 Chapter 26: User and Server Controls if (template != null) template.InstantiateIn(p); } } The container control creates two ITemplate objects, which serve as the controls to display. The ITemplate objects are the control containers for this server control, allowing you to drop other server controls or text into this control. The control also uses the Designer attribute to indicate to Visual Studio that it should use the MultiRegionControlDesigner class when displaying this control on the designer surface. Now you create the control designer that defines the regions for the control. Listing 26-43 shows the designer class. Listing 26-43: A custom designer class used to define designer regions VB Public Class MultiRegionControlDesigner Inherits System.Web.UI.Design.WebControls.CompositeControlDesigner Protected _currentView As Int32 = 0 Private myControl As MultiRegionControl Public Overrides Sub Initialize(ByVal component As IComponent) MyBase.Initialize(component) myControl = CType(component, MultiRegionControl) End Sub Public Overrides ReadOnly Property AllowResize() As Boolean Get Return True End Get End Property Protected Overrides Sub OnClick(ByVal e As DesignerRegionMouseEventArgs) If (e.Region Is Nothing) Then Return End If If ((e.Region.Name = "Header0") And (Not _currentView = 0)) Then _currentView = 0 UpdateDesignTimeHtml() End If If ((e.Region.Name = "Header1") And (Not _currentView = 1)) Then _currentView = 1 UpdateDesignTimeHtml() End If End Sub Public Overrides Function GetDesignTimeHtml( _ ByVal regions As DesignerRegionCollection) As String 1262 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1263 Chapter 26: User and Server Controls BuildRegions(regions) Return BuildDesignTimeHtml() End Function Protected Overridable Sub BuildRegions( _ ByVal regions As DesignerRegionCollection) regions.Add(New DesignerRegion(Me, "Header0")) regions.Add(New DesignerRegion(Me, "Header1")) ’ If the current view is for all, we need another editable region Dim edr0 As New EditableDesignerRegion(Me, "Content" & _currentView, False) edr0.Description = "Add stuff in here if you dare:" regions.Add(edr0) ’ Set the highlight, depending upon the selected region If ((_currentView = 0) Or (_currentView = 1)) Then regions(_currentView).Highlight = True End If End Sub Protected Overridable Function BuildDesignTimeHtml() As String Dim sb As New StringBuilder() sb.Append(BuildBeginDesignTimeHtml()) sb.Append(BuildContentDesignTimeHtml()) sb.Append(BuildEndDesignTimeHtml()) Return sb.ToString() End Function Protected Overridable Function BuildBeginDesignTimeHtml() As String ’ Create the table layout Dim sb As New StringBuilder() sb.Append("<table ") ’ Styles that we’ll use to render for the design-surface sb.Append("height="’ & myControl.Height.ToString() & "’ width=’" & _ myControl.Width.ToString() & "’ > ") ’ Generate the title or caption bar sb.Append("<tr height=’25px’ align=’center’ " & _ "style=’font-family:tahoma;font-size:10pt;font-weight:bold;’ > "&_ "<td style=’width:50%’ " & _ DesignerRegion.DesignerRegionAttributeName & "=’0’ > ") sb.Append("Page-View 1</td > ") sb.Append("<td style=’width:50%’ " & _ DesignerRegion.DesignerRegionAttributeName & "=’1’ > ") sb.Append("Page-View 2</td > </tr > ") Return sb.ToString() End Function Protected Overridable Function BuildEndDesignTimeHtml() As String 1263 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1264 Chapter 26: User and Server Controls Return ("</table > ") End Function Protected Overridable Function BuildContentDesignTimeHtml() As String Dim sb As New StringBuilder() sb.Append("<td colspan=’2’ style="’) sb.Append("background-color:" & _ myControl.BackColor.Name.ToString() & ";’ ") sb.Append(DesignerRegion.DesignerRegionAttributeName & "=’2’ > ") Return sb.ToString() End Function Public Overrides Function GetEditableDesignerRegionContent( _ ByVal region As EditableDesignerRegion) As String Dim host As IDesignerHost = _ CType(Component.Site.GetService(GetType(IDesignerHost)), IDesignerHost) If (Not host Is Nothing) Then Dim template As ITemplate = myControl.View1 If (region.Name = "Content1") Then template = myControl.View2 End If If (Not template Is Nothing) Then Return ControlPersister.PersistTemplate(template, host) End If End If Return String.Empty End Function Public Overrides Sub SetEditableDesignerRegionContent( _ ByVal region As EditableDesignerRegion, ByVal content As String) Dim regionIndex As Int32 = Int32.Parse(region.Name.Substring(7)) If (content Is Nothing) Then If (regionIndex = 0) Then myControl.View1 = Nothing ElseIf (regionIndex = 1) Then myControl.View2 = Nothing Return End If Dim host As IDesignerHost = _ CType(Component.Site.GetService(GetType(IDesignerHost)), IDesignerHost) If (Not host Is Nothing) Then 1264 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1265 Chapter 26: User and Server Controls Dim template = ControlParser.ParseTemplate(host, content) If (Not template Is Nothing) Then If (regionIndex = 0) Then myControl.View1 = template ElseIf (regionIndex = 1) Then myControl.View2 = template End If End If End If End If End Sub End Class C# public class MultiRegionControlDesigner : System.Web.UI.Design.WebControls.CompositeControlDesigner { protected int _currentView = 0; private MultiRegionControl myControl; public override void Initialize(IComponent component) { base.Initialize(component); myControl = (MultiRegionControl)component; } public override bool AllowResize { get { return true;}} protected override void OnClick(DesignerRegionMouseEventArgs e) { if (e.Region == null) return; if (e.Region.Name == "Header0" && _currentView != 0) { _currentView = 0; UpdateDesignTimeHtml(); } if (e.Region.Name == "Header1" && _currentView != 1) { _currentView = 1; UpdateDesignTimeHtml(); } } public override String GetDesignTimeHtml(DesignerRegionCollection regions) { BuildRegions(regions); return BuildDesignTimeHtml(); } protected virtual void BuildRegions(DesignerRegionCollection regions) { regions.Add(new DesignerRegion(this, "Header0")); regions.Add(new DesignerRegion(this, "Header1")); 1265 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1266 Chapter 26: User and Server Controls // If the current view is for all, we need another editable region EditableDesignerRegion edr0 = new EditableDesignerRegion(this, "Content" + _currentView, false); edr0.Description = "Add stuff in here if you dare:"; regions.Add(edr0); // Set the highlight, depending upon the selected region if (_currentView ==0 || _currentView==1) regions[_currentView].Highlight = true; } protected virtual string BuildDesignTimeHtml() { StringBuilder sb = new StringBuilder(); sb.Append(BuildBeginDesignTimeHtml()); sb.Append(BuildContentDesignTimeHtml()); sb.Append(BuildEndDesignTimeHtml()); return sb.ToString(); } protected virtual String BuildBeginDesignTimeHtml() { // Create the table layout StringBuilder sb = new StringBuilder(); sb.Append("<table "); // Styles that we’ll use to render for the design-surface sb.Append("height="’ + myControl.Height.ToString() + "’ width=’" + myControl.Width.ToString() + "’ > "); // Generate the title or caption bar sb.Append("<tr height=’25px’ align=’center’ " + "style=’font-family:tahoma;font-size:10pt;font-weight:bold;’ > "+ "<td style=’width:50%’ " + DesignerRegion.DesignerRegionAttributeName + "=’0’ > "); sb.Append("Page-View 1</td > "); sb.Append("<td style=’width:50%’ " + DesignerRegion.DesignerRegionAttributeName + "=’1’ > "); sb.Append("Page-View 2</td > </tr > "); return sb.ToString(); } protected virtual String BuildEndDesignTimeHtml() { return ("</table > "); } protected virtual String BuildContentDesignTimeHtml() { StringBuilder sb = new StringBuilder(); sb.Append("<td colspan=’2’ style=’"); sb.Append("background-color:" + myControl.BackColor.Name.ToString() + ";’ "); 1266 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1267 Chapter 26: User and Server Controls sb.Append(DesignerRegion.DesignerRegionAttributeName + "=’2’ > "); return sb.ToString(); } public override string GetEditableDesignerRegionContent (EditableDesignerRegion region) { IDesignerHost host = (IDesignerHost)Component.Site.GetService(typeof(IDesignerHost)); if (host != null) { ITemplate template = myControl.View1; if (region.Name == "Content1") template = myControl.View2; if (template != null) return ControlPersister.PersistTemplate(template, host); } return String.Empty; } public override void SetEditableDesignerRegionContent (EditableDesignerRegion region, string content) { int regionIndex = Int32.Parse(region.Name.Substring(7)); if (content == null) { if (regionIndex == 0) myControl.View1 = null; else if (regionIndex == 1) myControl.View2 = null; return; } IDesignerHost host = (IDesignerHost)Component.Site.GetService(typeof(IDesignerHost)); if (host != null) { ITemplate template = ControlParser.ParseTemplate(host, content); if (template != null) { if (regionIndex == 0) myControl.View1 = template; else if (regionIndex == 1) myControl.View2 = template; } } } } 1267 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1268 Chapter 26: User and Server Controls The designer overrides the GetDesignTimeHtml method, calling the BuildRegions and Build- DesignTimeHtml methods to alter the HTML that the control renders to the Visual Studio design surface. The BuildRegions method creates three design regions in the control, two header regions and an editable content region. The regions are added to the DesignerRegionCollection .The BuildDesignTimeHtml method calls three methods to generate the actual HTML that will be generated by the control at design time. The designer class also contains two overridden methods for getting and setting the editable designer region content: GetEditableDesignerRegionContent and SetEditableDesignerRegionContent . These methods get or set the appropriate content HTML, based on the designer region template that is currently active. Finally, the class contains an OnClick method that it uses to respond to click events fired by the control at design time. This control uses the OnClick event to switch the current region being displayed by the control at design time. When you add the control to a Web form, you see that you can toggle between the two editable regions, and each region maintains its own content. Figure 26-17 shows what the control looks like on the Visual Studio design surface. Figure 26-17 1268 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1269 Chapter 26: User and Server Controls As you can see in Figure 26-17, the control contains three separate design regions. When you click design regions 1 or 2, the OnClick method in the designer fires and redraws the control on the design surface, changing the template area located in design region 3. Designer Actions Another great feature of ASP.NET design-time support is control smart tags. Smart tags give developers using a control quick access to common control properties. Smart tags are actually a new and improved implementation of the Designer Verbs functionality that was available in ASP.NET 1.0. To add menu items to a server control’s smart tag, you create a new class that inherits from the DesignerActionList class. The DesignerActionList contains the list of designer action items that are displayed by a server control. Classes that derive from the DesignerActionList class can over- ride the GetSortedActionItems method, creating their own DesignerActionItemsCollection object to which designer action items can be added. You can add several different types of DesignerActionItems types to the collection: ❑ DesignerActionTextItem ❑ DesignerActionHeaderItem ❑ DesignerActionMethodItem ❑ DesignerActionPropertyItem Listing 26-44 shows a control designer class that contains a private class deriving from DesignerActionList . Listing 26-44: Adding designer actions to a control designer VB Imports System.Web.UI.Design Imports System.ComponentModel.Design Public Class TestControlDesigner Inherits ControlDesigner Public Overrides ReadOnly Property ActionLists() _ As DesignerActionListCollection Get Dim lists As New DesignerActionListCollection() lists.AddRange(MyBase.ActionLists) lists.Add(New TestControlList(Me)) Return lists End Get End Property Private NotInheritable Class TestControlList Inherits DesignerActionList Public Sub New(ByVal c As TestControlDesigner) MyBase.New(c.Component) End Sub 1269 Evjen c26.tex V2 - 01/28/2008 3:48pm Page 1270 Chapter 26: User and Server Controls Public Overrides Function GetSortedActionItems() _ As DesignerActionItemCollection Dim c As New DesignerActionItemCollection() c.Add(New DesignerActionTextItem("FOO", "FOO")) Return c End Function End Class End Class C# using Syste; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.Design; using System.Linq; using System.Text; using System.Web; using System.Web.UI; using System.Web.WebControls; using System.Web.UI.Design; public class TestControlDesigner : ControlDesigner { public override DesignerActionListCollection ActionLists { get { DesignerActionListCollection actionLists = new DesignerActionListCollection(); actionLists.AddRange(base.ActionLists); actionLists.Add(new TestControlList(this)); return actionLists; } } private sealed class TestControlList : DesignerActionList { public TestControlList(TestControlDesigner c) : base(c.Component) { } public override DesignerActionItemCollection GetSortedActionItems() { DesignerActionItemCollection c = new DesignerActionItemCollection(); c.Add(new DesignerActionTextItem("FOO", "FOO")); return c; } } } The control designer class overrides the ActionsLists property. The property creates an instance of the TextControlList class, which derives from DesignerActionList and overrides the GetSortedActionItems method. The method creates a new DesignerActionListCollection ,anda 1270 . Class End Class C# using Syste; using System.Collections.Generic; using System.ComponentModel; using System.ComponentModel.Design; using System.Linq; using System.Text; using System.Web; using System.Web.UI; using. host); } return String.Empty; } public override void SetEditableDesignerRegionContent (EditableDesignerRegion region, string content) { int regionIndex = Int32.Parse(region.Name.Substring(7)); if (content. If Return String.Empty End Function Public Overrides Sub SetEditableDesignerRegionContent( _ ByVal region As EditableDesignerRegion, ByVal content As String) Dim regionIndex As Int32 = Int32.Parse(region.Name.Substring(7)) If

Ngày đăng: 05/07/2014, 19:20