Saturday, July 28, 2007

Problems installing Windows Mobile 5.0 SDK R2 for Visual Studio 2007 Beta 2

I've had some trouble installing Visual Studio 2008 Beta 2 (I'm installing the Visual Studio Team System 2008 version). The installer fails when trying to install Windows Mobile 5.0 SDK R2 for Pocket PC, and I got the following error message:

"Installation failed for component Windows Mobile 5.0 SDK R2 for Pocket PC. MSI returned error code 1603"

What turned out to be the problem was that I already had a version of the Windows Mobile 5.0 SDK installed, namely the one that works with Visual Studio 2005. So apparently that one had to be uninstalled first. This does not seem to be mentioned in the installation instructions, or then I'm just crap at finding it.

Once I uninstalled the old version I tried going back and repairing the installation, but that didn't seem to try to reinstall the missing bits. What I ended up having to do was to go into the setup for VS 2008, select "Change or Remove Visual Studio 2008", and once the setup wizard has loaded press next and select "Add or Remove Features". The only missing bits were Crystal Reports for Visual Studio Beta 2. When I selected those, and started the installation, it also installed the missing stuff for Windows Mobile (and a lot of other things it seemed it had left uninstalled becuse of the error as well).

Friday, July 27, 2007

Visual Studio 2008 Beta 2 released

I just noticed on ScottGu's Blog that Beta 2 of Visual Studio 2008 (Orcas) has been released, and since I nowadays am an absolute WPF and LINQ fanboy I can't wait to try it out. I'll blog more once I've got the bits installed.

Saturday, June 30, 2007

Learning XAML

Lately I've been busy learning about WPF and XAML, and I have to say that cool doesn't even begin to describe it. After TechEd 2007 I installed the Visual Studio Orcas Beta 1, and it's been a pretty smooth ride so far.

One of the first things I've been playing around with is adding some better visualizations to some existing stuff we're doing at work, and for that I've been trying to figure out what can be done with the ListView control in WPF so that I won't have to resort to third party grids immediately. The reason for that is that first of all I want to really understand what WPF can do for me before I resort to third party stuff that tries to wrap everything up nicely for me, and in addition to that I've had a lot of really bad experiences with the different control packages out there (I could write an essay on Infragistics, but I think I won't).

One pretty good source on how to do cell templates for the list view I found was on Corrado's Blogs. It's in Italian, but the pictures and XAML speak for themselves.

One "funny" thing that happened was when I in the Orcas Beta 1 was trying to create a column that would show a checkbox in the cell. I was trying to set the cell template to bind to a property of the object that was being shown in the list, while having the designer open (Orcas shows both the design surface and the XAML at the same time by default). I was still typing the binding string for the IsChecked property of my check box-based data template, and switched to another window to check what I was supposed to bind to, switched back and got the following error message:

image

Note the nice way it shows the actual exception. It has a scrollbar for the completely unnecessary error message telling me that the designer just went completely insane, but the actual error message it refuses to even wrap. Fair enough, I didn't have a correct string set up. But getting rid of this windows turned out to be quite hard. I clicked OK, and it popped up again. One more OK just resulted in one more window. After about 20 tries I realised that this was quite a persistent little bugger, and tried to figure out what I could do to get around this.

What I ended up having to do is click OK, type one or two characters before it popped up again, click OK, type some more, and that way I was able to enter "true" into IsChecked, and finally it stopped.

Chardonnay helped me calm down.

Monday, August 21, 2006

How Software Factories changed my life

I’ve had three Microsoft-related epiphanies at work this year. The first one was when I finally got my head around how we could use Agile development methodologies to reinvent how we make software with the help of MSF Agile. The second one was when I realized just how good SharePoint 2007 is. The third one was Software Factories.

I don’t know if it is fair to claim that Software Factories are in themselves a Microsoft-specific concept, but MS sure are driving the field forward at the moment. I first saw Jack Greenfield do a presentation on the at TechEd 2005, and while I did find the topic interesting there simply wasn’t enough of an incentive available to actually start using them. Now there is. Guidance automation in Visual Studio 2005 has become mature enough for it to be possible to produce truly useful factories, and there are a couple of really interesting ones out there. Since this spring we’ve been using the Smart Client Software Factory, and it looks like it is changing the way we make Windows Forms applications.

