Tuesday 15 July 2008

Dynamic XAML

I thought I'd post up a Silverlight Beta 2 dynamic XAML sample.  This is a pretty simple sample which consists of a textbox, a button and a grid.

All you simply do is paste some XAML into the textbox, click the button and the XAML will appear in the grid.

You can view an online demo here

This is a very simple implementation however this could be extended much further as an application.  Isolated Storage to store XAML, save it back to a WCF Service etc.

You could take the concept further even still and use a duplex WCF service (or sockets) to post XAML between different clients.

The key thing when dealing with dynamic XAML is using System.Windows.Markup.XamlReader.Load to load the XAML.

The code is below.

XAML

<Grid x:Name="LayoutRoot">
<
Grid.ColumnDefinitions>
<
ColumnDefinition/>
</
Grid.ColumnDefinitions>
<
Grid.RowDefinitions>
<
RowDefinition/>
<
RowDefinition/>
</
Grid.RowDefinitions>
<
Grid x:Name="gridDynamic"
Grid.Row="0"
Height="500" Width="500"/>
<
StackPanel Orientation="Horizontal" Grid.Row="1">
<
TextBox x:Name="myTextbox"
Text="Load Xaml"
AcceptsReturn="True" TextWrapping="Wrap"
Margin="5" Height="200" Width="500"/>
<
Button Content="Load Xaml"
Height="30" Width="100"
Click="Button_Click"/>
</
StackPanel>
</
Grid>


C#


public partial class DynamicXaml : UserControl
{
public DynamicXaml()
{
InitializeComponent();
myTextbox.Text = @"<Grid xmlns=""http://schemas.microsoft.com/client/2007"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""><Ellipse Height=""100"" Width=""100"" Fill=""Red""/></Grid>";
}

private void Button_Click(object sender, RoutedEventArgs e)
{
UIElement xamlElement = (UIElement)System.Windows.Markup.XamlReader.Load(myTextbox.Text);
gridDynamic.Children.Clear();
gridDynamic.Children.Add(xamlElement);
}
}

5 comments:

Anonymous said...

That takes care of the trivial case, so how do you hook up an event in that XAML?

Anonymous said...

Forget that last post, I just named the element, found it using FindName, and hooked up the event. Really simple.

UIElement xamlElement = (UIElement)System.Windows.Markup.XamlReader.Load(myTextbox.Text);
Button b = (Button)((FrameworkElement)xamlElement).FindName("button");
b.Click += New_Button_Click;

chrishayuk said...

In all honesty if you want to dynamically hook up a button to a click event (if the button is dynamically created), is to you use the click event in the .xaml

To take it even further you could use the DLR (IronPython etc) and you could dynamically load the code behind.

Michael Foord is the expert in this area and has some cool demos regarding

Anonymous said...

chrishayuk, you can't have ANY events in the XAML code when using XamlReader, that's why you HAVE to do it the way I did.

However, you are correct about the DLR, but I don't think what I did is so hard it's a show stopper.

chrishayuk said...

Thanks for that! I was not aware of that :)

One of the things I truly love about being in the community is you learn something new everyday :)