VB4: "XAML, I am your father"
I think I've mentioned before that I've been a Visual Basic developer since the glory days of VB 1.0. While these days I prefer the syntax of C#, I still dabble in VB fairly often (usually because I've been the only one in p&p who will write VB QuickStarts!), and I often think that the contributions that VB has made to software development as a whole are often underrated. While its popularisation of concepts such as GUI designers, properties and passing objects by references has been noted many times, I've just noticed something that appears to be a VB throwback in a new guise that I hadn't seen anyone mention before. Maybe I'm just a conspiracy theorist (I don't know anyone in the relevant teams), but whether or not this theory is true, I think it's a good story regardless.
I'm currently working on a project that's finally forced me to start learning WPF. Of course I've seen the snazzy demos with videos on spinning cubes, but up until now I never really had the time (or more importantly the necessity) to figure out how it all worked. Now I've only just dipped my toes into the water, but so far I'm blown away by both the capabilities and the elegance of the architecture.
Once you start looking at WPF, it doesn't take long before you hear about this thing called XAML. At first glance, XAML is the XML language you use to build WPF GUIs. While there are fancy WPF designers in Visual Studio 2005 (via CTP tools) and Expression Blend, ultimately these are just editors over XAML files, and I've found that, just like with HTML, learning how to write XAML by hand is a great way of getting a better appreciation and understanding of the technology. If you haven't seen XAML code before, there are stacks of WPF XAML examples here, amongst other places.
However after reading and playing with XAML a bit more, I had the "a-ha" moment when I started to understand that XAML isn't actually about WPF at all. While the two technologies taste great together, you are completely free to build WPF apps entirely in code without a line of XAML. More interestingly, you can use XAML to build things completely unrelated to WPF. This is because XAML is actually a language for defining graphs of arbitrary .NET objects. While there are a few gotchas (like the requirement for classes to have default public constructors), XAML can be used for a wide array of applications, even when there isn't a UI to be seen.
To test this theory, I thought I'd try building a Windows Forms application in XAML. Obviously this wasn't the scenario that XAML was built for, but since all of the key classes are well behaved in terms of their constructors and collection types, it all worked just like a bought one. Here is the XAML for my trivial Windows Form:
<wf:Form x:Class="XamlWinForms.Window1"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Text="Window1" Height="300" Width="300"
>
<wf:Form.Controls>
<wf:Panel BackColor="#00FFFF" Dock="Fill" BorderStyle="Fixed3D">
<wf:Panel.Controls>
<wf:Button Text="Click Me!" Left="50" Top="50" Width="100" Height="50" Click="Button_Click"></wf:Button>
<wf:ListBox Top="120" Left="20">
<wf:ListBox.Items>
<sys:String>Foo</sys:String>
<sys:String>Bar</sys:String>
</wf:ListBox.Items>
</wf:ListBox>
</wf:Panel.Controls>
</wf:Panel>
</wf:Form.Controls>
</wf:Form>
You would never do this in a real application, mainly due to the lack of visual designers, plus the need to specify co-ordinates for everything makes it much more painful than writing WPF applications by hand. But still, after admiring my work, it got me thinking that this is actually a far more sensible representation for a GUI, even in a WinForms app, than what Visual Studio does by default. Visual Studio's approach is to use the designer data to generate code (such as C# or VB) that explicitly adds all of the controls to the form and sets all of the properties. Even though this code is now safely hidden away in generated partial classes, it's all a bit fragile and, to me at least, feels unnatural - especially when it comes to parsing the code to re-render the form in the visual designer.
But then it occurred to me that I've seen a very similar approach to declaratively specifying forms before, in - you guessed it - Visual Basic 4.0 to 6.0. I don't actually have any of my old projects lying around on my hard disk anymore, but a quick search of the web came up with a number of examples of .FRM files, with code like this:
VERSION 5.00
Begin VB.Form Form1
Caption = "Form1"
ClientHeight = 3090
ClientLeft = 60
ClientTop = 450
ClientWidth = 3690
ForeColor = &H0000FFFF&
LinkTopic = "Form1"
MaxButton = 0 'False
ScaleHeight = 3090
ScaleWidth = 3690
StartUpPosition = 3 'Windows Default
Begin VB.Timer Timer1
Interval = 1000
Left = 3000
Top = 2280
End
Begin VB.CommandButton Command1
Caption = "Press to Play"
BeginProperty Font
Name = "MS Sans Serif"
Size = 9.75
Charset = 0
Weight = 700
Underline = 0 'False
Italic = 0 'False
Strikethrough = 0 'False
EndProperty
Height = 495
Left = 720
MaskColor = &H008080FF&
TabIndex = 0
Top = 2400
Width = 2175
End
Begin VB.Shape Shape1
FillColor = &H000000FF&
FillStyle = 0 'Solid
Height = 615
Index = 8
Left = 2280
Shape = 5 'Rounded Square
Top = 1080
Width = 495
End
End
This file format was defined before the days of XML, but if you look at the content it has an uncanny resemblance to the XAML in its ability to define controls and properties, nest objects in one another, and even mix controls and (rudimentary) graphics together. I know that the XAML team has spent a bunch of time taking this idea and moving it far, far beyond what was ever possible in those days - but it's nice to know that good ideas like this don't die, they are just cryogenically frozen, waiting for just the right era to be thawed out again.
Comments
Anonymous
June 20, 2007
Have you already had a look at Acropolis. It actualy also uses XAML outside the GUI, for wiring the 'parts' etc. together. XAML is also used as specification, which can then be used/consumed by a tool to transform to different level/view.Anonymous
June 20, 2007
Holi Me gustaria saber de que se trata el Blog. no entiendo mucho. Me podrias explicar de que se trata. No hablo ingles pero se ve interesante. Chaooooo escribemeAnonymous
June 20, 2007
At least as early as VB3, these textual .frm files existed. You could also save as the binary equivalent, but this was discouraged due to instability and corruption.Anonymous
June 22, 2007
Nice work Tom! Just to drive this home further, for those that are not familiar with Windows Workflow Foundation, it uses XAML (XOML) as well for defining business processes. (see the snippet below) <SequentialWorkflowActivity x:Class="XAMLWorkflow.Workflow1" x:Name="Workflow1" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/workflow"> <IfElseActivity x:Name="ifElseActivity1"> <IfElseBranchActivity x:Name="ifElseBranchActivity1"> <IfElseBranchActivity.Condition> <CodeCondition Condition="EvalCondition" /> </IfElseBranchActivity.Condition> <CodeActivity x:Name="codeActivity1" ExecuteCode="codeActivity1_ExecuteCode" /> <FaultHandlersActivity x:Name="faultHandlersActivity1"> <FaultHandlerActivity x:Name="faultHandlerActivity1" Fault="{ActivityBind Workflow1,Path=faultHandlerProp}" FaultType="{x:Type System.NullReferenceException}"> <CodeActivity x:Name="codeActivity3" ExecuteCode="codeActivity3_ExecuteCode" /> </FaultHandlerActivity> </FaultHandlersActivity> </IfElseBranchActivity> <IfElseBranchActivity x:Name="ifElseBranchActivity2"> <CodeActivity x:Name="codeActivity2" ExecuteCode="codeActivity2_ExecuteCode" /> </IfElseBranchActivity> </IfElseActivity> </SequentialWorkflowActivity>Anonymous
June 22, 2007
The comment has been removedAnonymous
June 27, 2007
My memory of the glory days of Windows 3.x development is a little hazy now, but I thought textual forms were part of the 'visual' range of tools, so not strictly VB-specific. If I remember rightly, forms in those days were part of the resources group. At that time there was no specific documentation of the contents of a .frm file (at least, I never found anything...), but it was often easier to tweak form files by hand for small changes, rather than power up the form designer.Anonymous
September 14, 2007
Interesante "correspondencia" entre XAML y los .FRM de los viejos (que aun utilizo) proyectos