To me factories are about decreasing the amount of “plumbing” code you have to write in an application, and a way to make sure that similar applications are structured and built in the same way. I once saw Rockford Lhotka do presentation in which he mentioned that about 80% of the code that gets written as part of an application is not about producing actual value to the customer (i.e. those bits that the customer feels they are paying for), instead it goes into frameworks and similar things that are required before you actually can start writing code that implements any business-related functionality. You may argue that 80% seems high, I feel it is a pretty good average. I’ve been working on projects where it has at least felt that 95% went into plumbing and only 5 percent actually gave users any value, and on the other hand I’ve seen project where good choice of tools have allowed the developers to spend half their time on the actual functionality. Be as it may, one can argue that anything about 0% is a waste of time and the customer’s money. While I don’t believe we can reach that 0% anytime soon I feel that factories might be a good way to reach 50% or even go below that.

From our point of view the whole thing started with the Composite UI Application Block (CAB), which we started doing work with little over a year ago. The CAB allows you to create Windows application that are composed of discrete parts (Smart Parts) you can use in an MVC pattern to build applications. While it is really a framework and not a factory it is what got us really interested in the factory space. We used to have a great deal of variance in how we architected and developed Windows applications, and the CAB helped give us a reusable structure for that. It was generally felt that the slight overhead introduced by the CAB was well worth it, since it forced the architecture and structure of our solutions towards a similar and more easily understandable model. However, there were still differences in the architecture of the applications and how the CAB was being used. We found that a framework like CAB simply left too many things open and allowed the developers too much freedom in how to use it efficiently. This freedom didn’t lead to the ability to create solutions of higher quality or solutions that where more adapted to specific customer needs; it only led to different ways of achieving the same thing. In essence we were still reinventing the wheel, albeit on a smaller scale.

Last spring the Smart Client Software Factory changed this. The way GAT, GAX and the factory way of thinking gives the developers access to context-sensitive processes (recipes) for achieving pre-defined results does away with the unnecessary differences we are seeing in the architecture and structure of our applications when using only the CAB. I am expecting great things from the Smart Client factory. It seems that it is reducing the need for architecting the client side of the solution, and results in a lot more similar solutions than what we have so far been achieving. With limited architect-resources this is great because it means they can focus on actually designing new stuff, not just doing plumbing. For the developers this is great because it results in applications with similar structures, which makes it easier to get into a project developed by someone else.

Over the summer we also started using another software factory, the Service Factory. This promises to do for the server side what the Smart Client Factory did for the client side. Our experiences are so far limited, but since we’ve been seeing the exact same problems on the server side as we did on the client side, with great variations in how we build Web Services, I’m hope we’ll be seeing some great benefits from this factory as well. I’ll post more on it later.

To summarize, in many cases our architects have been spending most of their time on the plumbing, not on the business functionality, which means that there is not enough focus on the design of the bits that the customer actually see and feels is giving him value. Software Factories will help us reduce the architectural and development work that goes into the background bits that shouldn’t have to be rebuilt every time, and that the customer is not too keen on paying for. While I do not have any actual numbers on the increase in efficiency or on the decrease in complexity I have a strong gut feeling that they are substantial. If I come up with something I will post it here.

Sunday, June 11, 2006

TechEd 2006: On the importance of working within set requirements

Requirements and architecture

At the TechEd architecture preconf Ron Jacobs talked about what requirements are, and how they help define the goal for what you are trying to achieve. He drew a parallel to playing soccer on a field with no goal posts, no lines, no constraints whatsoever. Just starting to play, and figuring out the goal positions and so forth as you go along. Obviously this would simply not make any sense. However, people seem to believe it does so when making software. Especially from an architect’s point of view it is important to understand what we’re trying to achieve at least on a hight level before we can decide how to design it. If the architecture is broken in a sufficiently bad way it might cause the whole system to go back to the drawing board (suck on that, XP!). And how might this happen? By not understanding the business problems well enough and screwing up the requirements gathering and therefore designing an architecture to solve the wrong problems. Therefore a certain amount of up-front design is necessary.

But often enough it also happens that architects and developers get too worried about the requirements, and they let this block them from designing the solution. They start worrying about every little bit of unknown area, and refuse to touch it until it’s been specified. So this can really hit two different extremes. Either you do no design because you don’t know the requirements and just start coding, or you get anxious about not knowing everything so you produce nothing.

