Creating and Loading XAML dynamically in WPF

In this post, we will see how to create a XAML file from the WPF element object and how to load this XAML file dynamically to generate UI. In WPF we have been provided with following classes:

  • XamlWriter - used to serialize the WPF UI Element objects in Xaml code.
  • XamlReader - used to read the Xaml file, parse it and generate WPF object graph from it.

In the following application, I have demoed the same. I have created a WPF application with the following design Xaml for MainWindow.Xaml:

<Grid>
<
Button Content="Create XAML" Height="51" HorizontalAlignment="Left"
Margin="22,26,0,0" Name="btnCreateXAML" VerticalAlignment="Top"
Width="250" Click="btnCreateXAML_Click" />
<
Button Content="Load XAML" Height="50" HorizontalAlignment="Left"
Margin="458,12,0,0" Name="btnLoadXAML" VerticalAlignment="Top"
Width="250" Click="btnLoadXAML_Click" />
<
Grid Height="296" HorizontalAlignment="Left" Margin="384,82,0,0"
Name="grdLoadXAML" VerticalAlignment="Top" Width="414" />
</
Grid>

Creating Xml or XAML File From WPF UI Element Objects

The ‘btnCreateXAML’ click event has the following code as shown below. The buttons dynamically creates the Grid UI object and adds a Button and TextBox UI object as a child of the Grid. Using XamlWriter class a .xml file is created which serialize all UI objects. This object is passed to the FileStram class. The code is as shown below:

private void btnCreateXAML_Click(object sender, RoutedEventArgs e)
{
try
{
Grid grd = new Grid();
grd.Height = 210;
grd.Width = 400;
Button btn = new Button();
btn.Height = 50;
btn.Width = 80;
btn.Content = "Dyn. Button";
btn.Background = new SolidColorBrush(Colors.Red);
btn.Margin = new Thickness(5, 5, 310, 120);
grd.Children.Add(btn);

TextBox txt = new TextBox();
txt.Height = 50;
txt.Width = 100;
txt.Text = "Dynamic TextBox";
txt.Foreground = new SolidColorBrush(Colors.Red);
txt.Margin = new Thickness(5, 60, 310, 80);
grd.Children.Add(txt);

//Store this Xaml in File

FileStream Fs = new FileStream(@"H:\GeneratedFiles\MyDesign.Xml",
FileMode.CreateNew);
System.Windows.Markup.XamlWriter.Save(grd, Fs);
Fs.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

Note: The File extension can also be .XAML. There is no difference in the code, since XAML is logically based upon XML

The following XAML file will be generated:

image

Loading XML or XAML file dynamically to Generate WPF UI Element Graph

Let us quickly see the code first to load the XAML dynamically

private void btnLoadXAML_Click(object sender, RoutedEventArgs e)
{
try
{
OpenFileDialog Fd = new OpenFileDialog();
Fd.ShowDialog();
string LoadedFileName = Fd.FileName;

//Load the file
FileStream Fs = new FileStream(@LoadedFileName, FileMode.Open);
Grid grdToLoad = new Grid();
grdToLoad.Height = 210;
grdToLoad.Width = 400;

grdToLoad = System.Windows.Markup.XamlReader.Load(Fs) as Grid;

grdLoadXAML.Children.Add(grdToLoad);

Fs.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}

The code shown above loads the xml using ‘XamlReader’ class. This class provides the ‘Load’ method which parses the input xml / xaml document. One of the most important thing here is that the file is parsed from its root element. This has to match with a specific Panel control of WPF e.g. Grid, Canvas, etc. Based upon that, the Load() method is type casted using ‘as’ operator. If the root is matched with the panel, then all the XAML UI elements in the file will be constructed and the WPF Element object graph will be generated.

Run the application and click on the ‘Create XAML’ button. The file will be created in the specified path. Then click on ‘Load XAML’ button to open the ‘Open File Dialog’. Select the xml file generated earlier and you will see the following result:

image

4 comments:

  1. this is a great interesting xaml article

    ReplyDelete
  2. This is all great, but the problems start when you try to add a handler to Click event of a dymanic button

    ReplyDelete
  3. bom dia
    bacana o seu codigo estou usando
    wpf com vs2015 porem ele não esta abrindo o xaml
    da esse erro

    Valor não pode ser nulo.

    não sei oque pode ser

    ReplyDelete
  4. thanks for your tutorial :)
    i tried to load 3d xaml file and display it to windows form using this method.

    ---and dont forget to add :
    using System.Windows;
    using Microsoft.Win32;
    in your c# codes

    ReplyDelete