1 / 68

Building Server Controls For ASP Whidbey Part 2

2. Agenda. Part 1Tour of new core features in Whidbey for server control authoringSimpler compositionClient-script supportScript OMWeb ResourcesCallbacksControl stateAdaptationReal world sample: HtmlEditor control. Part 2Data Controls ArchitectureDataSource controlsData-bound controlsAutomatic data-binding and editingDesigner FrameworkData-aware designersInteractive designersReal world samples: BlogDataSource and BlogEntryView controls.

loren
Download Presentation

Building Server Controls For ASP Whidbey Part 2

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


    1. 1 Building Server Controls For ASP.NET “Whidbey” (Part 2) Nikhil Kothari (nikhilko@microsoft.com) Development Lead, Web Platform and Tools Team Microsoft Corporation

    2. 2 Agenda Part 1 Tour of new core features in Whidbey for server control authoring Simpler composition Client-script support Script OM Web Resources Callbacks Control state Adaptation Real world sample: HtmlEditor control Part 2 Data Controls Architecture DataSource controls Data-bound controls Automatic data-binding and editing Designer Framework Data-aware designers Interactive designers Real world samples: BlogDataSource and BlogEntryView controls

    3. 3 ASP.NET Control Framework Rich framework to enable building “smart” server controls Same model as v1, but enables much more New control types and scenarios Controls with declarative programming model Improved design-time experience for controls Extends v1 framework, while preserving existing knowledge and compatibility What’s new? Provide new services and framework features Simplify development with more functional base classes targeting common scenarios Incorporate learning and general recommended patterns

    4. 4 Blogging Controls The finished result… BlogEntryView BlogDataSource

    5. 5 BlogEntryView Design

    6. 6 Blogging Controls Markup <pdc:BlogDataSource id=“blogDS1” runat=“server” EntryPath=“BlogEntries” AdminRoleGroups=“Admin” /> <pdc:BlogEntryView id=“be1” runat=“server” DataSourceID=“blogDS1” > <EntryTemplate> <asp:Label ... Text=‘<%# Eval(“Title”) %>’ /> </EntryTemplate> <AddEntryTemplate> <asp:TextBox ... Text=‘<%# Bind(“Title”) %>’ /> </AddEntryTemplate> <EntryStyle Font-Name=“Georgia” Font-Size=“10pt” /> <AddEntryStyle BackColor=“Silver” /> </pdc:BlogEntryView>

    7. 7 BlogEntryView Functionality Offers UI to display blog entries UI can be customized via templates and styles Additionally offers UI to post new blog entries If the data source supports inserting rows Implemented as a data-bound control Entries are rendered by enumerating data from a data source Enables declarative page authoring model Both viewing and posting entries

    8. 8 BlogDataSource Functionality Provides data source consisting of blog entries Data store is a set of XML files in a folder within the Web application Provides a tabular view of data Each entry is a row with four columns: Title, Content, Category and PostDate Enables posting new entries If the user has the rights to do so Determined by user roles

    9. 9 Data Architecture Overview Goals Simplify creation of data-driven applications Declarative page authoring model for mainline scenarios Simplify authoring of data controls Preserve flexibility of v1 model Two types of data controls DataSource controls provide data Data-bound controls enumerate records and render them on the page Talk to each other using a standard interface

    10. 10 Blog Data Controls at Work

    11. 11 Mixing and Matching Data Controls

    12. 12 DataSource Controls Provide data and implement data access logic Load data on-demand Implement two API models Domain-specific Consumed by page developer SelectCommand on SqlDataSource; DataFile on XmlDataSource Generic abstraction of data Consumed by data-bound control author Essentially a collection of one or more named views of data, each represented by a DataSourceView Raise change notifications when data is modified, or query parameters are modified Non-visual controls (no rendering)

    13. 13 DataSource Control Types Tabular Implement IDataSource Typically derive from DataSourceControl Usable by controls like GridView, and BlogEntryView Hierarchical Implement IHierarchicalDataSource Typically derive from HierarchicalDataSourceControl Usable by controls like TreeView, and Menu Can be tabular or hierarchical or both Only covering tabular data source controls today

    14. 14 IDataSource and DataSourceControl public interface IDataSource { event EventHandler DataSourceChanged; DataSourceView GetView(string viewName); ICollection GetViewNames(); } public abstract class DataSourceControl : Control, IDataSource, IListSource { }

    15. 15 DataSourceView Allows enumerating a set of data records IEnumerable at a minimum; IList if possible Equivalent of a “SELECT” (required) Optionally support paging, sorting Optionally allows modifying the set of records Equivalent of “UPDATE”, “INSERT” and “DELETE” DataSourceView describes its capabilities Capabilities may be a function of property settings Or they may be fixed based on the back-end data store

    16. 16 DataSourceView public abstract class DataSourceView { protected DataSourceView(IDataSource owner, string name); public virtual bool CanDelete { get; } public virtual bool CanInsert { get; } public virtual bool CanUpdate { get; } public virtual bool CanSort { get; } ... public string Name { get; } public event Event DataSourceViewChanged; public virtual int Delete(IDictionary keys); public virtual int Insert(IDictionary values); public virtual int Update(IDictionary keys, IDictionary values); public abstract IEnumerable Select( DataSourceSelectArguments arguments); }

    17. 17 Data-bound Controls Associated with a DataSourceControl Consume one or more DataSourceViews offered by the data source Create visual rendering of data records Optionally provide UI to manipulate data (sorting, editing, …) Allow customization of UI via templates and styles Allow programmatic customization of UI via events

    18. 18 Data-bound Control Types Simple data-bound controls Enumerate data records to create child objects Derive from DataBoundControl Eg. DropDownList and ListItems Composite data-bound controls Enumerate data records to create child controls Derive from CompositeDataBoundControl Eg. GridView and table rows Hierarchical data-bound controls Enumerate and navigate hierarchy in data records to create child objects with hierarchy Derive from HierarchicalDataBoundControl Eg. TreeView create TreeNodes

    19. 19 Data-bound Control Base Classes Base class that implements the necessary plumbing DataSource, DataSourceID and DataMember properties Locate the associated DataSourceControl and retrieve its DataSourceView to allow enumerating and manipulate data Perform automatic data-binding at the right time in the page lifecycle Listen to change notifications from the DataSourceControl Manage state and recreation of control hierarchy upon post-back

    20. 20 Your Data-bound Controls Derive from the appropriate base class Implement their UI creation using data Implement rendering and handle events raised by their UI Take advantage of capabilities offered by DataSourceViews.

    21. 21 Data Control Base Classes

    22. 22 Automatic Data-binding Automatically data-bind in OnPreRender If bound to a DataSourceControl && RequiresDataBinding is true When is RequiresDataBinding set to true? OnLoad (if Page.IsPostBack is false) OnInit (if EnableViewState is false) Property changes (eg. DataSourceID) DataSource raises a change event Possible because a DataSourceControl can be located wihtin the Page, and IDataSource, DataSourceView provide the ability to load data on-demand

    23. 23 Parameter Objects Declaratively specify the value for a parameter in a query in a DataSourceControl Eg. SelectParameters property on SqlDataSourceControl Different sources of values: Control properties, request variables, etc. DataSourceControls track changes in parameter values and raise change notifications DataBoundControls use this notification to register the need to DataBind Automatically re-bind when the query parameters change DataBound controls can provide values for parameters as well Allows pushing of changed values from the data-bound UI into the data source

    24. 24 IBindableTemplate Template with binding semantics added ExtractValues() used to extract name/value pairs Data-binding expressions Bind() is special and defines a read/write data-binding Others expressions are read-only <pdc:BlogEntryView ...> <AddEntryTemplate> <asp:TextBox ... Text=‘<%# Bind(“Title”) %>’ /> <asp:TextBox ... Text=‘<%# Bind(“Content”) %>’ /> </AddEntryTemplate> </pdc:BlogEntryView> Text of controls are extracted as “Title” and “Content” values.

    25. 25 Using an IBindableTemplate Mark your template property as a bindable template TemplateContainer metadata attribute Use IBindableTemplate::ExtractValues when you need to pull updated values from UI Parser generates implementation of ExtractValues Allows data-bound control to automatically retrieve updated values without requiring page developer to add logic

    26. 26 Blogging Controls Code Walkthrough BlogEntryView BlogDataSource

    27. 27 BlogEntryView Code public class BlogEntryView : CompositeDataBoundControl { protected override int CreateChildControls(DataSourceView view, bool dataBinding) { // Enumerate data and create child controls // BlogEntryView creates a table and instances of // BlogEntryViewItems for each data record } protected bool RaiseBubbleEvent(object sender, EventArgs e) { // Handle events bubbled by child controls // BlogEntryView handles the “Add” Command event to add // a new entry } protected override void Render(HtmlTextWriter writer) { // Apply styles, etc. and then render child controls } }

    28. 28 BlogEntryView Code protected override int CreateChildControls(DataSourceView view, bool dataBinding) { bool showAddEntry = view.CanInsert; if (showAddEntry && (_addEntryTemplate != null)) { BlogEntryViewItem entryContainer = new BlogEntryViewItem(new BlogEntry()); Controls.Add(entryContainer); _addEntryTemplate.InstantiateIn(entryContainer); if (dataBinding) { entryContainer.DataBind(); } } int itemCount = 0; IEnumerable dataSource = view.Select(); foreach (object o in dataSource) { BlogEntryViewItem entryContainer = new BlogEntryViewItem(o); Controls.Add(entryContainer); _entryTemplate.InstantiateIn(entryContainer); if (dataBinding) { entryContainer.DataBind(); } itemCount++; } return itemCount; }

    29. 29 BlogEntryView Code private ITemplate _entryTemplate; private ITemplate _addEntryTemplate; [TemplateContainer(typeof(BlogEntryViewItem))] public ITemplate EntryTemplate { get { return _entryTemplate; } set { _entryTemplate = value; } } [TemplateContainer(typeof(BlogEntryViewItem), BindingDirection.TwoWay)] public ITemplate AddEntryTemplate { get { return _addEntryTemplate; } set { _addEntryTemplate = value; } }

    30. 30 BlogEntryView Code private void OnAddEntry(BlogEntryViewItem item) { IBindableTemplate bindableTemplate = _addEntryTemplate as IBindableTemplate; if (bindableTemplate != null) { DataSourceView view = GetData(); IDictionary values = bindableTemplate.ExtractValues(item); view.Insert(values); } } protected override bool OnBubbleEvent(object source, EventArgs e) { BlogEntryViewCommandEventArgs ce = e as BlogEntryViewCommandEventArgs; if (ce != null) { OnItemCommand(ce); if (ce.CommandName == "Add") { OnAddEntry(ce.Item); } return true; } return false; }

    31. 31 BlogDataSource Code public class BlogDataSource : DataSource { public BlogDataSource() { _entriesView = new BlogDataSourceView(this); } public string EntriesPath { get; set; } protected override DataSourceView GetView( string viewName) { return _entriesView; } protected override ICollection GetViewNames() { return new string[] { _entriesView.Name }; } }

    32. 32 BlogDataSourceView Code internal class BlogDataSourceView : DataSourceView { private void EnsureEntries() { BlogEntryCollection entries = new BlogEntryCollection(); foreach (string fileName in Directory.GetFiles(_path)) { string fullPath = Path.Combine(_path, fileName); using (FileStream fileStream = new FileStream(fullPath, FileMode.Open, FileAccess.Read, FileShare.Read)) { XmlSerializer serializer = new XmlSerializer(typeof(BlogEntry)); entries.Add((BlogEntry)serializer.Deserialize(fileStream)); } } entries.Sort(); _entries = entries; } public override IEnumerable Select(DataSourceSelectArguments arguments) { arguments.RaiseUnsupportedCapabilitiesError(this); if (_entries == null) { EnsureEntries(); } return new ArrayList(_entries); } }

    33. 33 BlogDataSourceView Code public override bool CanInsert { get { return (_path != null) && _owner.CanModify; } } public override int Insert(System.Collections.IDictionary values) { string title = (string)values["Title"]; string content = (string)values["Content"]; string category = (string)values["Category"]; BlogEntry newEntry = new BlogEntry(title, content, category); if (AutoSave) { SaveEntry(newEntry); } if (_entries != null) { _entries.Add(newEntry); _entries.Sort(); } OnDataSourceViewChanged(EventArgs.Empty); return 1; }

    34. 34 Designer Framework Overview Builds on top of the v1 designer framework Preserves the notion of Design-time HTML Designer class is associated to the control class via the “Designer” metadata attribute What’s new? New, more functional base classes DataBoundControlDesigner, CompositeControlDesigner, … Simplified template editing Interactive designers Regions, Events, Tasks, and Painting Slew of new services Ability to navigate project/workspace tree, database schema, toolbox items etc. Design-time state storage

    35. 35 Blogging Controls Design-time The finished design experience… BlogEntryView BlogDataSourceControl

    36. 36 Blogging Controls Design-time

    37. 37 Blogging Controls Design-time

    38. 38 BlogEntryView Design-time Functionality Provides the ability to bind the control to any tabular data source Guides the user by providing tasks Provides a realistic rendering of control on design surface Distinguishes between sample and live data Interacts with design of associated DataSourceControl to consume its schema, and sample data Enables editing of template properties Multiple views: Preview and Edit views Edit views allows in-place editing of templates

    39. 39 BlogDataSource Design-time Functionality Renders as a non-visual control Allows selecting folder containing blog entries Offers schema describing the data it offers Generates sample data used by data-bound controls to DataBind at design-time Allows page developer to choose between sample and live data

    40. 40 Data Control Designers Data source controls designers Derive from DataSourceControlDesigner Offer schema at design-time to drive designer UI Data-bindings dialog Offer design-time data for use in designer Data-bound control designers Derive from DataBoundControlDesigner Hook up with DataSourceControl and its designer Use design-time data to create rendering on design surface All of this is actually implemented by the base class!

    41. 41 Blogging Controls Design-time Data Control Designers Code Walkthrough

    42. 42 BlogDataSourceDesigner Code public class BlogDataSourceControlDesigner : DataSourceControlDesigner { public override IDataSourceSchema Schema { get { return new TypeSchema(typeof(BlogEntry)); } } public override IEnumerable GetDesignTimeData( string viewName, int minimumRows) { // Generate sample data based on the schema // and semantics of the data source } }

    43. 43 BlogEntryViewDesigner Code public class BlogEntryViewDesigner : DataBoundControlDesigner, IDynamicControlDesigner { public override DesignerActionListCollection Actions { get; } public override TemplateGroupCollection TemplateGroups { get; } public override string GetDesignTimeHtml( DesignerRegionCollection regions); public override string GetEditableDesignerRegionContent( EditableDesignerRegion region); public override void SetEditableDesignerRegionContent( EditableDesignerRegion region, string content); public override void OnClick(DesignerRegionEventArgs e); public overide void OnPaint(PaintEventArgs e); }

    44. 44 Tasks Ability to highlight core actions, properties and scenarios Properties show up as textboxes or dropdowns Properties can be design-time only properties Hyperlinks serve as quick actions, or wizard launch points Task panel is associated with a control on the design surface Recommend keeping it small and focused Not a replacement for the property grid

    45. 45 Tasks Implement a class deriving from DesignerActionList Properties on the class surface on the task panel to create editing UI Methods on the class surface on the task panel as hyperlinks Hand out an instance of this class by overriding the Actions property on your control designer

    46. 46 Blogging Controls Design-time Tasks Code Walkthrough

    47. 47 Tasks Code internal class BlogEntryViewDesignerActionList : DesignerActionList { public BlogEntryViewMode Mode { get; set; } public override DesignerActionItem[] GetItems() { return new DesignerActionItem[] { new DesignerActionItem(“Mode”, “Current Mode:”); } } } // In BlogEntryViewDesigner public override DesignerActionListCollection Actions { get { DesignerActionListCollection actions = base.Actions; DesignerActionList myActions = new BlogEntryViewDesignerActionList(this); actions.Add(myActions); return actions; } }

    48. 48 Regions Design-time HTML can be adorned with “regions” Regions are rectangles of interactivity within the bounds of the control on the design surface Selection within the control Editing within the control Generate events such as “Click” Allow you to implement a custom version of content editing When the banded templated editing model is not appropriate for your control Useful if your control is read-only with interspersed editing areas

    49. 49 Regions BlogEntryViewDesigner design-time HTML <table> <tr> <td _designerRegion=“0”>Normal View</td> <td _designerRegion=“1”>Admin View</td> </tr> <tr> <td colspan=“2” _designerRegion=“3”>...</td> </tr> </table>

    50. 50 Designer Events Control designers can handle user actions such as Clicks on the control Override OnClick method on ControlDesigner If the click is within the bounds of a region, that is handed in via the EventArgs

    51. 51 Blogging Controls Design-time Regions and Events Code Walkthrough

    52. 52 Regions Code protected override string GetDesignTimeHtml(DesignerRegionCollection regions) { DesignerRegion normalModeRegion = new DesignerRegion(this, “Normal”); DesignerRegion adminModeRegion = new DesignerRegion(this, “Admin”); regions.Add(normalModeRegion); regions.Add(adminModeRegion); string designTimeHtml; // Build design-time HTML containing tags // with the “__designerRegion” attribute whose // value is set to the index of the region in the // regions collection return designTimeHtml; }

    53. 53 Designer Events Code protected override void OnClick(RegionEventArgs e) { if (e.Region == null) { return; } if (e.Region.Name == “Normal”) { // switch to normal mode; } else if (e.Region.Name == “Admin”) { // switch to admin mode } UpdateView(); }

    54. 54 Painting on Design Surface Control designers can paint on the design surface Controls are handed a PaintEventArgs object which contains the bounds of the rectangle, and the Graphics object Use GDI+ to draw on top of the rendered design-time HTML Register to participate in the rendering process by choosing to custom paint in your control designer’s Initialize method

    55. 55 Blogging Controls Design-time Painting Code Walkthrough

    56. 56 Design-time Painting Code protected override void OnPaint(PaintEventArgs e) { bool sampleData = false; // logic to compute sampleData if (sampleData) { Graphics g = e.Graphics; // Logic to compute widths, heights etc. using (Font font = new Font("Tahoma", 60, FontStyle.Bold)) { SizeF textSize = g.MeasureString(“Sample”, font); g.DrawString(“Sample”, font, Brushes.Silver, -textSize.Width / 2, -textSize.Height / 2); } } } public override void Initialize(IComponent component) { // Initialization logic // Turn on custom painting SetViewFlags(ViewFlags.CustomPaint, true); }

    57. 57 Key Takeaways Think big! Server controls define the Web development experience “Whidbey” server controls are more powerful and functional Enable core scenarios in a declarative manner Framework enables authoring rich server controls New scenarios and opportunities Consistent data-bound and data source controls Compelling design-time experience Build on top of v1 server control and designer architecture

    58. 58 Related Talks WSV401 – Building Server Controls for ASP.NET “Whidbey” (Part 1) WSV200 – ASP.NET: Overview of ASP.NET “Whidbey” WSV310 and WSV311 – ASP.NET: Programming with the Data Controls in ASP.NET “Whidbey” (Part 1 and 2)

    59. 59 Download Slides/Demos Blog http://www.nikhilk.net (With ongoing updates to samples) ASP.NET Web site http://www.asp.net/whidbey

    60. 60 Questions and answers…

    61. 61 Abstract Learn about advanced topics in the server control architecture in ASP.NET “Whidbey” and how you can use them to build data-bound and data source components. In addition, learn how to use the new designer framework capabilities to enable a rich, interactive, RAD design-time experience for your controls. This talk will feature the BlogEntryView and BlogDataSource server controls that demonstrate writing Data controls, automatic data-binding and data editing, design time schema, tasks and in-place editing.

    62. 62

    63. 63 Bonus Material Simplified Template Editing Using infrastructure services

    64. 64 Template Editing Control designer simply defines its templates, their names and their visual style characteristics The v1 semantics of Template groups containing one or more templates goes forward Control designer offers a collection of TemplateGroups Each TemplateGroup contains one or more TemplateDefinitions The design surface does the rest!

    65. 65 Blogging Controls Design-time Template Editing Code Walkthrough

    66. 66 Template Editing Code private TemplateGroup _singleEntryTemplateGroup; public override TemplateGroupCollection TemplateGroups { get { TemplateGroupCollection groups = base.TemplateGroups; if (_singleEntryTemplateGroup == null) { // Show creating a template group } groups.Add(_singleEntryTemplateGroup); return groups; } }

    67. 67 Infrastructure Services ASP.NET provides several infrastructure services Membership and Roles SiteCounters Profile and Personalization Image generation … Infrastructure services are implemented as providers implementing a standard interface Custom provider implementation can be swapped in Controls can talk to the registered provider Eg. Login control talks to the Membership provider Same Control UI and object model automatically work against any provider selected by the app developer

    68. 68 Using the Roles Service Add AddEntryRoles property on BlogDataSource public string[] AdminRoleGroups { get; set; } At runtime, check if the user is in the list of specified roles to automatically enable Inserting capability in the DataSourceView bool canModify = false; if (Page.Request.IsAuthenticated) { foreach (string role in roles.Split(‘,’)) { if (Roles.IsUserInRole(userName, role)) { canModify = true; break; } } }

More Related