Learning to balance this line is key to becoming a good developer or architect, IMHO. You need to get enough confidence in yourself to trust that you will find a solution to problems that come up and just get started on designing those parts that can be designed. Focus first on those areas that you do understand, and use that as a way to get going and to create something that you can show the customer and get feedback on. This way the rest of those requirement will start to appear, and you can incrementally improve your design. Experience will teach you which types of things you need to know up front and which kinds of things it is ok to defer until you have more information.

Getting people to commit to the project

One of the really key things we’re trying to improve in our organization right now is to get everyone in a project to have a shared understanding of what the project is supposed to achieve. This sound like something really obvious, but still it is one of the most simple things that companies fail to get right. I’ve worked on many project where management has thought that everyone involved knows the goal of the project, but in reality none of the developers really do. Note that this also includes times when I have been part of the management for these projects.

In a situation like this it’s impossible for them to make good decisions about how to develop something or on how much time to spend on it, simply because they lack context. And that results in a lack of commitment to the project (sometimes I think that developers believe that “commit” is what you do when you check in code to version control). Without commitment and context you will be stuck with a bunch of people that can make no decisions on their own and can only perform exactly the tasks you give them. But by getting them more involved and by giving them context you allow them to contribute to the project beyond simply performing precisely given tasks. And you are sure to benefit from it.

All it takes to sow that first seed of project commitment in all the project members is to create a good vision statement and sit down with the whole team an talk through it. Discuss it and make sure everyone understands it. After this they will feel a lot more connected to the project because they have context. And the commitment will follow.

Monday, May 22, 2006

Modifying the Windows Forms MonthCalendar control

CalendarAt work we’ve got a .NET 2.0 Winforms time card-type application for entering information about which projects we work on. In this application we wanted to show the user which dates he’s entered work hours for. We decided to have these dates for show up in bold, just like in Outlook where it shows you which dates you have appointments for. This is easy, since this behavior is supported by the MonthCalendar control.

But we also wanted to indicate those days for which he’s not yet entered enough hours. We wanted those to show up in red, and since this is not standard behavior in the control we had to modify it. This turned out to be more difficult than I had expected, and therefore I decided to blog about it.

I do not claim that the stuff outlined below is the right way to mod the control. Actually, I sincerely hope it isn’t. Because it sure feels like climbing up a tree ass-first. So if anyone can point out a better way to achieve this stuff then I’d love to hear from you.

Step 1 – Checking the documentation

First I created a new control that derived from the MonthCalendar control. But when reading the documentation for MonthCalendar I started to suspect that implementing these red warnings might not be so easy after all. Because the control is drawn by the operating systems there are rather limited options for modifying it. In the documentation I found this gem:

“The MonthCalendar control is drawn by the operating system, so the Paint event is never raised. If you need to provide a customized look to the MonthCalendar control, you should override the OnPrint method, call the base implementation of OnPrint, and then perform custom painting.”

Sounds easy enough. There’s just one problem. OnPrint is never called. Ever. Asking nicely didn’t help. After fighting with this for a while and not really finding anything I decided to try and solve this some other way. I found very little info on the MonthCalendar control on Google, which became one of the reasons I decided to write this article.

Step 2 – First nasty workaround

OnPrint didn’t seem to be the way to go, but I managed to find something on Google in the end. Someone (sorry, can’t remember where I found this, so I can’t thank the person who provided this) pointed out that in WndProc it would be possible to catch the WM_PAINT event and use that. The code would look like this:

// Override WndProc and force a call to OnPaint when we get a WM_PAINT
protected static int WM_PAINT = 0x000F;

protected override void WndProc(ref System.Windows.Forms.Message m)
{
    base.WndProc(ref m);
    if (m.Msg == WM_PAINT)
   
{
       
Graphics graphics = Graphics.FromHwnd(this.Handle);
       
PaintEventArgs pe = new PaintEventArgs(graphics, new Rectangle(0, 0, this.Width, this.Height));
        OnPaint(pe);
   
}
}

Fair enough, I decided to go with that.

Step 3 – Adding some basics

Next I needed a list of those dates that should show up in red that we want to warn the user about.

private List _warningDates = new List();

public List WarningDates
{
    get
    {
       
return _warningDates;
   
}
    set
    {
        _warningDates = value;
    }
}

Nothing strange there.

