Friday, December 16, 2005

Toto, I've a feeling we're not in San Diego anymore

So you may have noticed I haven't been writing in my blog for a couple of weeks. The reason is that I moved from San Diego, CA to Kirkland, WA.

Being a native of Vancouver, B. C. I knew what to expect in terms of weather although the winter out here has been a little strange so far (all week and a half that I've been here), colder and drier than expected.

Why did I move to Kirkland, WA? Well, because Kirkland is close to Redmond and for a number of personal reasons I made the plunge and am now working for Microsoft in the .Net Framework, Client and Web Platform and Tools Team. More specifically, I'm working on the Cider project.

What's Cider? It's a project code name for the visual designer for Windows Presentation Foundation (avalon). The key difference between Cider and Sparkle (also a WPF/Avalon visual designer) is that Cider is geared towards developers and will run inside Visual Studio whereas Sparkle is geared towards graphics/UI designers.

I'm very excited about this opportunity, it's a strong team of awesome people.

As such, I am moving this blog to http://blogs.msdn.com/jnak, please update your RSS aggregators and bookmarks.

Monday, November 28, 2005

Microsoft Code Names

Here's an interesting Channel9 wiki that tracks the current code names used at Microsoft:

http://channel9.msdn.com/wiki/default.aspx/Channel9.CodeNames

Sunday, November 27, 2005

I want my Next-Gen TV

Have you ever thought about how TV shows will be delivered in the future?

I can tell you how I want it to be delivered: I want a searchable, show based subscription, time shiftable, place and device shiftable (search, subscription and playback) in a simple, integrated experience.

Presently, I'm a proud tivo owner and the tivo has changed the way I watch TV. Sounds trite but honestly, I got a tivo at a time where I had almost given up on watching TV altogether because of the hassle of working off the show's air time. The tivo brought TV back into my life and I'm enjoying it more than ever.

I want more though, I want to see what I have ready to watch from anywhere (i.e. home TV, any connected computer in the world) and then watch it from anywhere (i.e. from my PSP, Video iPod, any connected computer in the world, TV in my hotel room or home TV). The place-shifting is semi-available from Slingbox (when's the PSP and Video iPod integration coming?), and I want that with a more integrated end-to-end experience.

In terms of searching for shows to record, even though I've never seen a better "search and subscribe for TV shows" experience than tivo (kills the Time Warner DVR and the TV Guide powered Sony thing) the next generation needs to be better.

What I really want to do is search for some show from anywhere (Home TV, any connected computer in the world) and one click it into my "TV show aggregator" without worrying about show times and conflicts.

In other words, I really want the RSS blog reading experience for TV shows from a "TV show newsgator" equivalent which my TV, computers, Video iPod and PSP can all access.

IPTV (check out Microsoft TV) is a step in the direction of the future of TV. Hopefully the progress that is being made in RSS and SSE with content (like blogs) in terms of technology and user experience will provide a bootstrap for the next generation TV experience.

In related news:
Cisco purchases Scientific-Atlanta
Tivo to Support Video iPod and PSP transfers
Tape It Off The Internet (tioti.com)

Tuesday, November 22, 2005

MMC

Someone recently asked me how to bring up the services console without going through the Control Panel.

I got to thinking about what the comprehensive list of consoles was and I found this great list of all of the pre-configured consoles that come with XP as well as instructions on how to build your own custom console.

XBOX 360

So I got to Best Buy at about 15 minutes before 9:00AM this morning to pickup my XBOX 360! Unfortunately, the store only had about 60 of them in stock and there was about 120 people in line! Crazy.

It seems a little absurd to me that a big store like Best Buy would only have 60 units at launch (a lot of stores had between 10-50 units) but apparently, there is no shortage conspiracy.

I wonder when the next shipment is going to be? According this article they are trying to keep up with demand:

"Replenishment, replenishment, replenishment, that is the key word here," said Hufford. "We've got thousands of people working in China right now cranking out boxes. The minute they come off the line, we're boarding them up and putting them on 747s."

Monday, November 21, 2005

Pricing

There is an interesting debate going on between Joel Spolsky and Seth Goodwin about whether or not the signal that a particular price sends is a bigger factor in the recording industry wanting to have variable pricing on iTunes or whether it's just a ploy to raise the average price of downloads.

I think there is a certain element of truth to both arguments, I think the record companies do just want to take advantage of popularity to make more money at the same time I've worked at companies where we've had to raise the price of the product in order for people to believe that the quality and service a product provides is on par with alternative options.

The thing which really resonates with me is the last statement Seth makes in his post, which incidently comes from Jeff Bezos:

Which leads us to the wisdom of Jeff Bezos. There are two kinds of companies, Jeff says. Companies that work to lower prices (like Amazon, most of the time) and companies that work to raise prices (like the music industry, all of the time).

I'd like to spin that: I think there are companies that try to make money by putting the customer first and I think there are companies that try to make money by putting themselves first (and falling back on branding or ubiquity). Over the long run, which company would you rather work for and which company do you think will do better?

Composite UI Application Block (CAB)

[Update November 25, 2005 (ObjectBuilder info) - based on feedback by Edward Jezierski]

One of the things I've been playing around with lately is the Microsoft Composite UI Application Block or CAB. This is the Microsoft Pattern and Practice for developing Windows Forms Smart Client line of business applications.

According to the Microsoft documentation, the CAB has the following benefits:

  • It allows you to build clients composed of independent yet cooperating modules.
  • It separates the concerns of module builders from the concerns of the shell developer, allowing business units to concentrate on development of domain-specific modules instead of the client architecture.
  • It provides an architectural framework for producing a consistent and high quality integrated desktop development.
  • It increases productivity and reduces overall development time through consolidating architect and developer efforts.

with the overall design goals of:

  • modularity
  • productivity
  • extensibility

At the top level, the CAB has the concept of a shell and one or more loosely coupled plug-in modules.

The shell defines the layout of the application by placing Workspaces on the shell Form. Those Workspaces host SmartParts (defined below).

Each module is added to the application through the applications ProfileCatalog.xml (i.e. plug-in) and contains implementations of WorkItems (code that drives a use case including hooking up the UI to the BL and services), SmartParts (UserControls), Controllers or Presenters (to provide UI and BL decoupling), and services.

In addition, the CAB provides:

  • A module loader that loads assemblies based on configuration and processes classes that are attributed with [Service], [WorkItemExtension] and others.
  • An ObjectBuilder which uses dependency injection to build up and resolve references to instances of concrete types. The ObjectBuilder also runs developer extensible strategies during build up and tear down. For example, the EventBroker hooks up event publishers and subscribers throughout the application by running an ObjectBuilder strategy.
  • An Event Broker in which components publish and subscribe events to through attributes applied to events and to methods which act as event handlers. This allows multiple publishers to raise an event which multiple subscribers can handle (even across modules).
  • Command/UIElement infrastructure that allows modules to add/remove elements to the shell's menu, toolbar and/or status bar (or other registered UIExtension site) and associate a command and command handlers to one or more UI events.

As I mentioned before, the CAB was designed specifically for smart client line of business applications such as Online Transaction Processing front-ends or UI intensive information worker applications. With that in mind, I set out to see how the CAB would fare in a product line architecture scenario.

More specifically, how well does the CAB module concept fit the core assets concept of a product line architecture? And how well does the CAB shell and extension concepts fit the product development part of the product line architecture?

Overall, I feel the concepts align well. The CAB provides a lot of the structure and implementation required to implement a software product line architecture and certainly doesn't limit or constrain the development of core assets and products. That said, here's a couple of things to consider:

  • Think about how you are going to manage your dependencies between modules. All the great modularization of the CAB can be easily lost with an ill-advised "add reference". It may help to think of modules as independent, selectable pieces a product can choose or not choose to include in their application.
  • A core set of assemblies that all of the modules depend on is useful to define controls, types and interfaces that are shared (or provide a means of communication) across modules.
  • Think about a strategy to make it easy for products to specialize the core asset implementations. Services and the WorkItem catalog are useful for decoupling the implementation from the interface and allowing the product layer to specify which concrete implementations for an interface is used. Products will also want to specialize their own UI including branding, layout and look and feel. A factory or plug-in model implemented in the modules that the product layer can specialize will work well to solve that problem. The product development layer could also specify product specific ObjectBuilder strategies.
  • Think about the kind of work flow you may have through your application and how that could be implemented to aggregate and run different WorkItems depending on the product.
  • Make sure you have a conscious separation of product specific code and core asset code.
  • Consider the performance impact of using a reflection based dependency injection system and loading all of the modules in your application at startup (even if its only to instantiate and load ModuleInit subclasses). This is a concern I've had in the past with reflection based IOC/Dependency Injection, I wonder if there is a way to delay load modules?

finally

I've been happy with the CAB even though I'm looking to use it in a scenario that (at least on the surface) appears to be different from the main design center. If you are developing a large scale application, have a look at the CAB.

Wednesday, November 16, 2005

Chris Sell's Page of Fun

I was just looking through Chris Sell's Page of fun. A few good laughs. I especially liked:

Saturday, November 12, 2005

Windows Vista TaskBar Preview and Flip Features

I talk to a lot of people who are really curious about what some of the whiz bang features of Vista are going to be.

Here's a video, I believe this was at PDC, of a couple of the Windows Vista Aero desktop features.

It's my (second) Life

Have you ever checked out Second Life? It's a virtual world with it's own economy that allows you to buy and sell virtual goods and services, land and more. Also, as an incentive, Second Life also rewards developers who create places where people like to go and hang out.

You can use currency conversion sites to convert US$ to Linden$ (Second Life currency) or vice versa.

There are even people who make a living in our real world by having a business in a virtual world... by having a virtual job.

Its fun to reflect on how far we've come and imagine how far we will go. Will there be a day when virtual stock indexes (say the Second Life Small Cap Index) will be joined along side the S&P, Dow Jones and Nasdaq for real life investers?

Is Second Life the next big place to advertise real world products?

Friday, November 04, 2005

Get 3rd World Wages, Right Here in the US!

Amazon.com just started an intriguing new service where you can sign up to complete simple little tasks like identifying buildings in photos or choosing the best photo out of a group -- and you get paid for it. The service is called Mechanical Turk.

Of course, the title of this post is tongue in cheek but realistically, if you tried to do these tasks full time, you would probably only make between a $4-$10 an hour.

That said, I'm actually considering trying it out and making a few extra bucks from some of the funner ones where you are simply looking at photos and choosing the best one.

Thursday, November 03, 2005

Visual Studio 2005 Visual Inheritance Localization

I have now installed the release version of Visual Studio 2005 and have started doing some prototype development with it.

So far, I'm really liking the refreshed UI and the new features. Especially the editor features which make the tedious parts of coding fun -- snippets, surround with..., refactor, generate method stub...

I was working with Visio yesterday and was thinking "man, Visio needs snap lines" -- so yeah, really liking the new designer features as well.

Anyhow, I wanted to revisit the Visual Inheritance localization topic I started in a previous entry since the localization model has changed in Visual Studio 2005.

Property Reflection Resource Model
In .Net 1.1, resources were loaded from the resx file by the ResourceManager on a property by property basis:

this.Font = ((System.Drawing.Font)(resources.GetObject("$this.Font")));

In .Net 2.0, this is handled all via reflection by the ComponentResourceManager on a control by control basis:

resources.ApplyResources(this.checkBox1, "checkBox1");

Any resources in the resx file that correspond to checkBox1 are applied to checkBox1. This is different from .Net 1.1 where an entry in the resx file had to have corresponding code in InitializeComponent() in order for it to be applied.

The implication is that in order for a property on a Control to be localizable, it doesn't have to be serialized to the resx file and can be added later -- as long as the resources.ApplyResources() method is being called for that Control.

Keeping that in mind, only the properties that have been changed from their default value (as defined by the DefaultValueAttribute) are serialized into the resx file.

In the Visual Inheritance scenario, instead of the "default value", it's based on whether that property's value is different from the base value.

Initially, I was concerned when I didn't see the Font being serialized into the resx file -- I thought that the Font wouldn't be localizable, as would be the case in .Net 1.1, however a quick test showed that I could still localize the Font by adding the Font information to a culture specific resx file.

If you define your own localizable properties, you need to ensure that you are using a good localization tool and that it has access to any corresponding assemblies (on top of the resx files). By reflecting over the assemblies, the tool can find any of the custom localizable properties on your user created controls and find the type information required to populate a value for any of those properties in a resx file.

Localization and Visual Inheritance
I created a new Windows Application and put a couple of simple controls on a Form and marked their modifier property to protected.

I set the Localizable property to true in the designer and then added an inherited Form (set localizable to true for that Form as well) and added a button to it.

The InitializeComponent() method for the base Form is now:
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
this.button1 = new System.Windows.Forms.Button();
this.checkBox1 = new System.Windows.Forms.CheckBox();
this.label1 = new System.Windows.Forms.Label();
this.SuspendLayout();
//
// button1
//
resources.ApplyResources(this.button1, "button1");
this.button1.Name = "button1";
this.button1.UseVisualStyleBackColor = true;
//
// checkBox1
//
resources.ApplyResources(this.checkBox1, "checkBox1");
this.checkBox1.Name = "checkBox1";
this.checkBox1.UseVisualStyleBackColor = true;
//
// label1
//
resources.ApplyResources(this.label1, "label1");
this.label1.Name = "label1";
//
// Form1
//
resources.ApplyResources(this, "$this");
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.label1);
this.Controls.Add(this.checkBox1);
this.Controls.Add(this.button1);
this.Name = "Form1";
this.ResumeLayout(false);
this.PerformLayout();

}
And the InitializeComponent() method for the inherited Form is:
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DerivedForm));
this.button2 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// button2
//
resources.ApplyResources(this.button2, "button2");
this.button2.Name = "button2";
this.button2.UseVisualStyleBackColor = true;
//
// DerivedForm
//
resources.ApplyResources(this, "$this");
this.Controls.Add(this.button2);
this.Name = "DerivedForm";
this.Controls.SetChildIndex(this.button2, 0);
this.ResumeLayout(false);
this.PerformLayout();
}
As you can see from the ComponentResourceManager.ApplyResources() calls, resources are being applied to all of the controls defined on the base Form from the base Form's resources. In the inherited Form, resources are only being applied to "button2" which was the button that was added directly to the inherited Form.

