CodeBetter.Com
CodeBetter.Com
RSS 2.0 via Feedburner
           Do you Twitter? Follow us @CodeBetter

Peter's Gekko

public Blog MyNotepad : Imho { }

July 2005 - Posts

  • ASP.net applications : a rich user experince for mort-al users

    I was struck by a post Make it as rich as possible by simplegeek Chris'An where he complains about the limitations of "normal" web apps and raves about the possibilities AJAX will bring to browser apps. When talking about morts Rocky Lhotka mentions VB6 as their development environment of choice to build rich Windows applications. Both very good stories but I want to be the devils advocate and talk a little about some experiences I had with one of my clients. Over the years I had been building Delphi Win32 apps for them with all bells and whistles. For a new project, which would involve very frequent roll-outs (it took an administrator to install a Windows app on XP), we decided to go for an asp.net intranet app. Which was a great success. Also when it came to user experience.

    Some lessons learned:

    Most users are plain Mort-als

    • Have to work with a small screen, close to the window, a crappy mouse and a rattling keyboard.
    • Floating toolbars will drift away and get lost. It takes a call to support to recover them.
    • The screen should list plain information. No frills, no more. Coming back from lunch the screen's content should be just the same.
    • Printout's are filed , they have to look good.
    • A user with some geek-iness will want to do his work in Excel anyhow

    In contrast most blog-reading developers like you and me (a minority as Rocky explains) are utter geeks:

    That's quite a contrast.

    As a practical tip are some of my experiences in building asp.net applications which satisfy my mortal users

    • Use a common stylesheet for every page. To adjust the pages to available screen real-estate the sa updates the sheet. The VS2005 support for themes, skins and the like is great, VS 2003 needs some fiddling.
    • Use flow layout (default in VS2005)
    • Give your controls a relative size. A grid with a width of 100% will fully utilize every screen size. In case the user has a large screen she can increase the browser text size. In case she has a small screen the columns in the table will wrap
    • Make extensive use of hyperlinks. Drill-down by clicking the link. Don't cram everything on one page
    • Use a reporting tool which is friendly to the sa. Crystal is not. Reporting Services is.
    • Most reporting tools have a lot of export capabilities in the box. Make sure these are just a click away.

    Don't get me wrong, I personally love rich and interesting UI's. To satisfy my needs i have my Tablet PC to play with. But to pay my mort-gage, kids and car I do depend on plain asp.net.

  • Web reporting tools: get rid of Crystal and get yourself a life

    Having used both Crystal Reports (CR) and SQL Reporting Services (RS) for a web-app I'm fully convinced. I've had enough of CR for once and for all. Oh yes, I have build great reports with CR but it was a bumpy road. Getting it all to work was favorite blog fodder, the many responses tell I'm not the only one with frustrations. What surprises me is that many people think RS is an overkill. This is not the case, let me sum up some of my pleasant RS experiences. You think for yourself how CR compares on these points

    • An RS license is part of a MS sql server license. So when you have a sql server it is free
    • Initial setup of  RS is no big deal. No registry settings, no folder settings. After that anybody (with the right privileges) can upload reports with a browser.
    • RS works very intuitive with data, a report works on one SQL query, a subreport is a new report with a new SQL query
    • RS uses plain VBscript for expressions
    • An RS report can load .net assemblies

    The learning curve for RS is not steep, as it builds on your existing knowledge. I don't want to speak for the "power user" who builds his own reports. Actually I don't think such a person is common. Real reporters work with Excel, one of the many RS export formats in the box.

    You might argue that RS increases the monopoly of Microsoft, another kind of product where they are trying to be marker leader. Could be, but I prefer a good night of sleep.

  • A back button for asp.net pages

    For my app I needed a back button. Internet explorer and other browsers have back buttons, most mice have them as well but I needed my own small link to drop on my forms. Implementing it was no big deal, given you consider one essential quirk. After browsing around on the web I consider it worthwhile to share my findings.

    The essential thing is what back really stands for. When an user is working with an aspx page she will regularly post back to the page leading to many renderings of the same url. By default back is back to the previous request. An application like Community Server (which is an asp.net app) works this way. Write you comment and click submit. When you click the back button of your mouse after that you'll be back editing the comment. When you click submit again it might look like you 're posting an updated comment. In reality CS does receive a new comment. (Don't try this at home, to prevent comment spamming CS blocks posting comments in that pace). To give the user a better user experience the smartNavigation property of an asp.net webform comes to the help. Setting it to true will redirect the user to the previous page when the back button is clicked. It does this by some script magic. Alas smartNavigation can play some nasty tricks on you when you try to redirect from a page which has it enabled.

    In code you can see from which url the user came in the UrlReferrer property of the Request.. This always show the url of the last roundtrip, whether smartNavigation is switched on or off. So it will be the url of the page itself on a postback. On the first rendering of the page it will contain the intended page the user came from. So checking postback in combination with the referrer should do to find the desired url. The url has to be stored over roundtrips. On the best example I found on the web, by master of mystery Juval Löwy, it is stored in the session. This is a full demo ((free) registration required) where clicking a linkbutton performs a redirect to an URL. But besides problems with  smartnavigation I think the viewstate would be a better place to store the url than the session.

    I use a plain HyperLink. The essence of my back link boils down to

    private void Page_Load(object sender, System.EventArgs e)
    {
       if (! IsPostBack)
          HyperLink1.NavigateUrl = Request.UrlReferrer.AbsoluteUri;
    }
     

    The NavigateUrl is set on the first request and will be saved over roundtrips in the viewstate.

    As I am a bad and a lazy typist I don't want to code these lines again and again. Let's make it a custom control. Take these steps:

    • Add a new project, a Web ControlLibrary
    • Delete the webusercontrol1
    • Add a new item to the library, a Web Custom Control. Give it a real name
    • Delete all generated implementation code
    • Copy in this code
    using System;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.ComponentModel;

    namespace ButonBacklLibrary
    {
        /// <summary>
        /// Summary description for MyBackButton.
        /// </summary>
        [ToolboxData("<{0}:MyBackButton runat=server></{0}:MyBackButton>")]
        public class MyBackButton : System.Web.UI.WebControls.HyperLink
        {
            protected override void OnLoad(EventArgs e)
            {
                if (! Page.IsPostBack)
                    base.NavigateUrl = Page.Request.UrlReferrer.AbsoluteUri;
                base.OnLoad (e);
            }

            [Browsable(false)]
            public new string NavigateUrl
            {
                get
                {
                    return base.NavigateUrl;
                }
            }
        }
    }
     

    The MyBackButton inherits from the HyperLink control. In the overriden OnLoad method the code to get the referral url is executed and stored in the NavigateURL property of the base, HyperLink, class. It no longer makes sense to manipulate the NavigateURL property of the back control in the designer or from code. I cannot override the property as it is not virtual. Using the new keyword the original property is shadowed. In code and in the designer my version of the property named NavigateURL is used. The implementation of the property can still get to the inherited property. The property getter just reads the base property, but the setter property has gone. I can no longer change the URL from code. By setting the [Browsable(false)] attribute on the property it will also be gone from the property window in the designer.

    To get this button into the VS toolbox:

    • Right click the toolbox
    • Choose Add/Remove items
    • In the dialog click the browse button
    • Select the library we just built It's the dll in the bin\debug or bin\release directory
    • The control will show up in the toolbox.

    You can start using the control in you project. Debugging works well, breakpoints set in the control's source will be hit.

    Now you have a back button which is independent of the smartNavigation and session settings. But it does need the viewstate. Fiddling with that is another story.

  • The C# ?: operator

    Often I work for people with a Delphi background to introduce them to C#. No problem until we reach the conditional operator ?: The definition in the docs is cond-expr ? expr1 : expr2  but the examples are not that inspiring. The most common reaction is "we're not going to use that". Recently I found a very good way to use and demonstrate it. Let me share this.

    I'm working on an application which works with an existing database. Jeremy Miller has a lovely story on those kind of animals. Mine is not to bad, I have an occasional WTF but not on a daily base. To keep the DB as far away as possible I designed a  couple of strongly typed datasets and built a set of components to fill these. Instead of an alien database I now have my dataset. But I'm still not sure what's inside. That's where the ?: comes to my rescue. Take this code

    Indato.Data.Schemas.School.OPLOVKRow dr = OPLOVK.OPLOVK[0];
    TextBoxOmschrijving.Text = dr.IsOPMERKINGNull() ? "" : dr.OPMERKING;
     

    dr is a strong typed row. The problem is that I can never be sure if it doesn't contain a null value. Trying to set the Text property of a Textbox to null will throw an exception. The typed dataset has an IsxxxNull method for every field. This is a boolean test, if it evaluates to true the empty string after the ? is used, if it evaluated to false the contents of the field, that's the expression after the :, is used .

    Fits the docs and very worthwhile using.

  • SQL Reporting Services: Visibility is a confusing property

    A SQL reporting services report definition has loads and loads of properties. One of these is the visibility of a table (the core of a report) or subreport. Also here you can use a vbscript expression to set the property. I don't know if it is a bug or a feature, but the subreport (or table) will show when the expression is evaluated as false. When it is a feauture I think the property has the wrong name, when it's a bug it is a bug. Confusing.
    Posted Jul 14 2005, 03:18 PM by pvanooijen with 4 comment(s)
    Filed under:
  • The fix for the Tablet PC's memory leak is (finally) there

    Microsoft has finally released the fix for the memory leak in the tablet PC. It's diguished as Windowx XP hotfix KB895953. Took a while. At the time (5 months ago !) I wandered how serious the bug really was for real life day to day tablet use, but the update shows it was quite fundamental. While updating you see tabtip.exe come flashing by, that's really a core componennt. What strikes me is that I had to read it in the Winfo newsletter, MS didn't even bother to send out a mailing to their tablet partners (yet ?).

  • Calculated fields in SQL reporting services

    New York, Madrid, London.... SQL reporting services. All respect for the British flegma with which they respond to terror. They just go on with what they were doing. Having said that (what more can you say..?) I would like to add my micro-pennies by sharing some of my recent good experiences building reports with SQL reporting services. Installing did have some small quirks but since then it has been a joy to use. We had a monster of a Quick Report (a report tool which came with earlier versions of Delphi) which was repeated in three flavors and needed fiddling with the database to gather all information desired. The SQL reporting services version is one plain report using some straightforward sub-reports. Especially calculated fields made all desired options simple to implement.

    A report is based on one SELECT query. The columns returned are available as fields in the report designer. You can add calculated fields to that list. Their expressions yielding the result are in VBscript where you refer to other fields, report globals, parameters as well as VBscipt functions. 

    A simple calculated field might look like this:

    = Fields!AFKORTING.Value & " : " & Fields!INLOGNAAM.Value

    It concatenates two other fields and inserts a string constant. You can also refer to other calculated fields in the expression. A more sophisticated expression looks like this

    = LEN(TRIM(Fields!MyCalculatedField.Value))

    It takes the value of the first calculated field and applies the Vbscript functions TRIM and LEN on it. Reporting services will make sure the fields are calculated in the right order, the second calculated field will contain the right length.

    The core of a typical report is a table. By default the detail rows in there are sorted as they are returned by the report's SQL statement. You can change the sorting on a properties tab of the table. This uses the same expression builder as for building a calculated field. Sort on one of the fields or an expression  Also sorting on a calculated field works very well. As the sort order is just a script expression you can even pass in the name of the field to sort on at report render time:

    =Fields(Parameters!sort.Value).Value

    The report has a couple of calculated fields whose expressions are desired sort orders. One of the parameters to the report is the name of the calculated field to sort on. Originally we had three reports, each with a different ORDER BY in the SQL. Now we have one report where the desired sort order is just a parameter. Thanks to the calculated fields.

    It does not stop here. Instead of VBscript you can also let the report load your own assemblies with .NET code and use that. That's a new story. I do hope at a better occasion.

    Posted Jul 08 2005, 06:22 AM by pvanooijen with 6 comment(s)
    Filed under:
  • An idea waiting for a commit

    As a yearly recurring event around TechEd Europe Juval Löwy did a presenation for dotned, the Dutch user group. It was a fascinating talk, for two hours we have been bombarded with some very fascinating idea's.

     

    Juval's main message is "the is no such thing as recovery code". Your application starts in a certain well described state. As soon as your code starts fiddling with that state you app's state is unknown and should be hidden to the outer world. At a certain moment the code should say "this is it" and commit that state. Or it should say "oops" and roll back to the previous well defined state. That's programming in transactions. Any attempt to try to fix something in your own recovery code is (in Juval's words) futile. At the moment the only tools which support transactions are the better database servers. You mark the start of a transaction, start fiddling and commit the updates to the database or rollback all changes.

    Now wouldn't it be lovely to write all your code like that ? Yes it would. But I have a problem with further exploring the subject. In the talk we've been a sounding board for some very fascinating ideas on this. But we've been asked to zip our mouths'. It's still in review, when ready you're going to read all about it in the near future. I hope I'm not bringing Julian (or myself) in any trouble by even mentioning this talk... I just hope to have stirred your curiosity and, most of all, have motivated you to go to user group meetings yourself.

    Any questions ?

  • Any Tablet PC sessions at the PDC ?

    The PDC 2005 frenzy is heating up, on Codebetter you'll find poetic as well as total geeky starters. The content of the PDC is also starting to materialize. I skimmed all session and tracks for "Tablet PC" but did not find a thing. So what's next ? Convert my Tablet  to a beer coaster and stuff myself with conference snacks ?

    To be serious: there will be a lot of tablet stuff on the PDC but you will not find it under the name Tablet PC. Recently I was wandering what direction the tablet is going to take. Some answers to that were already there on the PDC 2003. In the keynote of the PDC 2001 the tablet PC SDK was announced, tablet PC's themselves were available in 2002, about a year after that. The 2003 PDC was all about Longhorn and its presentation layer Avalon. Some bullet highlights from a 2003 presentation slide deck :

    Avalon support for Pen Input and Ink:
    • Stylus is a 1st Class Input Device
    • System Controls are pen-aware
    • Any Avalon element can support ink

    Improved Ink Recognition

    • Personalization
    • Ink Analysis
    • Support for more languages
    Native Avalon Input Device
    • Tightly Integrated into Avalon Input Manager and Events system
    • Rich Stylus Events

    Unified input stream for Stylus and Mouse

    • Stylus emulates mouse
    • Containment for promoted events in Avalon apps

    Ink will be a 1st class citizen of the WinFx framework:

    The presentation is almost two years old but still very worthwhile to study. You will recognize many parts of the tablet API as well as WinFx and the Longhorn programming model.

    This year, on the Windows HEC conference there was another interesting presentation. Longhorn plans go further than pen and ink, fingertip touch will be added. To quote some bullets:

    • In Longhorn we are planning to add Touch as a new mode for Navigation and Control
    • Great complement to Pen and Speech Input
    • All navigation with Pen also works with Touch but is more efficient and intuitive - no pen required
    • Mouse operations: Tap and Double tap with finger
    • Advanced gestures: Finger flicks
    • Longhorn plans to enable easy precision targeting with finger
    • Stylus still preferred for ink input

    To use touch requires a resistive digitizer type, to use a pen requires an ElectroMagnetic digitizer. Dual mode digitizers exist. From OS perspective there are two drivers; for the API touch is an extension on the Tablet's Ink API. The presentation has some great ideas how to overcome the problems of combined digitizers. Imagine resting your hand on the screen while writing with the pen. The first would fire of the resistive digitizer, the second the EM-digitizer.

    This is to be continued on the PDC 2005. If you're looking for tablet presentations, search for Avalon or straight for the functionality you're looking for. I.e. handwriting recognition. It's all becoming mainstream. Last february, Shawn van Ness, author the MS column mobile inkjots, has joined Microsoft as a PM to integrate the tablet API into Avalon to make it happen. I just wished he would blog a little more. As an MS employee he can't take part in bloggin' my way to the PDC. But I would read his scribbling anyway.

    <Update>Shawn just did post. On Ink and Avalon...</update>

More Posts