Step 4 – Figuring out the dimensions of the control

Now the fun really began. At this point so much time had been spent on figuring out the basics of this that I was really pressed for time and had to start cutting corners. Basically I wanted to be able to identify where in the MonthCalendar a certain date was appearing so that I could draw a red square on it. For this I needed to figure out the dimensions and appearance of the control. I started with trying to figure out where in the control the actual dates were being drawn. I didn’t come up with a good way of doing this, and ended up having to use a method called HitTest to try and figure out which area is which in the control. This was a really ugly approach, but I didn’t have time to look for another solution.

I went about it like this:

int firstWeekPosition = 0;
int lastWeekPosition = Height;

while ((HitTest(25, firstWeekPosition).HitArea != HitArea.PrevMonthDate &&
  HitTest(25, firstWeekPosition).HitArea != HitArea.Date) && firstWeekPosition < Height)
{
    firstWeekPosition++;
}

while ((HitTest(25, lastWeekPosition).HitArea != HitArea.NextMonthDate &&
  HitTest(25, firstWeekPosition).HitArea != HitArea.Date) && firstWeekPosition >= 0)
{
    lastWeekPosition--;
}

What basically is going on here is that I traverse the control first from the top and then from the bottom in a straight line looking for the Date-area of the control. I arbitrarily chose to do this at 25 pixels into the control from the left, simply because it was likely that I would be sure to come across the date-area when looking there. I will not be winning any beauty contests with this code.

When I’d done that I needed to calculate the area that is allocated for each date. I did that like this:

int dayBoxWidth = 0;
int dayBoxHeight = 0;

dayBoxWidth = Width / (ShowWeekNumbers ? 8 : 7);
dayBoxHeight = (int)(((float)(lastWeekPosition - firstWeekPosition)) / 6.0f);

This gave me everything I needed for finding out where to paint.

Step 5 – Painting warnings

My original idea was to draw on top of the date drawn by the control itself, and use a red color with the alpha channel set to around 50% in order to achieve the red highlight. However, when I implemented this I realized that it wouldn’t work. Since I called OnPaint every time anything needed to be redrawn I ended up redrawing all the warning areas every time, even for such portions of the control that was not in need of redrawing. Since all of these paints were cumulative I ended up with a control that got increasingly red for each repaint because all the paints were being done on top of each other and the alpha channel was slowly being eroded.

Because of time constraints I had to decide between doing the proper implementation, i.e. starting to take into account which section of the screen actually needed repainting, instead of just painting everything. The other option was to skip the alpha idea and instead draw a solid square and also draw the text on it. I decided to go with the latter, because I decided it would be easier even though it clearly wasn’t the “right” solution.

.NET contains a number of interesting methods for working on graphics, and the new TextRenderer in .NET 2.0 is very nice. By extracting each visible date that should be a warning and putting it in a variable called visDate I was able to do the following:

int row = 0;
int col = 0;

TimeSpan span = visDate.Subtract(calendarRange.Start);
row = span.Days / 7;
col = span.Days % 7;

Rectangle fillRect = new Rectangle((col + (ShowWeekNumbers ? 1 : 0)) * dayBoxWidth + 2, firstWeekPosition + row * dayBoxHeight + 1, dayBoxWidth - 2, dayBoxHeight - 2);

graphics.FillRectangle(warningBrush, fillRect);

The warningBrush is a brush that contains the red color I wanted to draw. row and col calculate the position of the date that should be drawn, by first figuring out where that date is placed in relationship to the first visible date in the calendar.

Adding the text was quite simple.

// Check if the date is in the bolded dates array bool
makeDateBolded = false;
foreach (DateTime boldDate in BoldedDates)
{
    if (boldDate == visDate)
    {
       
makeDateBolded = true;
    }
}

using (Font textFont = new Font(Font, (makeDateBolded ? FontStyle.Bold : FontStyle.Regular)))
{
    TextRenderer.DrawText(graphics, visDate.Day.ToString(), textFont, fillRect, Color.FromArgb(255,128,0,0), TextFormatFlags.HorizontalCenter | TextFormatFlags.VerticalCenter);
}

By using a font based on the font of the control itself and only toggling whether it should be bold made sure that the squares I draw would look the same as the ones created by the control itself.

The end result

