ChrisAn's Blog Please read my disclaimer.

simplegeek

a.k.a. Chris Anderson

Dynamic UI

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:

  1. Dynamic code
  2. Conditional/Bound markup
  3. Parsed-at-runtime markup
  4. 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.

11/02/2003 10:00 PM | #Longhorn

Content © 2003 Chris Anderson | Subscribe to my RSS feed.

Powered by BlogX