Talking about new features, useful things, frustrations in .NET and so on...
14-08-2007
ASP..NET Web Parts
Web Parts are very useful to enable end users to modify the look and feel of your website : the content, appearance and even the behaviour can be changed, this is possible without writing any code.
First drag a WebPartManager control to the web page. This control must appear before any other Web Part control, otherwise a runtime exception will be thrown (and that's not exactly what we want...) Next add WebPartZone controls to the places where you want [an end user] to see Web Parts; you can do this inside a table to get a basic layout. The title can be changed in the HeaderText property. You can now start adding (in the design view) some web user controls to the WebPartZone controls by dragging and dropping.
A quick preview in a browser shows us the controls have a title "Untitled", this can easily be changed by adding title="" in the source code (the intellisense won't recognize it, don't worry about that) :
Now, all the above is quite useful, but to let the user interact with our web parts, a few things are still missing. Add an EditorZone and a CatalogZone the same way as the WebPartZone's above. Make sure not to add them to an existing WebPartZone as this will generate a runtime exception. In the EditorZone you can add an AppearanceEditorPart, LayoutEditorPart and BehaviorEditorPart, depending on what you want the end user to do. In the CatalogZone you can add a DeclarativeCatalogPart (when you want to add another instance of a predefined user control), a PageCatalogPart (to retain an existing control when you closed it) and an ImportCatalogPart (to import a non-defined user control).
When taking a quick look in the browser (after building...), you see none of the above appears... This is because the current view is set to the default view : Browse. Now let's add a control displaying the different modes, the first code that has to be written (except HTML...) ! (I chose a radiobuttonlist called rbListModes)
Make sure to set the AutoPostBack property of the control to "true" and start the application. When switching between the different display modes, you will be able to change properties and add/remove controls. To edit a control, switch to the Edit mode and click on in the right upper corner of the control and choose "Edit". The Editor parts added to the EditorZone will now become visible. To retain a closed control, switch to Catalog mode and navigate to Page Catalog, you will be able to display the control in the WebPartZone of your choice.
To display a slideshow in a webpage, you can navigate from image to image by using a pre-defined list of images. This requires a lot of work when adding another slideshow or changing the images in the slideshow. An easy solution is renaming your pictures (with a batch rename tool) so they are all in the same format containing a counter, e.g. picture_001.jpg picture_002.jpg ... Afterwards you simply overload the onLoadEvent (in each page you're using the slideshow in) : (see also http://simonwillison.net/2004/May/26/addLoadEvent/ )
<script type="text/javascript"> function addLoadEvent(func) { var oldonload = window.onload; if (typeof window.onload != 'function') { window.onload = func; } else { window.onload = function() { if (oldonload) { oldonload(); } func(); } } }
addLoadEvent(function() { FillArray(amount of pictures in array); SetFolder('foldercontainingthepictures'); }) </script>
The code for the slideshow can be stored in a seperate javascript file and imported using the following html-code (assuming the script to be called slideshow.js and stored in a folder called scripts) :
In the following example of "slideshow.js", next and previous are called on thumbnails, after hovering over or clicking on the thumbnail, the image is displayed by using the ShowPicture method. An example of the resulting HTML document can be found below.
var thumbnails=new Array();
var pictureCount; // amount of pictures to be displayed in the slideshow var folderName; // folder containing the pictures
function FillArray(pictCount) { pictureCount = pictCount; for (var ind = 0; ind < pictureCount; ind++) { //fill the array var ind_2 = ind + 1; if (ind_2 < 10) { thumbnails[ind] = "00" + ind_2 + ".jpg"; } else if (ind_2 < 100) { thumbnails[ind] = "0" + ind_2 + ".jpg"; } else { thumbnails[ind] = ind_2 + ".jpg"; } } } function SetFolder(folder) { folderName = folder; }
Note : you can easily define the prefix of the images (so the "picture_"-part) dynamically as well, but I only added this to make the example easier to read. Most of the times I used slideshows I simply renamed the pictures to the most basic format : 001.jpg, 002.jpg etc.
Error handling is one of the most important (and maybe least enjoying) things to do while developing.
Most of the times error-prone methods will contain try/catch blocks to prevent the exception from slipping through. There might still be some unhandled exceptions though, in code blocks not "protected" by a try/catch block. Those can be handled on page or on application level.
Now let's see an example, writing the error to the trace (so it can be viewed and further investigated by a developer using a trace listener) in case of page level error handling and navigating to a user defined error page in case of application level exception handling.
On page
level :
protectedvoid
Page_Error(object sender, EventArgs e) { // Retrieve the last error and write to the trace Trace.Write(Server.GetLastError()); // Clear the last error Server.ClearError(); }
On
application level :
void
Application_Error(object sender, EventArgs e) { // Navigate to a user defined error page Server.Transfer("HandleError.aspx"); // Make sure to call Server.GetLastError() and Server.ClearError() in the error handling page }
There are different ways to navigate to a different URL, including : Response.Redirect(url); Server.Transfer(url,
false);
What's the difference? With
Response.Redirect you will not be able to access data from the original page
through the PreviousPage property, by using Server.Transfer (or the PostBackUrl
property) you will be able to do so.
Ever wanted to return a comma seperated list of values with a query, struggling with functions or cursors ? In SQL 2005, there's an easy/short solution for this.
e.g. to return the name of a company and a comma separated list of e-mail addresses of the users in the company.
SELECT c.company_name, mail = STUFF ( ( SELECT , + u.mail_address as [text()] FROM t_User u INNER JOIN t_Company co ON u.company_id = co.company_id WHERE co.company_id = c.company_id FOR XML Path () ), 1, 2, ) FROM t_Company c
The STUFF() function removes - in this example - the first 2 characters in the list, to avoid starting the list with a comma followed by a space. Text() maps the list to a text node. For a description of "FOR XML Path", I refer to the MSDN documentation : http://msdn2.microsoft.com/en-us/library/ms345137.aspx
Some people keep asking me when I start blogging again. Yes again, since our first "blogging project" (used to be known as webbullogs) didn't last very long.
The purpose of this blog is to explain a bit what I'm busy with (mostly .NET related) - which will also allow me to remember some things a little longer ;-) - and some other useful (and at times extremely useless) stuff.
Hopefully you will enjoy reading it ... and maybe even learn something from it !