New_calendarThe resulting control you can see on the right of this text. Here I’ve given it a black color, and it’s running on a computer with Finnish regional settings. The “red” color I’ve chosen to use on the warnings is actually rather pink.  Please note that although this example does not show it the control can indicate days for which some time has been entered, but not enough. These are shown as both bolded and with a red background.

The finished OnPaint method

The code I’ve presented in this post so far isn’t complete, and it might be quite difficult to read it when I’ve cut up like I did above. Therefore I’ve included the completed OnPaint method below.

protected override void OnPaint(PaintEventArgs e)
{
    base.OnPaint(e);
    Graphics graphics = e.Graphics;

    int dayBoxWidth = 0; 
    int dayBoxHeight = 0;
    int firstWeekPosition = 0;
    int lastWeekPosition = Height;

    if ( WarningDates.Count > 0)
    {
        SelectionRange calendarRange = GetDisplayRange(false); 

        // Create a list of those dates that actually should be marked as warnings.
        List visibleWarningDates = new List();
        foreach (DateTime date in WarningDates)
       
{
            if (date >= calendarRange.Start && date <= calendarRange.End)
           
{
                visibleWarningDates.Add(date);
            }
        }

        if (visibleWarningDates.Count > 0)
       

           
while ((HitTest(25, firstWeekPosition).HitArea != HitArea.PrevMonthDate && HitTest(25, firstWeekPosition).HitArea != HitArea.Date) && firstWeekPosition < Height)
            {
                firstWeekPosition++;
            }

            while ((HitTest(25, lastWeekPosition).HitArea != HitArea.NextMonthDate && HitTest(25, lastWeekPosition).HitArea != HitArea.Date) && lastWeekPosition >= 0)
            {
                lastWeekPosition--;
            }

            if (firstWeekPosition > 0 && lastWeekPosition > 0)
            {
                dayBoxWidth = Width / (ShowWeekNumbers ? 8 : 7);
                dayBoxHeight = (ant)(((float)(lastWeekPosition - firstWeekPosition)) / 6.0f);

                using (Brush warning Brush = new Solid Brush(Color.FromArgb(255, Color.FromArgb(255,240,240))))
                {
                    foreach (DateTime visDate in visibleWarningDates)
                    {
                       
ant row = 0;
                        ant col = 0;

                        Timespan span = visDate.Subtract(calendar Range.Start);
                        row = span.Days / 7;
                        col = span.Days % 7;

                        Rectangle fillRect = new Rectangle((col + (ShowWeekNumbers ? 1 : 0)) * dayBoxWidth + 2, firstWeekPosition + row * dayBoxHeight + 1, dayBoxWidth - 2, dayBoxHeight - 2);
                        graphics.Fill Rectangle(warning Brush, fillRect);

                        // Check if the date is in the bolded dates array
                        bool makeDateBolded = false;
                        foreach (DateTime boldDate in BoldedDates)
                        {
                           
if (boldDate == visDate)
                            {
                               
makeDateBolded = true;
                            }
                        }

                        using (Font textFont = new Font(Font, (makeDateBolded ? Font Style.Bold : Font Style.Regular)))
                        {
                            TextRenderer.DrawText(graphics, visDate.Day.ToString(), textFont, fillRect, Color.FromArgb(255,128,0,0), TextFormatFlags.HorizontalCenter | TextFormatFlags.Vertical Center);
                        }
                    }
                }
            }
        }
    }
}

How to improve this solution

First of all I put a lot of things into OnPrint that shouldn’t really be done every single time the calendar is being redrawn, for example the position of the actual calendar dates in the control. This way is a waste of processing time. I also waste a lot of GDI resources in this solution. I will redo this whenever I have the time™.

Another thing is that nothing in the control takes into account if you set the control up to show more than one month at a time. It wouldn’t be that difficult to support this scenario, but I haven’t had time to do it yet. In our project there is no need for it anyway. I’ve also not tested this approach with different regional settings, and I’m sure that some are bound to break this.

As I pointed out earlier, what obviously should be done differently is to take the update region (i.e. the region of the window that actually has to be repainted) into account. That way I could avoid unnecessary redraws. This would probably have improved the situation somewhat with regards to being able to use alpha colors when filling in the red. More information about this topic can be found here. It is every bit as scary as it looks.

Addendum 2006–05–23

I should post my code to my blog more often. Mikale already pointed out a bug in it that I had missed.

Monday, September 12, 2005

