There seems to be a lot of discussion floating around in my comments about "Dynamic
XAML", which confuses me (I'm easily confused). No one thinks of "Dynamic C#" or "Dynamic
VB", they are languages - it is the application that you create that has dynamic behavior...
Dynamic user interface can be easily created in Longhorn using Avalon in several ways:
-
Dynamic code
-
Conditional/Bound markup
-
Parsed-at-runtime markup
-
Projection based markup
Projection based markup
I start with projection, because I think it is what most people think of when they
asked the question about "dynamic XAML". In the web world today you create projection
based user interface. You do work on the server to determine what the static view
the client should see (maybe with some interactivity in the form of jscript, etc.),
and then you project HTML across the wire and let the (basically) dumb client render
that logic.
In the web today there is this uneasy tension with DHTML (W3C DOM or IE DOM) and
ASP.NET/PHP/JSP... Here you have a sever and client side programming model, both trying
to produce dynamic results. You end up with this bizaree spaghetti code that spans
between the tiers. You might do data filtering on the server, but allow for sorting
to occur on the client to avoid round trips.
The question then is raise, with this new Windows markup "XAML", can you accomplish
projection based UI? The simple answer - yes. We support parsing of markup on the
fly.
However for interactivity the programming model for Avalon is .NET classes, which
means you need to somehow get IL generated, or have an interpretted language. Today
the JScript parser is the closest thing we have to an interpretted .NET language,
but I know there are other interpretted languages out there.
Why have we not focused on interpretted or projection based UI? To put it simply -
it doesn't scale. Smart client applications aren't really possible in projection based
UI. If you look at any even moderately interactive application they have moved the
processing logic to the client to leverage the power of the PC - Flash, Java, Anark,
all do the logic on the client. Yes, there are some places that do dynamic Flash generation,
but that seems to be a limitation that products like Royale and Central will solve.
Parsed-at-runtime markup
If projection based markup is only supported limitedly, then what about parsing at
runtime? This is the old DHTML model of doing things like "document.Write" and "someId.InnerHtml='...'"
as a programming model.
Avalon has a simple object model for our parser that will allow this type of programming.
You can concat a string together, pass it to the parser, and get back a fully realized
.NET object, viola!
Of course, parsing and string generation has it's problems - lack of type checking
at compile time, performance, debuggability, etc. This model, like projection based
markup, is supported - just not encouraged.
Conditional/Bound markup
Hopefully, eventually, I will actually hit one of these mechanisms for dynamic UI
that we think is great. Well, wait no longer!
Using databinding, repeating, styling, triggers, frames, etc, for creating truly dynamic
UI is the Avalon recommended way. People write "dynamic" UI today using VB.NET and
WinForms that gets data from a database and presents it in a great format using DataGrids,
etc. In Avalon we are evolving this and adding rich typography, template based repeating,
and a new model for triggers and styling.
The nuts and bolts of this? Say that I want to create a news browser, I can create
styles for the news objects (note, these are data objects, not UIElements):
<!-- Psuedo-code, I don't have a longhorn box handy right now -->
<Style def:Name="*typeof(NewsReport)">
<DataElement /> <!-- I forget the exact name of this element...
? -->
<Style.VisualTree>
<DockPanel>
<SimpleText
DockPanel.Dock="Top" Text="*Bind(Path=Title)">
<SimpleText
DockPanel.Dock="Top" Text="*Bind(Path=ByLine)">
<TextBox DockPanel.Dock="Fill"
Content="*Bind(Path=Body)" />
</DockPanel>
</Style.VisualTree>
</Style>
Now, I could have another format for some other type of story:
<!-- Psuedo-code, I don't have a longhorn box handy right now -->
<Style def:Name="*typeof(ForSaleAdd)">
<DataElement /> <!-- I forget the exact name of this element...
? -->
<Style.VisualTree>
<DockPanel>
<SimpleText
DockPanel.Dock="Top" Text="*Bind(Path=Title)">
<TextBox DockPanel.Dock="Fill"
Content="*Bind(Path=Body)" />
</DockPanel>
</Style.VisualTree>
</Style>
Here I could then have a listbox that contains an arbitrary list of NewsReports and
ForSaleAdds, and each would be rendered according to the style - thus a WebService
(or, heaven forbid!, a database) could return the content. These "data styles" can
be associated with the class that defines the data structure also.
Remember The ListBox is really a generic repeating control, it
isn't the same as the old scrollbar and horizontal list control. The ListBox in Avalon
is more of a peer of the "DataList" in ASP.NET.
Dynamic Code
Finally, if dynamic markup doesn't solve this, you can go to the brute force traditional
model for dynamic UI - write code. One of the goals with Avalon was to have a unified
model that provided both a simple markup and a simple code based programming model.
Thus, if you want to dynamically generate user interface elements you can simply write
code like:
void ButtonClicked(object sender, ClickEventArgs e)
{
someElement.Controls.Add(new Button());
}
Which provides you with unlimited flexibility.
Summary
My not-to-hidden agenda here is simple - dynamic applications should
be dynamic on the client. The server should send data - either through web
services, database access, or any other wire protocol - and the client should consume
that data and generate UI. The model of a server trying to generate the correct display
for a client is just broken.
My computer knows what my settings are, I don't need to server to guess them. The
application on the client knows my screen resolution, DPI, color depth. It knows if
I have a scanner, mouse, keyboard, tablet, printer, etc. The application on the client
has full access to a powerful CPU, GPU, and hard disk that are dedicated to *me*.
We are past the world of generating static snapshots of display and blasting them
down to a client. Most desktop computers you buy today have 2+Ghz CPU, >256MB of
RAM, and a massive hard disk. Use them! Make your application be so engaging and productive
for your customers that they want to buy it.