| Acknowledgments | xiii |
| Introduction | xvii |
| PART I DATA ACCESS AND REPORTING | |
| 1 Data Bound .NET Controls | 3 |
| ASP.NET Data Binding | 3 |
| Feasible Data-Binding Sources | 4 |
| Simple Data Binding | 5 |
| Complex Data Binding | 6 |
| The DropDownList Web Control | 7 |
| The CheckBoxList Web Control | 9 |
| The RadioButtonList Web Control | 11 |
| The ListBox Web Control | 12 |
| The Repeater Control | 14 |
| Accessing Data Bound Information | 14 |
| Repeater Control Events | 16 |
| The DataList Control | 19 |
| Templates Specific to DataList | 20 |
| Events Specific to DataList | 21 |
| Relating Graphical and Data Elements | 23 |
| The DataGrid Control | 26 |
| 2 Pageable Data Grids | 29 |
| Constituent Items of DataGrid | 29 |
| Column Types | 31 |
| Binding Columns | 32 |
| Bound Columns | 33 |
| Button Columns | 34 |
| Link Columns | 37 |
| Programmatic Binding | 40 |
| Data Pagination | 43 |
| Semi-Automatic Pagination | 43 |
| Properties for Pagination | 45 |
| The Pager Bar | 45 |
| Pagination in Action | 47 |
| Customizing the Pager Bar | 48 |
| Custom Pagination | 54 |
| Sorting Columns | 59 |
| Setting Up Sorting | 60 |
| Auto-Reverse Sorting | 61 |
| Sorting Multiple Fields | 64 |
| Auto-Reverse Sorting for Multiple Columns | 64 |
| Showing Sorting Information | 66 |
| DataGrid Controls and Data Persistence | 68 |
| Scalability? What Was That? | 69 |
| Using the Session Object | 69 |
| Using the Cache Object | 70 |
| Using XML Files | 71 |
| Using Data Readers and Adapters | 72 |
| The Paradox of Pagination | 73 |
| 3 Templated DataGrid Controls | 75 |
| Binding Templated Columns | 75 |
| Templated Columns in Action | 78 |
| Concatenating Data Fields | 79 |
| Sorting Templated Columns | 80 |
| Grouping Columns Under a Single Header | 81 |
| Adjusting Column Margins | 83 |
| Customizing Column Headers | 85 |
| Creating Templates Dynamically | 88 |
| Loading Templates from Files | 88 |
| Managing Multiple Views for a Column | 89 |
| Loading Templates from Strings | 93 |
| Implementing ITemplate | 94 |
| Adapting Columns to Data | 97 |
| Showing Boolean Values | 97 |
| Showing Images | 99 |
| Showing Arrays | 100 |
| 4 Editing DataGrid Controls | 105 |
| The In-Place Editing Feature | 106 |
| Enabling In-Place Editing | 106 |
| Reading Text from Edited Fields | 111 |
| Updating the Data Source | 113 |
| A Long List of Drawbacks | 116 |
| Editing In Place Using Templates | 117 |
| Working with Template Controls | 118 |
| Adapting Layouts to Data | 120 |
| Adding New Rows | 126 |
| Setting Up the Add-Row Feature | 126 |
| Adding Blank Rows | 128 |
| Switching to Edit Mode | 129 |
| Updating the Table and the Grid | 130 |
| PART II SMART AND EFFECTIVE DATA ACCESS AND REPORTING | |
| 5 Code Reusability in ASP.NET | 139 |
| Layers of ASP.NET Pages | 139 |
| From Spaghetti Code to Lasagna Code | 140 |
| Slimmer Pages | 141 |
| The Code-Behind Approach | 141 |
| Enabling Code-Behind | 142 |
| Writing Code-Behind Pages | 142 |
| Visual Inheritance for ASP.NET Pages | 145 |
| Embeddable Web Forms | 147 |
| Writing User Controls | 147 |
| Creating a New DateBox Control | 153 |
| Firing Events | 157 |
| Writing Custom Controls | 162 |
| A Labeled TextBox Control | 162 |
| Using Custom Controls | 165 |
| An Off-the-Shelf DataGrid Control | 167 |
| The UpdateView Event | 170 |
| The SortExpression Property | 171 |
| 6 Advanced Data Reporting | 175 |
| Item Selection | 175 |
| Enabling Item Selection | 176 |
| Using the SelectedIndexChanged Event | 179 |
| Selecting Rows Programmatically | 181 |
| Selection and Drill-Down | 183 |
| Filtered Views | 185 |
| Allowing the Selection of Multiple Items | 186 |
| Properties of the SuperGrid Control | 187 |
| Layout of the SuperGrid Control | 188 |
| Retrieving the Selected Items | 193 |
| Selecting by Condition | 195 |
| Changing the Background Color | 196 |
| Evaluating the Condition | 197 |
| Adding an Extra Column | 198 |
| Aggregates and Summary Rows | 201 |
| The Right Way to Query | 202 |
| Creating Relations Between Tables | 202 |
| 7 Disconnected Web Applications | 211 |
| What Is the DataSet Object Really For? | 212 |
| Implications for Web Applications | 212 |
| DataSet and the DataGrid Control | 213 |
| Towards Disconnected Applications | 214 |
| Transparent Data Sources | 215 |
| Working with the Cache Object | 216 |
| Loading Data from a Generic Source | 216 |
| Creating Subtables | 217 |
| Batch Updates | 219 |
| Locking Rows | 220 |
| Applying In-Memory Changes | 221 |
| Auto-Increment Fields | 224 |
| Delete and Remove | 226 |
| States of a Row | 228 |
| An Offline Buffer for Data | 229 |
| Loading a DataSet from XML | 229 |
| The DiffGram Format | 230 |
| Submitting Changes | 233 |
| Detecting Changes | 233 |
| Rejecting Changes | 235 |
| Viewing Changes | 235 |
| Generating Commands | 239 |
| Command Builders | 242 |
| Data Conflicts | 246 |
| PART III INTEROPERABILITY | |
| 8 Interoperable Web Applications | 255 |
| The COM Interop Services | 256 |
| Using ADO in .NET Applications | 257 |
| The ADODB Assembly | 258 |
| Getting a Recordset | 259 |
| ADO Server Cursors | 261 |
| Migration Issues | 262 |
| Adapting Recordset Objects to DataSet Objects | 262 |
| Loading a Recordset Object into a DataSet Object | 263 |
| Loading a Recordset Object into a DataTable Object | 264 |
| A Common Migration Scenario | 265 |
| From DataSet Objects to ADO Recordset Objects | 269 |
| Serializing DataSet Objects to XML Recordset Objects | 269 |
| XML Schemas for DataSet Objects | 270 |
| The ADO XML Schema | 271 |
| Creating an ADO XML Schema | 272 |
| From .NET Data to XML | 276 |
| XML Object Serialization | 278 |
| Enabling Object Serialization | 278 |
| Serializing to XML | 281 |
| 9 Web Services | 285 |
| Dynamic Link Web Libraries | 286 |
| Web Service Specifications | 286 |
| Underlying Technologies | 287 |
| .NET Web Services | 288 |
| The WebService Attribute | 288 |
| Changing the Default Namespace | 289 |
| Defining Web Methods | 290 |
| Under the Hood of .NET Web Services | 293 |
| Invoking .NET Web Services | 296 |
| Creating Proxy Classes | 300 |
| Web Service Implementation | 304 |
| Contract Design | 304 |
| Minimizing Round-Trips | 305 |
| Authentication and Authorization | 306 |
| Managing State | 308 |
| Publishing and Deploying Web Services | 308 |
| Web Service Optimization | 309 |
| Asynchronous Calls | 310 |
| SOAP Extensions | 312 |
| Extreme Optimization | 314 |
| 10 Exposing Data to .NET Applications | 317 |
| Exposing Proprietary Data | 318 |
| Using Tailor-Made Classes | 319 |
| The DirectoryListing Class | 320 |
| Creating In-Memory Tables | 324 |
| Using the DirectoryListing Class | 330 |
| Using OLE DB Providers | 333 |
| Inside .NET Data Providers | 335 |
| The Architecture of .NET Data Providers | 336 |
| Implementing a Connection | 338 |
| Implementing a Command | 340 |
| Implementing a Data Reader | 341 |
| Implementing a Data Adapter | 342 |
| Simple vs. Complex Data Providers | 343 |
| Writing a Simple Data Provider | 344 |
| The Table Mapping Mechanism | 345 |
| Filling the DataSet Object | 346 |
| Using the Simple Data Provider | 347 |
| Updating the Data Source | 348 |
| AFTERWORD Some Final Thoughts on the Future of ADO.NET | 355 |
| INDEX | 359 |