Tuesday, March 17, 2009

AIG and Congress

It's been amusing to watch the congressmen and women step all over themselves to condemn the $165MM in AIG executive bonuses. Of course, it's silly and stupid for the AIG employees to expect these bonuses: were it not for the fact that taxpayers have stepped in, the traunche for their bonuses would fit somewhere behind the janitor's salary in AIG's bankruptcy proceedings. If they get bonuses at all, it's from a sheer legal technicality.

But it's equally disingenuous for the members of our beloved Congress to insist, as I heard one member say, that "rewarding failure is not the American way." As John Schoen of MSNBC has pointed out in a recent article, the various laws passed by Congress, or not passed by Congress, have contributed to this mess just as much as any extra-fancy financing from AIG's trading desk. Most notably, in 2000, Congress (under Bill Clinton) passed the bi-partisan "Commodity Futures Modernization Act", which, among other things, dramatically loosened regulations on derivative financial products, and created the multi-trillion dollar bubble which recently imploded under AIG.

Chuck Grassley recently said that it would be the honorable thing for the AIG traders either to resign or commit suicide. It would seem convenient to request that our congressional representatives uphold similar standards. Unfortunately, we need them around, and for the same reason we need the AIG traders at their desks: the folks who got us into this mess are, regrettably, best positioned to get us out.

Wednesday, March 4, 2009

Further Thoughts on WPF and XAML