In other words, by default, on an inherited Form, controls defined in the base Form get their resources from the base resx file.

If I modify the properties (I moved the CheckBox and changed its text on the inherited Form) of a CheckBox control from the base Form in the inherited Form, the InitializeComponent() method in the inherited Form looks like this:
private void InitializeComponent()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(DerivedForm));
this.button2 = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// checkBox1
//
resources.ApplyResources(this.checkBox1, "checkBox1");
//
// button2
//
resources.ApplyResources(this.button2, "button2");
this.button2.Name = "button2";
this.button2.UseVisualStyleBackColor = true;
//
// DerivedForm
//
resources.ApplyResources(this, "$this");
this.Controls.Add(this.button2);
this.Name = "DerivedForm";
this.Controls.SetChildIndex(this.checkBox1, 0);
this.Controls.SetChildIndex(this.label1, 0);
this.Controls.SetChildIndex(this.button2, 0);
this.ResumeLayout(false);
this.PerformLayout();
}

Note the addition of the line

resources.ApplyResources(this.checkBox1, "checkBox1");

The inherited Forms resources are now being applied to "checkBox1".

The behavior is pretty much the same as was described in my previous article on Visual Inheritance and Localization (.Net 1.1).

In other words, as mentioned in my previous post on this topic, the situation can still be very confusing to localizers who are working only with resx files since the localizable properties of a control will vary depending on what properties the developer has modified on controls in the inherited Form.

The solution is the same in the .Net 1.1 case and it involves awareness of the problem, communicating the Visual Inheritance relationships and behaviors to the localizers and deliberately modifying control properties in the inherited Form in order to get them to show up in the inherited Form's resx file.

One improvement is that once you modify any property on a control from the base Form on that inherited Form, you get the resources.ApplyResources() code added. In .Net 1.1, you had to fiddle with every property you wanted to expose to the inherited Form's resources in order to get the serialization code for that property to be added.

Finally
The new resources model in Whidbey certainly does cut down the size of the resources and the InitializeComponent() method, especially in localizable scenarios which was an issue for me in the past.

That said, the behavior with Visual Inheritence is still the same as 1.1 and is something to be aware of.

Death Star

I came across this really clever article on the Implausibility of the Death Star's Trash Compactor.

I can hear my girlfriend saying "it's just a movie, don't take the fun out of it" but one of the things about being in science and engineering is that you associate with a disproportionate number of analytical people who find this kind of stuff fun to talk about :)

Monday, October 24, 2005

TypeConverters

Recently, Chuck Jazdzewski posted an article about XAML and Type Converters. A while back, Joe Stegman wrote an article entitled "Using the Windows Forms XML Parser Sample". Both of these articles talk about and use TypeConverters outside of the Windows Forms design time experience.

I thought it'd be interesting to talk about what TypeConverters are in the more generic sense.

