LinqBinding Markup Extension

Earlier today on Twitter Aaron Erickson was berating the inability to write linq statements directly in Xaml. While I’m not totally convinced that is a good idea to begin with I decided to come up with a little proof of concept to see if it’s even feasible. I was able to get about half way to what I would like to see by creating a custom markup extension called LinqBinding. The result allows you to create bindings such as this:

<sys:String x:Key=”query”>id &gt; 1 &amp;&amp; id &lt; 4 || name==”six”</sys:String>
<ListBox ItemsSource=”{e:LinqBinding {StaticResource query}, Binding={Binding}}” />
The query in the string is the linq statement you would put into the where clause normally. I was unable to figure out how to use a Binding statement to a TextBox instead of having the hard-coded string but I’m pretty confident it is possible somehow (I’ll leave that for another blog post for now).
In order to accomplish this I used the code found in the Dynamic Linq examples talked about by Scott Guthrie in his blog.
Here is the sample: LinqExtensionSample.zip

XAML 2009 Feature List

Yesterday I watched the PDC video about XAML called Microsoft .NET Framework: Declarative Programming Using XAML. It was pretty interesting and it had a list of some of the new features we can expect to see for XAML in the next version of the .NET framework. Here is a brief laundry list along with my (interpreted) explanation.

Better Name References
It used to be you had to create references to other elements using the ElementName property of Binding extensions. Well it seems now that they have created a simpler x:Reference markup extension which will be the default for properties such as the Target property of a Label. Meaning you only have to write the name of the element to get a binding to another control in some places.
XAML 2006
<Label Target=”{Binding ElementName=firstName}>First Name</Label>
<TextBox Name=“firstName” />
XAML 2009
<Label Target=“firstName”>First Name</Label>
<TextBox Name=“firstName” />
Expressions:
Interestingly enough they also touched on a new feature called expressions. The full power and syntax of expressions wasn’t fully explained but at first look they could be extremely useful. Below is an example of an expression that is the string literal “Hello” plus the value of the default property of the firstName element (being that it is a textbox I’m assuming the default property is the Text property).
<TextBox Text=‘[“Hello ” + firstName]’ />
Built-in Types
Currently you have to hook up some gnarly xmlns reference to get access to basic types. They are including access to the most common basic types by default into the ‘x’ namespace for us.
XAML 2006
<s:String xmlns:s=“clr-namespace:System;assembly=mscorlib”>Foo</s:String>
XAML 2009
<x:String>Foo</x:String>
Generics support everywhere
This is very intriguing, clearly this should be useful. I was fully expecting them to come up with something very clever and much more terse then what I see here (new syntax) but what they came up with was actually probably very easy to implement. They simply created a new attached property that stores the type arguments. I’m assuming if you have multiple type arguments you would separate them with a comma.
XAML 2006
classPersonCollection : ObservableCollection<Person>
{ }
 
<c:PersonCollection>
       <c:Person Name=“Dan” />
<c:PersonCollection>
XAML 2009
<ObservableCollection x:TypeArguments=“c:Person”>
       <c:Person Name=“Dan” />
</ObservableCollection>
My proposed generics syntax
If I was going to implement a generics syntax I probably would have favored something more like this
<ObservableCollection[c:Person]>
       <c:Person Name=“Dan” />
</ObservableCollection>
Support arbitrary dictionary key types
I haven’t experienced this as a pain point in doing WPF XAML but it seems that this feature is targeting WF more than anything. Note the example also combines examples of expressions, generics and simple type references. I bet the WF people will be happy about this one.
XAML 2006
<x:Key></x:Key>
XAML 2009
<Switch x:TypeArguments=“x:Int64” Expression=“[rating]”>
       <Sequence x:Key=“10”></Sequence>
       <Sequence>
              <x:Key>9</x:Key>
       </Sequence>
</Switch>
Beyond Method Names
Honestly I couldn’t quite fathom what he was talking about here. This must also be more targeted for WF people because I can’t really see how this would impact WPF at all.
XAML 2006
<Button Click=“button_Click” />
+ markup compilation
XAML 2009
<Button Click=“button_Click” />
+ markup compilation
Also:
<Button Click=”{Delegate Foo} />
 
Better declarative Type Authoring
Once again, this appears to be an improvement mostly for the WF crowd. After talking to Rocky Lhotka briefly he explained that it would be extremely useful to be able to declare your properties as In or Out arguments so that consumers your activities would know what to expect.
XAML 2006
<Window x:Class=“WpfApplication1.Window1” … />
XAML 2009
<Activity x:Class=“ActivityLibrary1.Prompt”>
       <x:SchemaType.Members>
              <x:SchemaProperty Name=“Text” Type=“InArgument(x:String)” />
              <x:SchemaProperty Name=“Result” Type=“OutArgument(x:String)” />
       </x:SchemaType.Members>
</Activity>
Non-default constructors
This sounds useful in general, coupled with simple type references it seems pretty easy to get any type of object you want.
XAML 2006
<x:DateTime>00:00:00.0000100</x:DateTime>
XAML 2009
<DateTime>
       <x:Arguments>
              <x:Int64>100</x:Int64>
       </x:Arguments>