I started to play with WPF and XAML a couple weeks back, and wrote a post about my first thoughts. Since then, I've been working through my first full-fledged WPF app, and I've figured out a ton more that I didn't understand at the time: both about the true strengths of WPF, and the things I still find really annoying. So some more thoughts:

  • The ability to easily modify templated controls is amazing. You can do things in minutes with a ListBox in XAML that would have taken months of tedious coding in WinForms.
  • The WPF designer in Visual Studio sucks. It gives you virtually no help in troubleshooting errors, it's slow, and among many other complaints, it is of no help whatsoever when you're trying to layout a DataTemplate. I've been reduced to numerous long, painful cycles of, "change/compile/run/look/swear/change again".
  • The WPF data-binding model is very powerful, but it's very subtle, difficult to get right, and very easy to get wrong. If anyone at Microsoft actually believes the marketing-speak that it's "simple" in addition to powerful, they need to have their head examined. For instance, I guess it's kinda cool that you can set bind properties on one control to another control, and can trigger behaviors when those properties change: but I can do this in a very straightforward way in C#, and in contrast, the XAML syntax for doing it is really annoying. If you didn't know XAML pretty darned well, would you have any idea what the code below is doing? (Hint: it displays a particular control when its parent ListBoxItem is selected.)
  • <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListBoxItem}, AncestorLevel=1}, Path=IsSelected}" Value="True">     <Setter Property="Visibility" Value="Visible" TargetName="pledgeDetailsDockPanel" /> DataTrigger>

  • XAML desperately needs some debugging aids. Since it's a declarative and not a procedural language, it doesn't really make sense to "step through" code, but something like FireBug for XAML instead of HTML would make a ton of difference when you're trying to figure out why a particular {Binding} isn't working the way you expect. (Which, in my limited experience, is fairly close to always.)
  • Contrary to the raves I've read elsewhere, I'm convinced that XAML is an ugly, clunky language. Granted, there are certain things that it allows you to express with great ease: instantiating a control, for instance, and setting its properties. But if you have to interact with outside objects or even other controls in any but the most basic manner, things get ugly very quickly. If you've ever worked with an ObjectDataSource, especially if you had to pass it dynamic method parameters, you know what I mean. Compared to XAML in these instances, C++ is a model of clarity, and perl is a model of readability.
  • Here's an example of what I mean on that last point. Let's say that I've got a simple WPF app that converts Fahrenheit to Celsius, by calling the method ToCelsius() on a Fahrenheit class.

    In C# code-behind, I can get this to work with two lines of code:

    private void txtFahrenheit_TextChanged(object sender, TextChangedEventArgs e) {     Fahrenheit temp = new Fahrenheit(txtFahrenheit.Text);     lblCelsius.Content = temp.ToCelsius(); }

    Here's how you get those two lines of code to work in XAML (with all of the purely formatting attributes and tags removed):

    <Grid.Resources>     <ObjectDataProvider ObjectType="{x:Type local:Fahrenheit}" x:Key="fahrenheit">         <ObjectDataProvider.ConstructorParameters>             <system:String>system:String>         ObjectDataProvider.ConstructorParameters>     ObjectDataProvider>     <ObjectDataProvider ObjectInstance="{StaticResource fahrenheit}" MethodName="ToCelsius" x:Key="toCelsius" /> Grid.Resources> <TextBox>     <TextBox.Text>         <Binding Source="{StaticResource fahrenheit}">             <Binding.Path>ConstructorParameters[0]Binding.Path>             <Binding.BindsDirectlyToSource>TrueBinding.BindsDirectlyToSource>             <Binding.UpdateSourceTrigger>PropertyChangedBinding.UpdateSourceTrigger>         Binding>     TextBox.Text> TextBox> <Label>     <Label.Content>         <Binding Source="{StaticResource toCelsius}" />     Label.Content> Label>

    Those two lines of very simple, very comprehensible code have expanded into something like 16 new lines of very dense, intricate, complicated XML. Oh, and have I mentioned that you can't debug those 16 lines of code? And if you look closely, you'll notice that there's a nice ugly hack in there, where I do a sort of reverse-binding, with the Fahrenheit textbox as the target of a binding to the first parameter in the Fahrenheit constructor. You have to do this because the ObjectDataProvider is inexplicably not a DependencyObject, so you can't bind any of its properties to the properties of a control: you have to do it the other way around, and bind a control's properties to the ObjectDataProvider.

    Sigh.

    XAML and WPF still needs a bit of work.

    Tuesday, March 3, 2009

    The type initializer for ‘SomeClass’ threw an exception.

    I spent a good hour this afternoon troubleshooting a bizarre WPF designer error. I've been working on an app for my church, and I was using an ObjectDataProvider in a particular page to return a "Donation" object from my data-layer with some appropriate defaults set.

    <ObjectDataProvider x:Key="defaultDonation" ObjectType="{x:Type classes:Data}" MethodName="GetNewDonation" />

    This had been working fine for a while, but after I refactored a bit of the code in my data layer, the WPF designer stopped loading any form that touched this data layer. It kept returning the error:

    The type initializer for 'WouldBeTheologian.PledgeManager.Classes.Data' threw an exception.

    Interestingly enough, although the WPF forms wouldn't load, the project itself would run just fine; and specifically, the Data class would load and execute just fine. But it's a pain and a half to lose IntelliSense, and to have no hint of what your XAML is gonna look like.

    It took some work to figure out what was going on. It turns out that after I refactored my Data class, I was instantiating a reference to my Entity Data Model during the class' static constructor, like so:

    static Data() { pledgesEntities = new PledgesEntities(); }
    But beneath the hood, when the EF tries to initialize its ObjectContext, it's doing so by reading the appropriate connection strings from the application's .config file. That works fine when the "application" is, in fact, your own application. But when it's called by the WPF designer, the "application" is Visual Studio, which (presumably) doesn't have the appropriate connection strings in its .config file; and hence the constructor throws an exception.

    Once I figured this out, I fixed it by moving the instantiation of my Entity Data Model into a property, like so:

    private static PledgesEntities pledgesEntities = new PledgesEntities(); 
    public static PledgesEntities PledgesEntities 
    {
        get
        {
            if (pledgesEntities == null)
            {
                pledgesEntities = new PledgesEntities();
            }
            return pledgesEntities;
         }
         set
         { 
             pledgesEntities = value; 
         }
    }
    In other words, the static PledgesEntitities instance doesn’t get initiated until it’s actually needed, and hence doesn’t throw an exception when the designer loads the class. It's a bit uglier and infinitesimally slower, but it works.
     
    I should note that there are lots of other ways around this problem as well; a more general approach is just to wrap any code that might give the designer trouble with a check to see whether you’re running in the designer or not, like so:
    if (!DesignerProperties.IsInDesignTool)
    {
        // Do stuff that won't work in the designer
    }

    Of course, I'm not the first person to figure out that the Visual Studio WPF designer sucks at providing any help troubleshooting these errors. Among many other things, there's no way to access the InnerException of the error in question, which is a serious limitation, and has bit me on several occasions. Hopefully VS 2010 will fix this, though I haven't yet seen any firm indication that will be the case.