What is a TypeConverter?
According to MSDN TypeConverter Class documentation, the TypeConverter class:

    Provides a unified way of converting types of values to other types, as well as for accessing standard values and subproperties
    To provide a little more context, some of the key methods of the TypeConverter class include CanConvertFrom(), CanConvertTo(), ConvertFrom, and ConvertTo(). As you can see, it provides a means to convert from one type to another.

    Typically, TypeConverters are discussed in the context of Windows Forms.
    1. Converting strings typed into the Windows Forms property browser/grid to the type that the property being set requires. (typing in Red and getting the System.Drawing.Color.Red instance)
    2. Converting a type to an InstanceDescriptor so that the Windows Forms code serialization mechanism has additional information about how to generate the serialization and instantiation code for that type.
    3. Converting to and from strings when a type is serialized to a resx file
    The key functionality behind TypeConverters is that the TypeConverterAttribute is used to bind a class or property with a TypeConverter and that TypeConverter instance can be retrieved dynamically at runtime.

    For example: Suppose you want to set a property with an incoming value. If the type of the property and the type being passed in match, its simple, you simply set the property. What about if the incoming type is different from the type of the property? You could convert it, but how would you do that in a generic way for any property and incoming type?

    With TypeConverters, you can write generic code that grabs the TypeConverter that is bound to the property you are setting and use it to convert that incoming type to the type the property needs. Of course, the TypeConverter instance needs to support the conversion, and it provides the CanConvertTo() and CanConvertFrom() methods to check that before actually attempting the conversion.

    In the two articles mentioned above, TypeConverters are used to change string representations to instances of types.

    In one article its in the context of XAML, where the TypeConverter bound to a class is used to create an instance of that class from a string.

    In the other article, its in the context of Windows Forms markup language (XML to describe a Windows Forms UI) where the TypeConverter bound to a property is used to set that property from a string.

    MSDN also shows how to do parameter checking for a property that takes an enum however I feel using the Enum.IsDefined() method is a better way to handle that.

    Finally, you can also get "standard values" for a given type from a TypeConverter, for example the static instances of the Color struct (Color.Red, Color.AliceBlue etc.).

    Getting a TypeConverter
    As mentioned before, you can get a TypeConverter that is bound to a class or a property. In both cases, you want to go through a TypeDescriptor.

    For a class:

    Color c = (Color)TypeDescriptor.GetConverter(typeof(Color)).ConvertFromString("Red");
    This example shows how to get the TypeConverter for a property and also how you can set a value from any type on that property:

    The "obj" and "propName" arguments specify the instance and the property to set while the "val" argument specifies the new value for that property.
    public static void SetProperty(object obj, string propName, object val)
    {
    PropertyDescriptor prop = TypeDescriptor.GetProperties(obj.GetType())[propName];
    if (null != prop)
    {
    // Check for string type
    if (prop.PropertyType.IsAssignableFrom(val.GetType()))
    {
    // Just set the value
    prop.SetValue(obj, val);
    }
    else
    {
    // Need to do type conversion - use a type converter
    TypeConverter tc = TypeDescriptor.GetConverter(prop.PropertyType);
    object newVal = null;

    if ((null != tc) && (tc.CanConvertFrom(val.GetType())))
    {
    newVal = tc.ConvertFrom(val);
    if (null != newVal)
    {
    // Conversion worked, set value
    prop.SetValue(obj, newVal);
    }
    }
    else
    {
    string errMsg = string.Format("Cannot set property {0} on object {1} with value {2}",
    propName, obj, val);
    throw new ArgumentException(errMsg);
    }
    }
    }
    }
    Finally
    Although the majority of the interaction with TypeConverters is done in the context of the Windows Form design time, the mechanism itself is generic and powerful and can be leveraged in a number of other scenarios.

    Some other good articles on TypeConverters to look at:

    Why doesn't my TypeConverter get called?
    Introduction to the TypeConverter
    Whidbey TypeConverter Documentation

    Thursday, October 20, 2005

    Avoid Leaking from PrinterSettings (.Net 1.1)

    In .Net 1.1, it was possible for you to incur a GDI object leak when you get a Graphics instance via the PrinterSettings.CreateMeasurementGraphics() call. You would use CreateMeasurementGraphics() when you want to get printable area information in order to layout your print job relative to the current printer settings.

    In order to avoid the leak, you must dispose the Graphics instance as follows:

    Graphics pageGraphics = printerSettings.CreateMeasurementGraphics();
    DisposeGraphicsDeletingDC(pageGraphics);

    Where:

    public static void DisposeGraphicsDeletingDC(Graphics graphics)
    {
    IntPtr hDC = graphics.GetHdc();
    graphics.ReleaseHdc(hDC);
    Win32GDI.DeleteDC(hDC);
    graphics.Dispose();
    }

    Where Win32GDI.DeleteDC() is simply a wrapper around the Win32 DeleteDC() API.

    I tried exercising this in Visual Studio 2005 and lo and behold, this problem is fixed!

    Monday, October 17, 2005

    The long tail

    Have you heard of the long tail? Chris Anderson coined this term in 2004 and wrote an article about it in Wired magazine.

    There's even a blog about it.

    The concept is that in the past, due to distribution and geographical constraints, retailers could only carry products of high popularity. Where a Barnes and Noble retail outlet can only stock their 40,000 best selling books, Amazon.com can make more money off of all the other books they have for sale than they do off their top 40,000 books. That is the long tail.

    I find the concept and how our world is changing to be fascinating. If you haven't heard of it, check out the links above.

    Sunday, October 16, 2005

    My Outsourced Life

    Through Chris Sells blog, I saw an article from Esquire Magazine which was titled "My Outsourced Life". Pretty funny (scary) article about how he outsources his chores, including finishing the article he was writing to India.

    One of the companies he used, YourManInIndia, has a link to the article on their site.

    Visual Inheritance and Localization

    I was playing around with Whidbey/VS 2005 beta 2 and I couldn't get any of the Windows Forms Visual Inheritance stuff to work. I was interested in seeing how the resource handling in the Visual Inheritance scenario might be different from VS 2003.

    In VS 2003, there was an interesting behavior with the resx files and Visual Inheritance in a localization scenario (where only the resx files are handed off to the localizers). Whether or not the localizers could change the localizable properties on a derived UI depended on a given properties accessibility (public/internal/protected or private) and on whether or not that property was modified in the derived UI using the Windows Forms designer.

    Accessibility Affecting Localizability
    For controls that are marked private, which is the default accessibility when you drop a control onto a Form or UserControl in the Windows Forms designer, subclassed UIs (Forms or UserControls) cannot alter any of the properties on those controls defined in the base class.

    In the localization scenario, this means that resx changes on the base UI are propagated to any derived UIs (for example, the size and position of a controls on on the base UI will be the same as that on the derived UI).

    For example, given a simple BaseForm and DerivedForm where the only control on that form is a private button1, the DerivedForm's InitializeComponent() is as follows (abbreviated):

    private void InitializeComponent()
    {
    System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(DerivedForm));
    //
    // DerivedForm
    //
    this.AutoScaleBaseSize = ((System.Drawing.Size)(resources.GetObject("$this.AutoScaleBaseSize")));
    this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage")));
    this.ClientSize = ((System.Drawing.Size)(resources.GetObject("$this.ClientSize")));
    this.Font = ((System.Drawing.Font)(resources.GetObject("$this.Font")));
    this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
    this.Location = ((System.Drawing.Point)(resources.GetObject("$this.Location")));
    this.MaximumSize = ((System.Drawing.Size)(resources.GetObject("$this.MaximumSize")));
    this.MinimumSize = ((System.Drawing.Size)(resources.GetObject("$this.MinimumSize")));
    this.Name = "DerivedForm";
    this.StartPosition = ((System.Windows.Forms.FormStartPosition)(resources.GetObject("$this.StartPosition")));
    this.Text = resources.GetString("$this.Text");
    ..
    }

    Notice that there aren't any properties being loaded from the resx file for the private button1. That means that the localizers don't have any control over that button in the DerivedForm.

    Since marking button1 as private means that only the base class UI can access that member, this behavior is expected.

    At least for a developer it's obvious. That said, many localizers are not developers and the lack of context or knowledge can be a source of confusion. But wait! There's more...

    Overriding Control Properties in resx Files for a Derived UI
    A slightly more interesting scenario is the one where a control is marked in such a way that the subclassed UI can override that controls properties (public, protected and in some cases internal). The behavior can actually vary.

    For example, suppose I have a simple base class as follows (code abbreviated):

    public class Form1 : System.Windows.Forms.Form
    {
    protected System.Windows.Forms.Button button1;
    private System.ComponentModel.Container components = null;

    public Form1()
    {
    InitializeComponent();
    }

    #region Windows Form Designer generated code

    private void InitializeComponent()
    {
    System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form1));
    this.button1 = new System.Windows.Forms.Button();
    this.SuspendLayout();
    //
    // button1
    //
    this.button1.Font = ((System.Drawing.Font)(resources.GetObject("button1.Font")));
    this.button1.Location = ((System.Drawing.Point)(resources.GetObject("button1.Location")));
    this.button1.Name ="button1";
    this.button1.Size = ((System.Drawing.Size)(resources.GetObject("button1.Size")));
    //
    // Form1
    //
    this.Controls.Add(this.radioButton1);
    this.Controls.Add(this.label1);
    this.Controls.Add(this.button1);
    this.Font = ((System.Drawing.Font)(resources.GetObject("$this.Font")));
    this.ResumeLayout(false);
    }
    #endregion
    }


    If I create a derived Form from the above code, I get the following:

    public class DerivedForm : VisualInheritanceTest.Form1
    {
    private System.ComponentModel.IContainer components = null;
    public DerivedForm()
    {
    InitializeComponent();
    }

    #region Designer generated code
    private void InitializeComponent()
    {
    System.Resources.ResourceManager resources = new
    System.Resources.ResourceManager(typeof(DerivedForm));
    this.SuspendLayout();
    //
    // button1
    //
    this.button1.Name = "button1";
    //
    // DerivedForm
    //
    this.Font = ((System.Drawing.Font)(resources.GetObject("$this.Font")));
    this.Location = ((System.Drawing.Point)(resources.GetObject("$this.Location")));
    this.ResumeLayout(false);
    }
    #endregion
    }

    The key thing to notice is that in the derived class, by default, the InitializeComponent() method does not have any code to load the button1 properties from the derived class' resx file.

    This prevents the localizers from being able to modify button1 independently of the base UI. In other words, by default, modifying the properties in the resx for the base UI will affect all of the derived UIs.

    Suppose the developer were to modify the size and location of button1 in the derived UI using the Windows Forms designer. This causes the forms designer to generate code in the derived class' InitializeComponent() method to load the size and location of button1 from the resx file.

    New code after modifying the size and position of button1:

    //
    // button1
    //
    this.button1.Location = ((System.Drawing.Point)(resources.GetObject("button1.Location")));
    this.button1.Size = ((System.Drawing.Size)(resources.GetObject("button1.Size")));

    Now the derived class' resources would be used to determine the size and location of those controls and changing button1's properties in the base UI resources will no longer affect the derived UI.

    In other words:

    • If the developer hadn't modified a property of a given control in the WinForms designer on the derived UI then that property would not be changeable from the subclassed UI's resources and would be inherited from the base UI resources
    • If the developer had modified a property of a given control on the derived UI then it would be changeable from that subclassed UI's resources and changing the base UI resources would not have an effect on any derived UIs.
    The result is that from a localizer's point of view, changing a property in the base UI may or may not affect the derived UI and changing a property on a control in the derived UI may or may not be possible.

    Because many localizers aren't developers, this behavior can seem to be very inconsistent and hard to work with.

    Finally
    In order to resolve this problem, it's important for the developers to provide context and information to the localizers on where Visual Inheritance is used. Additionally, for subclassed UIs with controls whose properties are overridable, it would be good to adopt some kind of convention or add consistency to make the localizers job easier.

    In the past, I solved this by ensuring that all of the control properties on a subclassed UI were overridable in the derived UIs resources. Although this caused a bit more work in situations where a common property needed to be updated in the base UI and all derived UIs, giving the localizers control and consistency was more important.

    It'll be interesting to see how Whidbey addresses this, the changes to the localization model will probably alter this behavior. In a mere few weeks I'll have the released Visual Studio 2005 installed and I'll blog about how the Visual Inheritance and Localization behavior has changed.

    Thursday, October 13, 2005

    Resources and Performance

    Recently, David Gutierrez blogged about some Performance tips for using resources on the BCL team blog.

    He focuses on ways to prevent the ResourceManager from probing for language or culture specific resources that aren't installed in order to improve the load time performance for resource assemblies. The two techniques he cites are the NeutralResourcesLanguageAttribute and specifying the installed cultures in your application config file. These both work in .Net 1.X and 2.0.

    This reminds me of another resource performance issue which is common in localized Windows Forms applications -- the unnecessary loading of property values from the resx file.

    Resources in the .Net Framework 1.1
    For example, if I create a new Form and set its design time Localizable property to true, I get the following in the InitializeComponent() method:

    private void InitializeComponent()
    {
    System.Resources.ResourceManager resources = new System.Resources.ResourceManager(typeof(Form2));
    this.button1 = new System.Windows.Forms.Button();
    this.SuspendLayout();
    //
    // button1
    //
    this.button1.AccessibleDescription = resources.GetString("button1.AccessibleDescription");
    this.button1.AccessibleName = resources.GetString("button1.AccessibleName");
    this.button1.Anchor = ((System.Windows.Forms.AnchorStyles)(resources.GetObject("button1.Anchor")));
    this.button1.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("button1.BackgroundImage")));
    this.button1.Dock = ((System.Windows.Forms.DockStyle)(resources.GetObject("button1.Dock")));
    this.button1.Enabled = ((bool)(resources.GetObject("button1.Enabled")));
    this.button1.FlatStyle = ((System.Windows.Forms.FlatStyle)(resources.GetObject("button1.FlatStyle")));
    this.button1.Font = ((System.Drawing.Font)(resources.GetObject("button1.Font")));
    this.button1.Image = ((System.Drawing.Image)(resources.GetObject("button1.Image")));
    this.button1.ImageAlign = ((System.Drawing.ContentAlignment)(resources.GetObject("button1.ImageAlign")));
    this.button1.ImageIndex = ((int)(resources.GetObject("button1.ImageIndex")));
    this.button1.ImeMode = ((System.Windows.Forms.ImeMode)(resources.GetObject("button1.ImeMode")));
    this.button1.Location = ((System.Drawing.Point)(resources.GetObject("button1.Location")));
    this.button1.Name = "button1";
    this.button1.RightToLeft = ((System.Windows.Forms.RightToLeft)(resources.GetObject("button1.RightToLeft")));
    this.button1.Size = ((System.Drawing.Size)(resources.GetObject("button1.Size")));
    this.button1.TabIndex = ((int)(resources.GetObject("button1.TabIndex")));
    this.button1.Text = resources.GetString("button1.Text");
    this.button1.TextAlign = ((System.Drawing.ContentAlignment)(resources.GetObject("button1.TextAlign")));
    this.button1.Visible = ((bool)(resources.GetObject("button1.Visible")));
    //
    // Form2
    //
    this.AccessibleDescription = resources.GetString("$this.AccessibleDescription");
    this.AccessibleName = resources.GetString("$this.AccessibleName");
    this.AutoScaleBaseSize = ((System.Drawing.Size)(resources.GetObject("$this.AutoScaleBaseSize")));
    this.AutoScroll = ((bool)(resources.GetObject("$this.AutoScroll")));
    this.AutoScrollMargin = ((System.Drawing.Size)(resources.GetObject("$this.AutoScrollMargin")));
    this.AutoScrollMinSize = ((System.Drawing.Size)(resources.GetObject("$this.AutoScrollMinSize")));
    this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage")));
    this.ClientSize = ((System.Drawing.Size)(resources.GetObject("$this.ClientSize")));
    this.Controls.Add(this.button1);
    this.Enabled = ((bool)(resources.GetObject("$this.Enabled")));
    this.Font = ((System.Drawing.Font)(resources.GetObject("$this.Font")));
    this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
    this.ImeMode = ((System.Windows.Forms.ImeMode)(resources.GetObject("$this.ImeMode")));
    this.Location = ((System.Drawing.Point)(resources.GetObject("$this.Location")));
    this.MaximumSize = ((System.Drawing.Size)(resources.GetObject("$this.MaximumSize")));
    this.MinimumSize = ((System.Drawing.Size)(resources.GetObject("$this.MinimumSize")));
    this.Name = "Form2";
    this.RightToLeft = ((System.Windows.Forms.RightToLeft)(resources.GetObject("$this.RightToLeft")));
    this.StartPosition = ((System.Windows.Forms.FormStartPosition)(resources.GetObject("$this.StartPosition")));
    this.Text = resources.GetString("$this.Text");
    this.ResumeLayout(false);
    }

    You have to ask yourself if all of these properties really need to be localized. For example:
    • AutoScroll
    • AutoScrollMinSize
    • AutoScrollMargin
    • Enabled
    • Anchor
    • Dock

    Chances are, you won't be changing those values on a per language basis. Having those values in the resources have a performance cost and a size cost. The size may seem inconsequential but if you have a scenario where you are translating to 21 or more languages, the size can be a factor very quickly since the resources get multiplied by the number of languages.

    As it turns out, there is an article on WindowsForms.Net that addresses this issue. It's called Improving Performance of Localized Forms by Brian Pepin.

    He solves the problem through a Localization Filter component which is dropped in the designer for any UIs in which you want to filter out the extra localized properties. It's a very interesting article that also shows how to use many of the Windows Forms technologies like designers, code serialization and TypeDescriptors.

    It certainly does the job, however I wanted to discuss an alternate approach which gives the same result and may be more suitable for your situation.

    The approach is to subclass all of the controls and apply the Localizable(false) attribute to the properties which you don't want to show up in the resx file. For example:

    public class Button : System.Windows.Forms.Button
    {
    [Localizable(false)]
    public new string
    AccessibleDescription
    {
    get { return base.AccessibleDescription; }
    set
    { base.AccessibleDescription = value; }
    }

    [Localizable(false)]
    public
    new string AccessibleName
    {
    get { return base.AccessibleName; }
    set { base.AccessibleName = value; }
    }
    ...
    }


    Note that the "new" keyword needs to be used because those properties are not virtual.

    By subclassing all of the .Net Windows Forms provided controls including UserControl and Control, and having all user defined controls derive from those subclasses, you can remove all of the the extraneous properties from your resx files.

    .Net Framework 2.0

    Raghavendra Prabhu from the .Net Client Team talks about the changes to the resource model in Whidbey here. Note that the issues above are specifically addressed by the new PropertyReflection localization model in Visual Studio 2005.

    The use of reflection to get around the problem is interesting since it is inherently slower on a per property basis.

    Both models are supported for backwards compatibility reasons.

    Finally

    As we move forward in the Visual Studio 2005 era, its good to know the history behind how some of the technologies have evolved.

    For resources, if you are working with Visual Studio 2003, you have a couple of different options for optimizing the size and performance of your resources. In Visual Studio 2005, you have a new localization model which will help with the resource size issue and hopefully also have benefits on the performance side.

    Tuesday, October 11, 2005

    .Net Book Recommendations

    Brad Abrams posted a list of book recommendations on his blog. I haven't read all of those books but of the ones I have read, I definetly agree with these:

    These are all very good books.

    Quite often, I get asked what books someone should read in order to learn Windows Forms. I always say that in order to be really effective developing Windows applications using the .Net Framework, you need to know 5 things:

    1. CLR
    2. C#
    3. Windows Forms
    4. GDI+ (in the .Net context)
    5. Interoperability

    In that order.

    I prefer C# but you can substitute your language of choice. For me, C# has a syntax that is very natural for a C++ programmer yet provides a simplicity that makes it easy to learn and highly productive.

    So if I were to point someone to 5 books that covers the 5 topics above, they would be:

    1. Applied Microsoft .Net Framework Programming (CLR)
    2. Programming C#
    3. Windows Forms Programming in C#
    4. Graphics Programming with GDI+
    5. .NET and COM: The Complete Interoperability Guide

    To me, the C# book is less important since Jeff Richter's Applied Microsoft .Net Framework Programming will give you the majority of what you need to know. I might substitute more of a C# reference book like The C# Programming Language.

    If you are building a lot of foundation or shared libraries, then Framework Design Guidelines : Conventions, Idioms, and Patterns for Reusable .NET Libraries is a must read.

    Once you have all of these books under your belt, it's all a matter of getting experience with the platform. Coding early helps make more sense of the books you are reading so try not to be too methodical :)

    Visual Studio 2005 is about a month away, I can't wait to dig in to some new books that cover all of the .Net Framework 2.0 features and changes.

    Monday, October 10, 2005

    So happy together

    Mike Henderlight is blogging about Windows Forms and Avalon (Windows Presentation Foundation) interoperability.

    Tons of good information there about hosting Avalon content in a Windows Form, launching an Avalon Window from a Windows Forms app, describing Windows Forms Controls in XAML and more.

    Run, don't walk...

    Tuesday, October 04, 2005

    UI Designers Implementing UI

    In my last post entitled "Battle of the Windows Presentation Technologies", I mentioned that a lot of companies want to get their developers out of the UI implementation business and put it in the hands of the domain experts -- UI designers.

    Instead of having a developer translate screen shots from the designer into a Windows UI, wouldn't it be ideal if the designers themselves could create a UI that the developers could consume and code behind?

    Why can't a designer just use Visual Studio and the Windows Forms designer?
    Because the Windows Forms designer is code centric. Making changes using the Windows Forms designer means making changes to the code and the type of knowledge required to build up a UI in the Windows Forms designer requires the skill set of a developer, not a designer.

    One of the reasons is that the code is readily accessible to anyone using the WinForms designer and in fact, the WinForms designer flows between the code and the design surface regularly. Even though the WinForms designer is graphical, it provides a representation of code and not a rich interactive design experience.

    Another reason is that the paradigm for the WinForms designer is nothing like the kinds of tools that designers have developed their skills in. Different users require different tools.

    What kinds of tools could a designer use to create a UI?
    With Avalon and XAML, it becomes possible to develop a UI in applications other than Visual Studio and then consume it programmatically. The power of XAML is that tools can produce and consume it very easily.

    One such tool is Sparkle or the Microsoft Expression "Sparkle Interactive Designer". This tool can be used to create a UI that includes animations, graphics, can define and control the layout and more.
    "Now, designers can create the full application interface and hand it over to the developer to work with directly," said a Microsoft spokesman. "Previously, developers would receive a mock-up of the application and then work to try to recreate the designer's intent. Now, the designer becomes part of the development process directly.

    Another quote, here, gives more insight:


    This is a tool for UI / UX designers - it is specifically made for "us" - because as John and I say in the video: there was *no* tool to allow designers to make *real* UI and be a part of a client app team...Just like VS is a dashboard on top of Avalon, with tons of tools that are made for devs, Sparkle is a "steering wheel" - only with different set of tools... Devs *can* use it and will enjoy it HOWEVER many of the tools behave in ways designers expect - which can differ from what devs expect.VS will also have its own set of Avalon tools (including a design surface) sometime in the future... It was shown today and it is called Cider. This is where devs specifically will say "aaaahh myyy tool" See different users really mean different tools. But again, devs will have fun exploring the WPF/Avalon platform thru Sparkle as well.


    A key point is that the equivalent Avalon tool to the WinForms designer is Cider -- a developer tool for Avalon. (just like the WinForms designer is not a tool for designers

    Ultimately, there is going to be a full suite of tools out there that can export to XAML. Designers will be able to create UIs in whatever tools they feel comfortable. For example, check out ZAM3D, which is a tool that enables you to take 3D models and export them to XAML.

    So how does it work?
    Essentially, a designer develops a UI that consists mainly of XAML, although it is possible that it will have code as well. (tool generated code)

    In the case of Sparkle, Sparkle will output both XAML and code and uses the same build environment (MSBUILD) as Visual Studio to allow seamless workflow integration between the designer and the developer.

    There is a good video here showing Sparkle and the designer experience. The designer has a palette of controls and can build up a UI by putting those controls on a design surface. The designer then has the ability to override the look and feel completely, including changing how the control is rendered and adding animations for events.

    For example: in the video a radio button control is modified to be a 3D widget that springs out at the user when it is the selected button. The new look and feel as well as the animated behavior is accomplished completely in XAML.

    Will we really be able to move the UI implementation to a designer?
    Having a UI designer act as an implementer is a departure from the current development model and there will need to be adjustments in the minds of the developers and in the skill sets of the designers.

    Some people I've talked to question whether or not the generated XAML will be acceptable to use as is. Although I agree there will need to be tweaking and the integration to the code behind will require extending the generated XAML, I am going to put a stake in the ground and say that I believe that in the future, this new model will become a reality.

    Windows Forms has shown that generated code is a reality. I'll admit in .Net 1.1 there were design time issues with controls disappearing or moving that were really frustrating -- but I managed to build a very large scale application where almost all of the UI was built in the Windows Forms designer. And that was .Net 1.1, .Net 2.0 has fixed those bugs and has also added new controls that create a professional UI with fewer lines of code.

    Flash UIs has shown that designers can create a clickable, animated UI without needing developers.

    When you couple those two data points with the well structured programming model in Avalon, its just a matter of time before the UI designer becomes a part of the development process.

    Finally
    As cool as all the DirectX, multimedia, 3D, and translucent features of Avalon are, in the business and productivity application space, one of the more compelling reasons to move to Avalon is for the change in the UI development model.

    I'm particularly excited to see and use the next generation of UIs that will enable much richer and more usable experiences.

    In closing, there is another channel9 video here showing off Avalon features.

    Monday, October 03, 2005

    Battle of the Windows Presentation Technologies

    Since the Windows Presentation Foundation (Avalon) will be available on XP, one of the things I hear people struggle with is the decision of whether or not to use Avalon or Windows Forms for their presentation layer given that they plan to ship their product in a time frame later than Windows Vista and WinFX.

    It's pretty clear that longer term, say in the 10 year time frame, that Avalon will be the dominant presentation technology but over the next few years, things are a bit more gray.

    In fact, there has been a lot of blog activity with regards to Windows Forms vs. Avalon. Some of these articles are getting dated but here are some summaries of what is out there:

    Mike Harsh asks "Is Windows Forms Dead?"


    • Asserts that Whidbey will be the last full featured version of Windows Forms.
    • Windows Forms is hitting the ceiling on what Win32 can accomplish
    • The Windows Forms team is focusing more on infrastructure that is independent of the presentation technology (i.e. ClickOnce and configuration)
    • Worth investing in Windows Forms today and next year since VS.Net 2003 and VS.Net 2005 are the most efficient ways to build Windows applications in that time frame
    • Worth investing in Windows Forms in 2 years? Judgment call, if you only need to support XP and Vista, then Avalon is the way to go.
    • Simple to integrate Windows Forms with Avalon controls
    • Because of the Windows Forms support for Avalon and Avalon support for Windows Forms, there isn't going to be a need to rewrite a Windows Forms UI in Avalon -- can make incremental changes.

    My take:

    I'd be a little disappointed if Whidbey was the last full featured version of Windows Forms. I think that similar to the new ToolStrip controls that there can be a lot of work done to provide richer controls.

    Although Avalon brings a lot of capabilities around whiz bang type UIs by utilizing DirectX, one of the main reasons I hear people want to move to Avalon is to change the UI development model. (think business and productivity apps where video backgrounds and 3D don't have a value proposition) A lot of companies want to get the developers out of the UI implementation business and put it in the hands of the experts in that area -- UI Designers.

    In other words, the key to XAML is the tools that support it. As Don Box indicates here, he believes that the number of people who will create and edit XAML using a text editor will be statistically zero.

    If getting developers out of the UI implementation business is what you want to do then you want to consider how the tools available will support building your UI in the time frame you need. Additionally, you need to think about how the Windows Forms to Avalon transition will map to your UI development model changes.

    Dan Appleman "Windows Forms to Developers: I'm not dead yet"

    • Because Windows Forms wraps the Win32 API, it has much less of a learning curve than Avalon since every Windows developer in the world is familiar with the Win32 API. Do the features Avalon promise justify learning the new Avalon API?
    • Believes the transition to Longhorn/Avalon will be slow as there is no compelling economic advantage.
    • Windows Forms suffers the .Net distribution issue and Avalon will suffer that as well as limited OS support

    My take:

    I believe the API is secondary, developers love learning new things... at least the architects and tech leads that get to decide which technologies to use do. Changing the development model to have UI implementers will also play a role in the adoption of Avalon.

    Ultimately, the features and declarative programming model in Avalon need to justify, not only learning the new API but also the Windows OS value proposition. As AJAX and DHTML start coming close to the power of Win32, the Windows presentation layer has to raise the bar.

    The question is: when will Avalon be able to raise that bar while also having the productivity that Windows Forms has for building business and productivity applications?

    More on XP vs. Longhorn discussion

    • Can Avalon run on XP?
    • LDDM (Longhorn Device Driver model) different from XPDM, concerns about the stability of the DirectX drivers under the XPDM. These drivers were written for gaming, not for the everyday use on the desktop.
    • Inability to tweak User32 on XP. Won't be able to treat legacy content (i.e. Win32) the same way as Avalon content like you will be able to on Longhorn
    • Terminal Services and Remote Desktop - planned on handling that differently with Avalon.
    • Avalon was relying on the Longhorn Media decoding system. May not be available on XP.
    • Desktop window manager will be available on Longhorn only

    My take:

    This article is slightly off topic but it highlights the point that you need to ensure that if you plan to use Avalon on XP that you do your homework with regards to where it doesn't work the same as Longhorn. Windows Forms will be consistent across those platforms...

    Another thing to consider is what the Avalon minimum system requirements will be. I don't believe Microsoft has announced this yet but the beta 1 requirements are 512 MB RAM and a DirectX 9.0 compatible graphics card. XP shipped in 2001 and the majority of those machines will not fulfill those requirements. In other words, if you are considering on using Avalon, you better understand what is meant by your "Windows XP support" product requirement.

    Put another way: just because Avalon supports XP doesn't mean you can use
    Avalon to support all of your XP customers.

    Mike Henderlight asks "Can't We All Just Get Along?"

    • Avalon/Windows Forms interoperability should be viewed more as a co-existence strategy and not a migration strategy (i.e. there won't be a Windows Forms to Avalon converter in the future)
    • little parallel to the chasm of VB6 to VB.Net, Windows Forms and Avalon will support having assets from both technologies in the same executable
    • Two message loops, one for Avalon, one for Windows Forms will bring challenges
    • Goal is to support: Avalon controls on Windows Forms, launching an Avalon window from a Windows Forms app, and Avalon apps that can host Windows Forms controls

    My take:

    I'm really excited about the high level of support for interoperability between Avalon and Windows Forms and I really see Windows Forms as the technology of today and the bridge to the technology of tomorrow.

    To me, that is one of the main reasons to continue with Windows Forms development now and then switch over to Avalon when the technology matures and the tools become available.

    Of course, for completeness, I have to mention that the Windows Forms/Avalon interop scenario doesn't support the "UI designer implements the UI" model. You can have a hybrid model though and that can act as a bridge for the UI development process.

    Conclusion

    Ultimately, whether or not to use Windows Forms or Avalon will depend on your situation, when you plan to ship your product and your tolerance for risk.

    That said, the key criteria to consider when making a choice between the two are:

    • Level of OS and hardware support required
    • Tools available for building the type of UI you need
    • Tolerance for v1 technologies
    • Tolerance for shipping an additional redistributable on top of the .net Framework (WinFX)
    • Avalon value proposition - DirectX based, declarative UI...
    • Ship date for your application
    • Skill sets of the developers

    It's important to consider that Windows Forms is proven, there are large scale applications localized to 21+ languages out there using Windows Forms. For Example: Here's a case study of a large Windows Forms suite of applications that HP shipped in 21 languages.

    Windows Forms will support 98 through Vista and provides a highly productive development environment. I feel it still has room to evolve as a framework and I hope Microsoft does too.

    There is first class support for Avalon on Windows Forms and Windows Forms on Avalon so you can rest assured that your investment in Windows Forms will not be wasted.

    My conclusion is that for most applications, Avalon will not provide enough value proposition to overcome the OS and hardware requirements, lack of tool support and risk with a v1 technology for the next 2-4 years.

    Avalon is the future, there is no doubt, develop in Windows Forms now and use it to be your bridge to Avalon.

    Monday, September 26, 2005

    XmlSerializer Performance Issue

    Ever notice that making a call to new a System.Xml.Serialization.XmlSerializer is really slow?

    As it turns out, the XmlSerializer constructor is slow since it creates the serialization and deserialization code and compiles it into a temporary assembly at runtime. This occurs for each type that is passed in as a parameter to the XmlSerializer constructor.

    On older machines or machines where the performance is I/O bound, the time it takes for the constructor call balloons very quickly. I’ve seen it take as long as 8 seconds.

    The fact is that in the majority of cases, you will not need to have this functionality at runtime since the binding of the object graph and the XML will be known at compile time.

    Workaround in the .Net Framework 1.0 and 1.1
    In .Net 1.0 and 1.1, you could workaround this issue by capturing the generated code in a test run, write an XmlSerializer subclass and use that instead.

    In order to capture the XmlSerializer generated code, you need to set a diagnostic switch in the application config file of the app:

    <?xml version="1.0"?>
    <configuration>
    <runtime>
    <gcConcurrent enabled="true" />
    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
    <publisherPolicy apply="yes" />
    <probing privatePath="bin\debug" />
    </assemblyBinding>
    </runtime>
    <system.diagnostics>
    <switches>
    <add name="XmlSerialization.Compilation" value="4"/>
    </switches>
    </system.diagnostics>
    </configuration>

    After performing a test run with this app config file, the generated code can be found in the temp folder. Now that you have that code, you need to write a subclass of the XmlSerializer that looks something like this (the actual names of the methods and classes are generated and are subject to change):

    public class MySerializer : XmlSerializer
    {
    public MySerializer()
    {
    }

    protected override XmlSerializationReader CreateReader()
    {
    return new XmlSerializationReader1();
    }

    protected override XmlSerializationWriter CreateWriter()
    {
    return new XmlSerializationWriter1 ();
    }

    public override Boolean CanDeserialize(XmlReader xmlReader)
    {
    return true;
    }

    protected override void Serialize(Object objectToSerialize, XmlSerializationWriter writer)
    {
    ((XmlSerializationWriter1)writer).Write4_Options(objectToSerialize);
    }

    protected override System.Object Deserialize(XmlSerializationReader reader)
    {
    return ((XmlSerializationReader1)reader).Read5_Options();
    }
    }

    Given that you’ve added the class above and the generated code to your project, the last thing that remains is to change your instantiation of the XmlSerializer:

    From:
    XmlSerializer serializer = new XmlSerializer(typeof(Options));

    To:
    XmlSerializer serializer = new MySerializer();

    The MySerializer() constructor is empty so it takes 0 time. All the time spent instantiating the XmlSerializer is eliminated.

    The other nice thing about this is that you can look at the generated code to see how the serialization/deserialization code is implemented.

    The downside is that you need to ensure that you keep the generated code and the code for the class being serialized in sync. You may want to wait until your code stabilizes before switching to the captured code.

    sGen in the .Net Framework 2.0
    In the .Net Framework 2.0 (Whidbey), there is a new command line tool called sGen that is also accessible from the Visual Studio 2005 IDE in the Build project settings as “Generate serialization assembly”.

    Essentially, this automates the list of steps above and creates a corresponding AssemblyName.XmlSerializers.dll where "AssemblyName" corresponds to the name of the assembly that uses the XmlSerializers.

    When the XmlSerializer constructor is called, the .Net Framework will look for a corresponding *.XmlSerializers.dll assembly and to load the statically generated serializers.

    Its important to realize that this is happening because if you forget to deploy your *.XmlSerializers.dll files, your deployed application will have far worse performance than what you are seeing on your development machines – and if you don’t know about this mechanism, it’ll be hard to figure out why that is.

    Thursday, September 22, 2005

    PDC: Profile Guided Optimizations (POGO)



    One of the more interesting technologies that is coming out in the Whidbey time frame actually has nothing to do with the .Net Framework or managed code.

    Visual C++ in Visual Studio 2005 has a new Profile Guided Optimizations technology or POGO for short. As a very rough number, there is typically an 8-18% performance improvement with a POGO optimized scenario.

    POGO optimization is different from previous optimizations in Visual C++ in that data from test runs is collected and used to make smarter choices on how to optimize the code. For example, runtime data can be used to understand what code paths are expected and which are exceptional and the final link can optimize the code for the expected code paths.

    When creating a POGO optimized image, data test runs are used to apply additional optimizations such as intelligent inlining, virtual call speculation, register allocation and code locality. A full list of the optimizations with explanations is available here and there is a POGO walkthrough here.

    Because I am mainly a managed code developer, one of the ways I imagine using POGO is to optimize sections of code that require a high level of performance and are therefore written in unmanaged C++ and invoked from my managed code via interoperability.

    Additionally, I have a number of applications that are written in unmanaged code that can benefit from this technology.

    Finally, from what I understand MS Office and Windows NT both use this technology to improve the performance of their software. The implications are that POGO is both reliable and compatible.

    Sunday, September 18, 2005

    PDC: Vista LUA



    One of the things I got to do at the PDC was attend a Vista compatibility testing session with someone from Microsoft. I had a number of features break in my application and they all centered around LUA. It was a very eye opening experience and definitely worth the time.

    Least-privilege User Account (LUA) (sometimes known as User Account Protection or UAP) is a new feature in Vista that is intended to help prevent some of the issues we've seen in the past with Viruses/Spyware/malware taking advantage of users that run with administrator privileges.

    Keep in mind that the information below was based on the build of Vista they had available at the PDC. I'm sure much of it is subject to change.

    LUA
    With LUA, any group membership permissions are stripped away and all the users on the system (except for the built in administrator account) run with standard user privileges. Instead of the group membership (i.e. administrators group) determining what your access privileges are, the group membership determines your "elevation potential".

    For example, in order to perform an action that requires administrator privileges, like installing an application, Vista will prompt the user once per process (at the start) to elevate the privileges for that user. Whether Vista will prompt, prompt with request for credentials (i.e. password) or elevate silently is controlled by the security policy setting in: Local Security Settings->Local Policies->Security Options

    Any programmatic queries to determine the user permissions will return the standard user token unless that user's permissions have already been elevated. We may see an API that can determine a user's elevation potential.

    Access rights elevation, can only be performed when an application starts and will be based on heuristics (for backwards compatibility support) or an application manifest.

    Application manifests allow an application to be marked with 1 of 3 LUA settings.
    • "Invoker", which is the default and simply gets the parent token.
    • "Highest" prompts for the highest permissions a particular user has. Apps that are marked with "highest" may have different behaviors based on the user's permissions. For example, regedit could still run without administrator rights but only provide read-only access to HKLM.
    • "Requires Admin" means that a particular application will only run if the user can be elevated to and accepts administrator rights.

    If you have a scenario where your application does not usually require elevated access rights but certain functions within that app does (like update), you can launch a separate process that requires those rights. It's important to note that by default, an application will get the same privileges as the parent process.

    For this reason, Microsoft is not recommending that you launch an application right after an installation is complete -- since the installer will need elevated privileges, the child process will also get them. They are considering a new API to allow a developer to launch a process with LUA.

    Workarounds
    For legacy applications (no LUA manifest entry) that require administrator rights the shell supports right-clicking on an application and choosing the "run elevated" menu item. This will prompt for elevation consent and run the application with elevated permissions.

    MS indicated that if you work with them, legacy exe's can be marked by the OS as requiring elevated privileges. This is purely to preserve backwards compatibility.

    For situations where you cannot right click on the application to run it, the add/remove programs uninstaller for example, you can take advantage of the fact that child processes get their security token from their parent process.

    For the add/remove programs case, you can run the command prompt with elevated privileges and launch appwiz.cpl to bring up the add/remove programs wizard with the permissions you require.

    Access to HKLM, and the program files directory when insufficient privileges are available do not fail but are virtualized on a per user basis. Exe, dll and other binary files are not virtualized.

    Finally
    I've seen my share of spyware on family and friends machines so I'm quite happy to hear about this feature, I think it will help a lot.

    The things I worry about with LUA is that the prompts for elevated access rights will become annoying and/or that those prompts will lose their effectiveness when users start to blindly accept the elevation.

    That said, anything that will help keep our machines more secure is a good thing. As Bill Gates stated in his PDC keynote, Vista is about confident, clear and connected experiences. LUA addresses the "confident"/safe part of that equation.

    Saturday, September 17, 2005

    PDC: Shared Bytes, Private Bytes and Fixups



    I attended both of Rico Mariani's CLR performance talks and I thought they were great. Actually, my biggest complaint was that they were both only 45 minutes long. I left wanting more...

    One of the things he talked about a lot was private bytes, shared bytes and fixups. He went over them in his presentation but I needed to catch up with him to ensure that I was getting the whole picture. Here is what I found:

    Shared Bytes vs Private Bytes
    A shared byte is one that can be shared across multiple processes. A private byte cannot. So what bytes qualify as shareable? Unaltered pages of a dll where the backing file for that dll is not the page file but the dll itself.

    Anytime a page of code or data from a dll needs to change for a particular process, it is marked dirty and becomes private. This can occur on pages that have references to objects on the heap, pages that have code offsets that get modified after load time, or on pages in the data segment that change.

    A quick way to have almost all of your dll marked private is to have it rebased during load time.

    This concept mainly applies to NGEN'd images as non-NGEN'd images mainly consist of IL that will be JIT compiled on the loader heap and therefore will all be private. The IL is shared, but it is discarded after JIT anyhow.

    It's important to realize that the benefit of shared bytes are just that: that they can be shared across multiple processes and their cost can be amortized across the number of processes using those bytes. For assemblies like the .Net Framework assemblies, having shared bytes is a clear benefit. That said, in non-sharing cases, optimizing for shared bytes may sub-optimize your code so caveat emptor.

    Fixups
    The term "fixups" refers to "fixing up" an address in the code to a new address. Since this modifies a page for a given process, any page that has a fixup, also becomes private.

    Reducing Private Bytes
    The following are some ways you can reduce the number of private bytes:
    • put code that will be private together such that the number of pages that need to be marked private is decreased
    • prevent rebasing
    • fix addresses so that they don't become a fixup

    String Freezing and Hard Binding
    String Freezing and Hard Binding are both great examples of how the concepts above are being applied.

    In .Net 2.0, you can mark an assembly such that it will freeze its string literals. What that means is that all of the strings in that assembly will be put in a separate segment (during NGEN) so that all of the references to string literals will not require a fixup.

    The reason strings need fixups is because the literals need to be wrapped in a string instance and the code then points to those instances.

    With string freezing, there is a benefit in that the string isn't duplicated in the literal and the string instance as well as the reduction in private pages. Note as well that those string instances are interned (with opt in/opt out in whibey see the article here) to avoid duplication.

    The downside of string freezing is that such an assembly cannot be unloaded -- because the reference to that string now resides in a segment of that dll instead of on the heap and code in other assemblies may be depending on that reference.

    Hard binding refers to another new NGEN feature where NGEN assumes that a reference from one assembly to another is always going to be there. That allows NGEN to hard code offsets from one assembly to another reducing the need for load time fixups.

    The downside is that any assemblies that are hard bound will be loaded at the same time as the referencing assembly. This is in order to guarantee that the desired load addresses are gotten.

    Finally
    One of the things Rico mentioned in his talk at the PDC, was that there have been a lot of improvements in the area of shared bytes and working set in Whidbey. That will be really helpful for the performance of your .Net applications.

    Looking forward to Whidbey. Thanks Rico for taking the time to explain this to me.

    i-mate Stalemate - Support Code:85010014



    One of the things I omitted from my entry on Jim Allchin's keynote was the fact that he showed an i-mate Jasjar PocketPC/Phone which runs Windows Mobile 5.0. The devices sell for around $1000 or so but he announced that a limited quantity would be available to PDC attendees for only $150! Wow. That's great!

    As it turns out, I was one of the lucky ones, I got one of the devices and yes, I left the keynote early to make sure I did -- as did all the people who actually got one. Many people didn't get one even though they went to buy it as soon as the keynote ended. There is a blog entry here describing some of the negative sentiments around that as well as a response from someone on the PDC Events team.

    That drama aside, I got it home and started playing with it. With a 520Mhz processor, 128MB ROM, 64MB SDRAM, a 3.6" 640x480 TFT LCD 65K color touch screen, full QWERTY keyboard, Bluetooth, Wifi, Tri-Band GSM/GPRS, Camera, and more -- it's packing a ton of power and features.

    So I install ActiveSync 4.0 and hook up the Jasjar to my PC and try to sync with Outlook.


    So ActiveSync is missing both the "Active" and the "Sync".

    I search the web and find others are having the same problem and some people found some voodoo that got it to work but I couldn't find anything that would work for me.

    To Microsoft's defense, this version of ActiveSync is a developer preview. That still doesn't help me get around the fact that I can't sync though.

    Of course my girlfriend now thinks I overpaid for the device and wonders if that is why they were on discount :)

    Technology is becoming so difficult and unreliable, when are we going to figure out how to make things simple, elegant, yet powerful?

    Friday, September 16, 2005

    PDC Keynote: Eric Rudder



    Eric Rudder - Senior VP Server and Tools Business

    The main topics for Eric's keynote was Windows Workflow Foundation, Acrylic, Sparkle, and Quartz.

    Windows Workflow Foundation
    Windows Workflow Foundation blindsided me a little bit and I'm really excited about what this technology is going to provide for the development process.

    It is a unified workflow framework that uses a provider architecture for extensibility and extends .Net. It is used to capture the complex workflow in an application and make it easier for developers to visualize and build workflow into their applications. Workflows can be described using declarative markup (XAML), code or a combination of the two.

    With WWF, you can use Visual Studio tools to create a flow chart or state diagram and add activities to that diagram. There is a WorkFlow class and an Activity class that relate the diagram to the code. You can set breakpoints on the WorkFlow or activity and you can step through the activities in the work flow in the debugger right in to your code.

    So many applications involve work flow that this framework foundation is going to be great.

    Acrylic
    Acrylic is a graphic design tool that does both vector and raster graphics. "The professional design program that brings together the richness of pixel-based painting and the performance of editable vector graphics". Of course it exports to XAML. They did a demo of the smart select and inclusion tool which made selecting a person out of a photo as easy as a couple of intuitive clicks.

    Quartz
    Quartz is Microsoft's new Web Designer. They demo'd the integrated support of style sheets and XSLT where changes in either the designer or the files stayed in sync with each other in real time while having a very accurate design surface. Of course, it also has ASP.Net integration built in.

    Sparkle
    Sparkle is the XAML based interactive designer that integrates with Visual Studio projects and uses MSBuild. This is the tool you would use to create a next gen WPF UI with rich media. You can build XAML controls and create and hook up animations based on events all within Sparkle.

    Cider
    This was the first public unveiling of Cider. Cider is a XAML design time editor within Visual Studio. Visual Studio will have intellisense on the XAML and will keep the XAML and cider surface in sync. In fact, the internal XAML formatting is also preserved by Cider. This is what a developer would use to build the code behind a XAML UI.

    Finally, the last part of the keynote was on Application Customization which was VBA in the past but is moving to .Net technologies.

    Lots of great stuff! It was exciting.

    Wednesday, September 14, 2005

    PDC: Choosing a Presentation Technology



    Microsoft announced two new presentation technologies, Atlas and WPF/E (Windows Presentation Foundation Everywhere) at the PDC.

    One of the sessions I went to was entitled "Choosing a Presentation Technology". I thought a summary of this session would be helpful to gain a high level understanding of the presentation technologies:

    ATLAS
    • Has the reach of DHTML (w/o client install), application level features
    • Web client framework for AJAX that provides a richer, more interactive web (think AJAX for ASP.Net)
    • Deeply integrated with ASP.Net 2.0 and VS 2005
    • Rich experiences without the pain of traditional web scripting
    • Productivity: application + UI building blocks. Easier to author, debug and maintain (Component model, controls)
    • Data binding between controls and data sources
    • build programmatically or declaratively
    • Access to ASP.Net hosted and serviced components
    • MSN Hotmail beta that uses Atlas is coming and has outlook-like client side functionality

    WPF/E

    • Interactive content across multiple platforms (Windows, Mac, Devices)
    • XAML subset + Javascript
    • Vector, images, video, animation, text controls
    • No 3D, adaptive documents or HW acceleration
    • Hostable and programmable
    • Native or ActiveX hosting for application scenarios
    • ActiveX and Plugins for browser hosting (i.e. safari plugin on Mac which was demonstrated)

    At first I didn't understand why Microsoft would want to promote XAML everywhere but I had someone put it in context for me: think Macromedia Flash. Starts to make a little more sense.

    Windows Presentation Foundation (WPF)

    • Immersive experiences, next gen Windows Apps
    • XAML, XAML, XAML, XAML
    • Unified approach to UI, documents and media
    • vector based engine
    • Declarative programming models for "toolability" and flexibility that can bring designers into the process
    • Tries to avoid the owner draw pattern through composition.
    • procedural code is a peer of the declarative markup and that keeps the patterns aligned
    • Databinding baked in
    • Layout: flow, stack, grid etc. Enables support for UIs with multiple form factors
    • Document services

    WPF is formerly known as Avalon and has been a buzzword since PDC '03. It may not be the technology of the near future, but its definitely the technology of the future.

    Windows Forms

    • 3rd release of this technology is coming out in April. Only released technology discussed.
    • Supports 98, Me, W2K, XP, and Vista
    • Powerful and productive programming model
    • Poor support of reading and documents
    • Graphics and media support is there but difficult
    • Interop to Win32 and Avalon

    The best way to describe Windows Forms is that it is the technology of today and will be the bridge to the technology of the future.

    PDC Keynote with Bill Gates and Jim Allchin

    Today was the main event, the keynote with Bill Gates and Jim Allchin.

    After all the PDC ’03 announcements of how Windows Vista (Longhorn at the time), was going to incorporate a host of new technologies like WinFS, Avalon, Indigo, eDocuments (metro) to name a few, followed by the subsequent scaling back of all of those features a year later, including dropping WinFS – everyone was really interested to see how Windows Vista wasn’t going to be a Windows XP with a little nip/tuck.

    There had been some hype generation from various blogs, most notably Robert Scoble’s blog.

    So did the keynote deliver?

    In some ways. As preamble to the first presentation there was a video entitled “Change the World”. It was focused on jazzing up developers on Microsoft technologies. I have to admit, even though I knew what it was trying to do to me, I couldn’t help but feel very excited about the future of Windows development. Music and flash – gets me every time.

    Bill Gates
    Bill Gates portion started out with a very funny video of him recruiting Napoleon Dynamite for a job at Microsoft. Seeing Bill on roller blades being towed by Napoleon on a bike was just too funny.

    Bill talked about the 32 bit to 64 bit transition, the growth in tablet PCs, and how there are more broadband than dialup connections in the US. He also mentioned that Service Oriented Architecture (SOA) and connectivity beyond browsing are the future.

    The rest of his presentation focused on Vista, IE 7 and Office 12. Lots of new UI features and collaboration. You have to check out Microsoft Gadgets.

    Vista = confident + clean + connected.
    Office 12 = Results oriented UI + Extensible UI + Open XML formats

    RSS was a big topic – Microsoft is really seeing the use of RSS expanding beyond blogs and is going to have an RSS store for RSS feeds in Vista. I’ve been telling that to a lot of people about RSS lately and have been surprised by how many people don’t get the power of RSS, have never heard of it or both.

    Jim Allchin
    Jim Allchin was next and the title of his presentation was “The Next Steps for the Windows Platform”.

    The first demo he had was a beautiful set of video game scenes from a company called Crytek. Amazing graphics from what was perhaps a next generation of Far Cry.

    He then talked about the automatic optimizations that would help prevent Windows from getting slower over time (something I used to call Windows cholesterol). The first one mentioned was "Superfetch" which enhances virtual memory and optimizes the system based on historical data.

    Superfetch is a low level algorithm that collects data on which parts of any files on the disk are used the most and preloads them in the background. It also uses that data to put a priority on which parts of the preloaded files should be discarded when the system needs more physical memory. Additionally, USB flash readers can be used to increase the amount of data that can be cached. This has benefits in that the USB drive has random access (no seek times), and doesn't consume as much power as the hard drive. Great for mobile scenarios.

    From what I understand, the goal was to try to preload as much as possible to prevent hard drive hits when a user is doing their day to day work on the machine.

    He went on to talk about Atlas, which is Microsofts web client framework around AJAX that runs on any DHTML compatible browser without a client install and is deeply integrated with ASP.Net and Visual Studio 2005. It enables rich web experiences without the pain of traditional web scripting.

    One of the really neat WOW things that Jim Allchin mentioned was WPF/E. Windows Presentation Foundation (i.e. Avalon) Everywhere. This is a lightweight, multiplatform javascript + XAML solution that allows you to leverage all the XAML tools in different scenarios. There was a great example of a XAML Netflix application that ran on Windows, Tablet and a Mobile device with very little additional work required for each platform. In a later session I saw WPFE run in Safari on Mac.

    There was then a very cool demo of the peer to peer networking in Windows Vista. This is a problem I’ve wanted solved for a long time. I quite often want to send files to my family in Vancouver, B.C. It’s really difficult if the file is > 10MB. Having a P2P facility to do this in the OS would be really cool. It also simplifies file transfers with your friends or colleagues. Replication services can also be used to sync files for collaboration scenarios.

    Finally, the rest of Jim Allchin’s part of the keynote centered around demos put on by Don Box, Anders Hejsberg, Chris Anderson and Steve. They introduced LINQ (Language Integrated Query) and then did some integration with other parts of the platform. LINQ provides C# extensions to perform SQL queries on data making it simple to combine runtime and database data as well as to convert database data to XML. Very cool and powerful.

    Also, if you like to play with Digital Photos, you gotta check out Microsoft Max. This is album layout done right. Clean, simple and a really attractive UI.

    Finally
    It really is amazing to see this keynote in person. 4 huge screens, a flashy stage and around 10,000 people crammed into a single room. In a lot of ways it has the same kind of buzz and excitement as a rock concert. Where’s my lighter?

    One final thought: it sure is a different experience being in an environment where the channel 9 guy is a celebrity and you can crack jokes like “that must be the last Microsoft dev to break the build” and have the people around you laugh.