</DateTime>
Use static factory methods
I’m really happy to see this one, the lack of support for factory methods was pretty disappointing to me in the past. The workaround was to use an ObjectDataProvider and specify the MethodName property, which would, unfortunately, force you to have a public default constructor for your object before it could get to your factory. This really messes with your object model, now we should be able to go directly to a factory method. There are still benefits to using the ObjectDataProvider though, I hope there is a way to get the ODP to access the factory methods without requiring a default constructor too.
XAML 2006
Guid guid = Guid.NewGuid();
XAML 2009
<x:Guid x:FactoryMethod=“Guid.NewGuid” />
Composes with x:Arguments
 

XAML Code Generation Markup Language

I have a very simple working prototype of the XAML Code Generator that I was discussing in my last post. It turns out that it’s totally possible! So for example if you have XAML that looks like this:

<test:Parent xmlns=”clr-namespace:Xcgml;assembly=Xcgml”

     xmlns:test=”clr-namespace:Xcgml.Testing.Mock;assembly=Xcgml.Testing” >

     <test:Child Data=”{Binding}” />

</test:Parent>

What we have here are two classes that inherit from GeneratorElement (which inherits from DependencyObject) and one other class called Binding that inherits from MarkupExtension. After running this XAML through the XamlReader, you end up with deserialized objects.

public static GeneratorElement Load(string xaml)

{

    using (TextReader reader = new StringReader(xaml))

    {

        using (XmlReader xmlReader = XmlReader.Create(reader))

        {

            ParserContext context = new ParserContext();

            context.XmlLang = “xcgml”;

 

            return (GeneratorElement)System.Windows.Markup.XamlReader.Load(xmlReader);

        }

    }    

}

The interesting thing is the binding. It turns out that there is no automatic system for resolving bindings like I had hoped but fortunately it’s possible to implement your own. It seems like a lot of what we get seemingly for free in WPF sits on top of the FrameworkElement class. The framework element class is not available for this scenario; I must implement my own elements on top of DependencyObject. However it wasn’t very hard to figure out how to propagate the DataContext and how to refresh values based on bindings. Here is an example unit test:

[TestMethod]

public void Simple1()

{

    Parent element = XamlReader.Load(Resources.Simple1) as Parent;

    Assert.IsNotNull(element);

    Assert.IsNotNull(element.Content);

    Assert.IsInstanceOfType(element.Content, typeof(Child));

 

    string expected = “success”;

    element.DataContext = expected;

    string actual = (element.Content as Child).Data;

 

    Assert.AreEqual(expected, actual);

}

Notice when I set the element.DataContext the child’s Data property will change because of the binding specified! I am planning on adding these features soon:

<!–[if !supportLists]–>·         <!–[endif]–>StaticResource binding – so you can bind to values in resources

<!–[if !supportLists]–>·         <!–[endif]–>Templates – so you can customize standard objects

<!–[if !supportLists]–>·         <!–[endif]–>ItemsControl – so you can have multiple nested controls

<!–[if !supportLists]–>·         <!–[endif]–>Repeat control

<!–[if !supportLists]–>·         <!–[endif]–>If control

 

Download the Source

<!–[if !supportLists]–>·         <!–[endif]–>Xcgml-20080731.zip (17.2 KB)

XAML View Engine

I just had an interesting idea and wanted to blog it down before forgetting since I can’t really spend time investigating it now.

Well I’ve been working with NVelocity and now Spark to use as my view engine for template generation. I’m very happy with Spark right now (since it actually works) and I have been generating templates like a fool the last couple days. I think I might have a preview release of NBusiness 3 out for testing sometime soon.

That being said there is definitely still something missing. It works… it’s a heck of a lot better than NVelocity but it’s not quite perfect. I was just mentioning this to a friend and suddenly had a jolt of inspiration. I had the idea that you could, quite possibly, declare your entire template in XAML . Your XAML syntax could support binding and you could have looping and conditional controls right in it. This would allow you to declaratively define code in arbitrary languages. Pretty interesting… here is a little snippet of what I was envisioning:

<Class Attributes=”Public, Abstract” Base=”BusinessBase” Name=”{Binding Name}”>

   <Repeat Collection=”{Binding Fields}”>

      <Field Name=”field” Attributes=”Private” Type=”{Binding Path=Type}” Name=”{Binding Path=Name, Converter=FIeldNameConverter}” />

      <Property Attributes=”Public” Type={Binding Path=Type}” Name={Binding Path=Name}”>

         <Property.Getter><Return Expression=”{Binding RelativeSource=field}” /></Property.Getter>

      </Property>

   </Repeat>

  

</Class>

Honestly, I’m thinking that all I have to do is create these objects which would inherit from DependencyObject and the XAML serializer will do the rest… I doubt it would be that simple but I may have to try it out later tonight.

The thing is, once you have this template into a DOM you could then run it through some sort of Conversion process to create CodeDom objects which would produce code for any arbitrary language! The trick would be to make it flexible enough to support conversion to things like HTML or whatever. Wow, this could be interesting.

Improve XAML Load Time in Visual Studio 2008

I’ve noticed that whenever I attempt to open up a XAML file in VS 2008 it will freeze up for about 5 seconds. Then whenever I make any changes to the XAML visual studio will freeze up again for about 5 seconds.

To be fair I have a pretty significantly sized XAML application and it seems the real slow down comes from including a Merged Resource Dictionary with a large amount of templates. But freezing up visual studio for this amount of time is incredibly painful.

I have managed to finally get rid of this delay by changing the options for XAML files to “Always open documents in full XAML view”.

You can find these options in Visual Studio 2008 by going to Tools->Options->Text Editor->XAML->Miscellaneous. Thank the flying spaghetti monster for this option!