PDC PreConf Day 1: .NET Framework 2.0 - The Smart Client Perspective

As part of my work I make decisions on which client projects should be implemented as Web Applications and which should be Smart Clients. Because of this I decided to attend the pre conference session on Smart Clients and .NET 2, to see if there were any new issues that I was not yet aware of. The session was being presented by Rockford Lhotka and Billy Hollis, two gentlemen who’s sessions I’ve had the pleasure of attending before. I’ve been working on a project using Visual Studio 2005 since February, and that project involves some Smart Client elements. So most of the stuff covered by this session was pretty familiar to me, but it was still nice to hear how these two cool guys view these things.

The session started out with a discussion on the history of client user interfaces, focusing on how we’ve moved from mainframes and client server apps to web apps and now back again. The guys also touched on one issues I come across quite a lot – namely that by now people have finally gotten used to UIs being browser based and there is a fair amount of resistance towards going back to making “real” Windows applications again. One of the major issues they recommended was to take a look at how you calculate the cost of different alternative and especially how calculating the per user-cost of a web application can be misleading. The reason for this is that in so many cases you will end up having to add a lot of quite expensive hardware and licenses to your server setup when your user amounts increase. If you work with Smart Clients you might get away with less investment on the server, since you can actually use some of that computing power in the usually quite expensive desktops or laptops that your users are equipped with.

A lot of interesting and funny stuff was covered during the intro and the Smart Client background, and I won’t repeat it here, except for one last thing; how there basically no general agreement on what a Smart Client actually is. My view on it is that the name is horribly misleading and that they should actually have been called “Windows Applications – Finally Done Right” (WAFDR). But I guess that would have been too long for the Microsoft Marketing Department to accept it. Sigh. But that won’t stop me from using it!

Data and Data Binding

They kicked off the proper session with a look at the data and data binding stuff in VS 2005 and how it has evolved from the .NET 1,1–world. One of the really major new things I’ve found in Windows Forms 2 is the ability to do data binding to objects, which is is essence the only decent way to do it in a client server application or in a real WAFDR application. It’s also become a lot easier to work with data sources, ranging from how to create them to how to use them in your forms. One thing I really like is that VS now comes with a proper data set editor, instead of just using the regular XSD-editor, which isn’t really that good for data sets. I’ve done some work with this stuff, and I can tell you it’s actually quite good. A clear and great step forward for data binding, and even though I’ve been quite sceptical towards data binding in the past I have to say that has mostly changed over that past 6 months because of working with VS 2005. And most of the stuff is nowadays strongly typed, which is the way it should have been to start with.

In Windows Forms 2 there’s a bunch of new UI controls, and for the first time ever there’s a pretty good grid control included (the GridView control). It used to be so that you couldn’t really understand why Microsoft even bothered to include their own grid control in Visual Studio, since it was so crap. But that’s changed now, because the GridView is actually quite nice. It lets you use proper controls in the cells, and it also lets you set a bunch of display properties all the way down to the cell level. At work we’ve used a bunch of third party controls in order to get decent grids and certain other UI controls, and we’ve not really been happy with them. Most are simply too bloated to be practically useful in a business environment where some of the client machines might be a bit old and therefore not able to deal nicely with the multitude of events firing all over the place in the grid. And not to mention what a disaster they tend to be in ASP.NET, especially in an environment where every machine is not set to use English (United States) as their regional settings. We’ve used Infragistics a lot, and by now I pretty much consider them to be the unholy Spawn of Satan. With VS 2005 we’ve been able to avoid using third party controls for several new projects, which I’m quite happy about.

Rhockford talked quite a bit about the data stuff, and I won’t repeat all of it here, but one thing I got stuck on was where to place business logic in an application. Quite obviously it should not be in the UI, and it seemed that his opinion was that the reason why people tend to put it there was because you couldn’t data bind properly to object before (not without a lot of work), and you couldn’t really put logic in the dataset. Either that or stupidity. But in this presentation he talked about how now it is possible to put logic in the data set, and seemed to be of the opinion that this is a good thing. I haven’t had time to think about this myself yet, but I have to say I am rather sceptical. Perhaps what he meant is having it in the object that contains the data in general, and since the data source could be an object as well then perhaps he meant was having it in a custom object and binding to that. Or then perhaps I just didn’t catch was he was on about.

Break for lunch, I’ll post more in the afternoon.

