PDA

Click to See Complete Forum and Search --> : Dynamically load a xaml contents to another xaml app


KGComputers
Aug 14th, 2009, 04:22 AM
Hi,

My first WPF post.

In my project's folder,

1. I have a xaml file browser_me.xaml(browser app/window) that will let the customer choose the xaml files in the directory that contains other xaml files. After the customer choose a specific xaml file, its contents will be displayed to brower_me.xaml.

It's like dynamically loading an entire xaml page to another xaml page.


Sincerely,


greg

chris128
Aug 14th, 2009, 06:18 AM
You can use the Markup.XamlReader and Markup.XamlWriter classes to load/save XAML files. Like so:


'Save the entire Page/Window (whatever "Me" refers to in this case)
Markup.XamlWriter.Save(Me, New System.IO.StreamWriter("C:\test.xaml", False))


'Load the test.xaml file
Markup.XamlReader.Load(New IO.StreamReader("C:\test.xaml").BaseStream)

KGComputers
Aug 15th, 2009, 12:29 AM
hI,

It gives me an error like this:
"Specified index is out of range or child at index is null. Do not call this method if VisualChildrenCount returns zero, indicating that the Visual has no children.\r\nParameter name: index\r\nActual value was 0."


This happens when this code is executed:
FrameworkElement parentt = (FrameworkElement)VisualTreeHelper.GetChild(ctrl, 0);

whats the right way to traverse the visual tree of xaml?

XAML PAGE
<Window x:Class="LoadDynamicallyXamlPages.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="600" Width="800" Loaded="Window_Loaded">
<Grid Loaded="Grid_Loaded">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Name="pnl1" Orientation="Horizontal" Grid.Column="0" Grid.Row="0">
<Button Name="btnShowPage" Height="25" Width="70" Click="btnShowPage_Click">
Show Page
</Button>
<TextBox Name="txtPage" Height="25" Width="200">
</TextBox>
</StackPanel>

</Grid>
</Window>

C# CODE
private void ReadXaml()
{
try
{

//working code
Window w = new Window();
System.Uri uri = new Uri("Window1.xaml", UriKind.RelativeOrAbsolute);
w = Application.LoadComponent(uri) as Window;
castObject(w);
}

catch (Exception ex)
{
MessageBox.Show(ex.InnerException.Message.ToString(),"Error");
}
}


private void castObject(Window ctrl)
{
this.txtPage.Text = ctrl.Height.ToString();
FrameworkElement parentt = (FrameworkElement)VisualTreeHelper.GetChild(ctrl, 0);
int count = VisualTreeHelper.GetChildrenCount(parentt);
for (int i = 0; i < count; i++)
{
FrameworkElement c = (FrameworkElement)VisualTreeHelper.GetChild(parentt, i);
if (c is Button)
{
Button b = c as Button;
//b.Click += new RoutedEventHandler(Button_Click);
}
else if (c is TextBox)
{
TextBox txt = c as TextBox;
//txt.TextChanged += new TextChangedEventHandler(txt_TextChanged);
}
}

private void Grid_Loaded(object sender, RoutedEventArgs e)
{
ReadXaml();
}

chris128
Aug 15th, 2009, 01:46 PM
Have you actually read my post?

KGComputers
Aug 15th, 2009, 02:44 PM
Cris,

In this code below, it will insert load a loose xaml(Page,Grid,Canvass,StackPanel, and etc..)
to the window.

However, if a page with x:class markup or window with x:class markup or code event will be loaded, it will generate series of errors.

Can I possibly trap my application to display only loose xaml files?

If a xaml file that is not a loose xaml will be loaded, it display an error message.

This code uses a common dialog to open xaml files,so basically it will load any type of xaml file. Each file opened will be passed to FileStream object.
BUt my concern is to trapp to display only loose xaml files will be shown on the window.


try
{
dependencyObject = XamlReader.Load(fileStream) as DependencyObject;
this.Content = dependencyObject; //insert to the current window
//obj = XamlReader.Load(fileStream);
}
catch (Exception ex)
{
MessageBox.Show(ex.InnerException.Message);
return;
}

Here are the xaml files (not Loose)
codes that will create errors when loaded:


'Class' attribute does not exist in XML namespace 'http://schemas.microsoft.com/winfx/2006/xaml' namespace. Line '1' Position '9'.
<Window x:Class="LoadDynamicallyXamlPages.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="600" Width="800">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="30"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Name="pnl1" Orientation="Horizontal" Grid.Column="0" Grid.Row="0">
<Button Name="btnShowPage" Height="25" Width="70" Click="btnShowPage_Click">
Show Page
</Button>
<TextBox Name="txtPage" Height="25" Width="200">
</TextBox>
</StackPanel>
</Grid>
</Window>



<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button Click="button_Click">OK</Button>
<x:Code><![CDATA[
void button_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
]]></x:Code>
</Window>

error:Must compile XAML file that specifies events. Line '3' Position '9'.
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Button Click="button_Click">OK</Button>
<x:Code><![CDATA[
void button_Click(object sender, RoutedEventArgs e)
{
this.Close();
}
]]></x:Code>
</Page>

Hope its clear..

Greg