Smart Clients Continued

(This is the second half of my post from the first day of the first pre conference day at PDC 05)

The afternoon started off with some more discussion on data binding and on objects with a focus on business logic. At this point the session started to get more interesting, since now they were starting to cover the parts of application design where I still have some doubts and unclear issues regarding Smart Clients (or WAFDR applications, if you read my previous post). Here it also became apparent that Lhotka did put the business logic in custom objects on which he did data binding, which I was wondering about in my previous post. How to move the data between the client and the server was discussed at some length, with a jab at Juwal Löwy on the topic of whether to use web services, enterprise services or remoting (Juwal is fanatic about Enterprise Services, I’ve heard him preach on the subject in a number of presentations). Basically the point here was that using IIS is the easiest and Enterprise Services the fastest. So regardless of what the Enterprise Services Taliban says I guess at least I would recommend using the simplest solution available, as long as it still does the job. In many cases that means hosting your server in IIS.

Layers in a Smart Client

Next was the topic of layers and tiers, and why they matter when designing an application. This was pretty basic stuff, at least if you’ve worked on reasonably large applications. The “traditional” view on this topic works somewhat well in a Smart Client scenario, but since most Smart Clients need to work off line that adds some complexity to the picture and has an impact on the application architecture. Since the business logic needs to run on at least the client, and in many cases some of it has to run on the server, you need to slightly rethink how you structure you app. Lhotka was describing it through a data portal pattern, which was just a way of describing an architecture where you had a server that exposed a bunch of data-related services that were exposed to a client, where they were hidden away by a facade. The business logic accesses the data through the facade, without having to concern itself with from where and how the data is being produced. Pretty basic stuff, and I was happy to see that they were recommending some of the same solutions that we have been putting into our solutions for the past half year. The major of the remainder of this part of the session was spent on talking about which part of the business objects live in which layer, and where it exists as data and where it exists as a business object (the difference between business logic and data here is that a business object contains layer). The model Lhotka came off as recommending was one where the business objects exist both on the client and the server, so that you can have a situation where you don’t need to trust the client; the server can make its own choices on the data in the objects without assuming that the client has used the correctly.

I had been a bit worried about the risk of finding out a bunch of new and superior ways of architecting a distributed app for a Smart Client compared to the stuff I’ve been doing at work, but fortunately that was not the case. That could have resulted in some re-engineering in a bunch of customer objects, which I would prefer not to have to do at this point… There was a lot of nice details here, and it was good to get confirmation of the design choices we’ve been doing.

New stuff in Windows Forms 2.0

I won’t write about this in great length, it’s a topic that has been covered quite a lot in other blogs. I’ll just quickly mention some of my favorite things (I already mentioned the grid in my previous post). The first would be the two new layout controls (flow and table layout). This is basic stuff if you’ve worked with UIs in Java, but it’s new in Windows Forms. Hollis pointed out that in the Smart Client world you can’t make so many assumptions about what the user’s screen proportions and size are (consider Tablet PC:s for example), and therefore the layout controls can be very useful. I agree completely with this. Furthermore they help in making sure your UIs always look and behave the same. The next thing I’d like to mention are the new toolbars and menus, now they look like proper Office menus and toolbars, which is something I’ve missed in the standard controls. Basically we’ve had to use third party controls in all our apps, and I mentioned what I thought about that in my previous post… Finally the fact that you can tell your text boxes what kind of data you want them to accept (in the shape of format strings) is very nice and a great help in making it easier for users to enter correct data.

New language features in VB and C#

Why this was included in this session is beyond me. I won’t cover it here, except for to note that VB (which I don’t use) has a new keyword called “IsNot”. So you can write grammatically disastrous code along the lines of:

“If myVariable IsNot Nothing Then”

English is not my native language, but isn’t that a double negation? Shouldn’t it have been called:

“If myVariable IsSomething Then” or “If myVariable Is Something”?

The first alternative is a bit illogical (which would make it excellent for inclusion in VB), but I really like the second one. That would only have required that they would have introduced an alternative (or actually an opposite) of the already existing “Nothing”. Neat. That would have allowed you to write stuff like:

“If Something Is Nothing Then”

and of course, instead of writing “1 = 1” or “2 > 1” to indicate statements that would always be true you could instead type “Something > Nothing”. But then again I guess that you can’t always know if Something actually is more than Nothing. If Freedom can be a another word for Nothing left to lose, and Nothing ain’t worth Nothing but it’s free, then quite obviously Nothing is Free, and therefore it is also Something. This is getting rather philosophical, which again would have put it firmly out of reach of VB. Hmm, wouldn't it be valid VB code to write “If Nothing IsNot Nothing Then”, and that would always evaluate to false? Does that mean that VB is trying to tell us that Janis was wrong? Damn this jet lag.

Click Once install

I’ve blogged about this before, so I won’t go into detail on it now, except for to say that I really like it. I think it will considerably simplify application deployment, at least for deploying applications in a corporate scenario. One thing I believe I didn’t mention last time I wrote about this is that Click Once can not do background updates (like Windows Update and the Application updater block does). This will be added later, apparently when Vista comes around. I do think this is a bit of an annoyance, but as long as the application is running on a fast network and not over the Internet is should not be a problem. On the other hand, with careful use of the options for selecting how the update should behave (check on startup, compulsory update etc.) I think it will not make such a big difference that the application can’t update in the background. Will have to get back to this when I’ve had a chance to test it out a bit more.

The bootstrapper is nice. If it works as promised then Click Once will be able to install stuff like the .NET Framework and SQL Server Express as part of the installation processes. That will be seriously cool.

Tuesday, June 07, 2005

Exploring the ClickOnce installation mechanism

I caught the last half hour of a session on ClickOnce, which is a new installation technology in .NET 2.0. The main idea is that an application can easily be installed over the Web. It can also be updated automatically whenever a new version is placed on the server it originally was installed from.

ClickOnce is a very interesting technology, and it looks like a very interesting deployment option for Smart Clients. It seems quite secure through its use of certificates for signing deployments, and it still leaves enough maneuverability for it to suit a wide range of options. The deployment mechanism can be configured to work both automatically and manually, and if running automatically you can select if it should check for updates before starting (so that users always run the latest version) or while the application is running (so that the user can use the new version the next time he runs the program). You can also configure certain updates to be compulsory, which is nice if you need to distribute an urgent hot fix and don’t want to give the user the chance to not accept the update. You can also do the updating in code, which means you can let the application decide when an update should take place.

ClickOnce can also install the .NET Framework on PC:s that do not already have it installed, through a small bootstrapper. This should greatly simplify deployment on unmanaged machines. I guess most mid-size organizations still tend to not manage their machines through SMS or Tivoli, so this will be a great help both for deploying applications in corporate environments and on machines running in a small organization or in someone's home. In addition to the Framework you can also configure it to check for a bunch of other prerequisites and to also install other MSI packages that is needed by the application. SQL Server Express is now so easy to install and configure (you can even xcopy-deploy databases) that it can be deployed as a prerequisite for your ClickOnce application. Severely cool, and I think we are going to see a lot of stuff utilizing this technology in the next year.

One negative thing is that ClickOnce can only install applications per user, meaning it is difficult to use it to install applications that will be used by several users on the same machine.

Compared to No-Touch-deployment, which was pushed quite hard as the way to distribute .NET apps over the web until now, it is quite safe to say that ClickOnce offers a complete replacement since it can work with a much wider range of applications and is much better. There are still situations where you want to use MSI:s, and conceivably you can also consider the two technologies to be complimentary. You could distribute an application on a CD as an MSI and then have it update itself using ClickOnce. The Application Updater application block is not necessarily replaced by ClickOnce either, since the Application Updater can be tweaked more, giving you a wider range of control over the update functionality. Furthermore, the Application Updater uses BITS for background transfer, which is kinder to your network connection.

Saturday, May 28, 2005

User interfaces

I have been looking into different ways of constructing user interfaces for a project at work. It’s a fairly large Winforms application with probably hundreds of screens, and the idea is to try and make the user interface as process oriented as possible. For this I have been looking into both the User Interface Process Application Block and the Composite UI Application Block, both available on GotDotNet.

The idea of composite user interfaces really appeals to me in this case since it is pretty much what we need for this project. Basically they are about how you can construct complex user interfaces from simpler parts that can communicate with each other without having to be aware of the inner workings of each other. Typically the different UI parts would each be talking to different services, and do not need to be aware of what the different UI parts actually accomplish together as an application. You can find out more about the CAB here in eugeniop’s blog.