Windows Vista Forums
Vista Forums Home Join Vista Forums Windows 7 Forum Vista Tutorials Tags
Welcome to Windows Vista Forums. Our forum is dedicated to helping you find solutions with any problems, errors or issues you are experiencing with Windows Vista. The Vista forum also covers news and updates and has an extensive Windows Vista tutorial section that covers a wide range of tips and tricks.

Go Back   Vista Forums > Misc Newsgroups > Avalon

Vista - How to deploy an XAML-based App with its XAML-UI-File?

 
 
Old 11-01-2006   #1 (permalink)
Solveigh


 
 

How to deploy an XAML-based App with its XAML-UI-File?

Hi,

I'm new to WPF/XAML. The basic stuff is working fine, but now I would like
to deploy a simple application (C#, but more preferable Visual C++) with an
external XAML-file defining the GUI.
Are there any examples showing how to provide an app like this (e.g. that
makes it possible to edit the GUI-file without recompiling the whole project)?
I would be thankful for any hints on this question.

My System SpecsSystem Spec
Old 11-01-2006   #2 (permalink)
Brian Lenway


 
 

Re: How to deploy an XAML-based App with its XAML-UI-File?

In your application define a window with a StackPanel in it. Then read the
XAML file and use code like the following to render your XAML in the stack
panel. screenPanel is the name of the StackPanel in the XAML. errorText is
the name of a TextBox.

protected void displayScreen(string Xaml)
{
// Clear out any children from the stack panel.
this.screenPanel.Children.Clear();

errorText.Text = "";
if (Xaml == null || Xaml == "")
return;
try
{
MemoryStream ms = new MemoryStream();
StreamWriter sw = new StreamWriter(ms);
sw.Write(Xaml);
sw.Flush();
ms.Flush();
ms.Position = 0;
try
{
object content = XamlReader.Load(ms);
if (content != null)
{
this.screenPanel.Children.Add((UIElement)content);
}
errorText.Text = "";
}

catch (XamlParseException xpe)
{
// Display the error.
errorText.Text = xpe.Message.ToString();
}
}
catch (Exception)
{
// Obviously more should be done here.
return;
}
}

Hope this helps.

"Solveigh" <Solveigh@discussions.microsoft.com> wrote in message
news:C7606F01-A6AC-4F94-8B2E-A40DFFD586C4@microsoft.com...
> Hi,
>
> I'm new to WPF/XAML. The basic stuff is working fine, but now I would like
> to deploy a simple application (C#, but more preferable Visual C++) with
> an
> external XAML-file defining the GUI.
> Are there any examples showing how to provide an app like this (e.g. that
> makes it possible to edit the GUI-file without recompiling the whole
> project)?
> I would be thankful for any hints on this question.


My System SpecsSystem Spec
Old 11-06-2006   #3 (permalink)
Solveigh


 
 

Re: How to deploy an XAML-based App with its XAML-UI-File?

I have a XAML-file defining my window like this:
<Window x:Class="XAML_ReloadGUI.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="XAML_ReloadGUI" Height="353" Width="532"
>

<Grid>
<DockPanel VerticalAlignment="Top" Background="Azure" Height="25">
<TextBox Name="errorText" HorizontalAlignment="Left" ></TextBox>
<Button Height="25" VerticalAlignment="Top"
HorizontalAlignment="Right" Click="LoadStackPanel" Name="loadbtn">Load
StackPanel</Button>

</DockPanel>

<StackPanel Name="screenPanel" Margin="12.5,36.04,7.5,-47" >
<Button Height="25" Name="button1"
VerticalAlignment="Top" HorizontalAlignment="Left"
Width="80" Click="Btn1_Click">Button1</Button>
<Button HorizontalAlignment="Left" Margin="52,63,0,81"
Name="button2" Width="80" Click="Btn2_Click">Button2</Button>
<Button Height="25" Width="80" Margin="101,0,116,44" Name="button3"
Click="Btn3_Click">Button3</Button>
</StackPanel>
</Grid>
</Window>

In the underlying class I use this function to load the new StackPanel:
protected void displayScreen(string Xaml)
{
screenPanel.Children.Clear(); // clear out any children from
the stackpanel
errorText.Text = Xaml;
if (Xaml == null || Xaml == "")
return;
StringReader stringReader = null;
string xamlDocument = Xaml;
FileStream stream = null;
try
{
stringReader = new StringReader(Xaml);
stream = new FileStream(Xaml, FileMode.Open);
UIElement el = (UIElement)XamlReader.Load(stream);
this.screenPanel.Children.Add(el);
}
catch (Exception ex)
{
errorText.Text = ex.Message.ToString();
}
finally
{
if (stringReader != null) stringReader.Close();
}
}

The XAML-File I would like to load looks like this:
<Button
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="25" Margin="20,20,0,0" x:Name="button1"
VerticalAlignment="Top" HorizontalAlignment="Left"
Width="80" Click="Btn1_Click">Button No.1</Button>

Loading this File produces an error similar to "the xaml-file containing
events needs to be compiled". How can I avoid this?

"Brian Lenway" wrote:

> In your application define a window with a StackPanel in it. Then read the
> XAML file and use code like the following to render your XAML in the stack
> panel. screenPanel is the name of the StackPanel in the XAML. errorText is
> the name of a TextBox.
>
> protected void displayScreen(string Xaml)
> {
> // Clear out any children from the stack panel.
> this.screenPanel.Children.Clear();
>
> errorText.Text = "";
> if (Xaml == null || Xaml == "")
> return;
> try
> {
> MemoryStream ms = new MemoryStream();
> StreamWriter sw = new StreamWriter(ms);
> sw.Write(Xaml);
> sw.Flush();
> ms.Flush();
> ms.Position = 0;
> try
> {
> object content = XamlReader.Load(ms);
> if (content != null)
> {
> this.screenPanel.Children.Add((UIElement)content);
> }
> errorText.Text = "";
> }
>
> catch (XamlParseException xpe)
> {
> // Display the error.
> errorText.Text = xpe.Message.ToString();
> }
> }
> catch (Exception)
> {
> // Obviously more should be done here.
> return;
> }
> }
>
> Hope this helps.

My System SpecsSystem Spec
Old 11-07-2006   #4 (permalink)
Brian Lenway


 
 

Re: How to deploy an XAML-based App with its XAML-UI-File?

According to MS help you cannot include event handling in dynamically loaded
XAML. I don't know if there is a way around this.

"Solveigh" <Solveigh@discussions.microsoft.com> wrote in message
news:AF9430F6-6765-47D6-9147-F8C72EE8BB68@microsoft.com...
>I have a XAML-file defining my window like this:
> <Window x:Class="XAML_ReloadGUI.Window1"
> xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
> Title="XAML_ReloadGUI" Height="353" Width="532"
> >

> <Grid>
> <DockPanel VerticalAlignment="Top" Background="Azure" Height="25">
> <TextBox Name="errorText" HorizontalAlignment="Left" ></TextBox>
> <Button Height="25" VerticalAlignment="Top"
> HorizontalAlignment="Right" Click="LoadStackPanel" Name="loadbtn">Load
> StackPanel</Button>
>
> </DockPanel>
>
> <StackPanel Name="screenPanel" Margin="12.5,36.04,7.5,-47" >
> <Button Height="25" Name="button1"
> VerticalAlignment="Top" HorizontalAlignment="Left"
> Width="80" Click="Btn1_Click">Button1</Button>
> <Button HorizontalAlignment="Left" Margin="52,63,0,81"
> Name="button2" Width="80" Click="Btn2_Click">Button2</Button>
> <Button Height="25" Width="80" Margin="101,0,116,44" Name="button3"
> Click="Btn3_Click">Button3</Button>
> </StackPanel>
> </Grid>
> </Window>
>
> In the underlying class I use this function to load the new StackPanel:
> protected void displayScreen(string Xaml)
> {
> screenPanel.Children.Clear(); // clear out any children from
> the stackpanel
> errorText.Text = Xaml;
> if (Xaml == null || Xaml == "")
> return;
> StringReader stringReader = null;
> string xamlDocument = Xaml;
> FileStream stream = null;
> try
> {
> stringReader = new StringReader(Xaml);
> stream = new FileStream(Xaml, FileMode.Open);
> UIElement el = (UIElement)XamlReader.Load(stream);
> this.screenPanel.Children.Add(el);
> }
> catch (Exception ex)
> {
> errorText.Text = ex.Message.ToString();
> }
> finally
> {
> if (stringReader != null) stringReader.Close();
> }
> }
>
> The XAML-File I would like to load looks like this:
> <Button
> xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
> xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
> Height="25" Margin="20,20,0,0" x:Name="button1"
> VerticalAlignment="Top" HorizontalAlignment="Left"
> Width="80" Click="Btn1_Click">Button No.1</Button>
>
> Loading this File produces an error similar to "the xaml-file containing
> events needs to be compiled". How can I avoid this?
>
> "Brian Lenway" wrote:
>
>> In your application define a window with a StackPanel in it. Then read
>> the
>> XAML file and use code like the following to render your XAML in the
>> stack
>> panel. screenPanel is the name of the StackPanel in the XAML. errorText
>> is
>> the name of a TextBox.
>>
>> protected void displayScreen(string Xaml)
>> {
>> // Clear out any children from the stack panel.
>> this.screenPanel.Children.Clear();
>>
>> errorText.Text = "";
>> if (Xaml == null || Xaml == "")
>> return;
>> try
>> {
>> MemoryStream ms = new MemoryStream();
>> StreamWriter sw = new StreamWriter(ms);
>> sw.Write(Xaml);
>> sw.Flush();
>> ms.Flush();
>> ms.Position = 0;
>> try
>> {
>> object content = XamlReader.Load(ms);
>> if (content != null)
>> {
>> this.screenPanel.Children.Add((UIElement)content);
>> }
>> errorText.Text = "";
>> }
>>
>> catch (XamlParseException xpe)
>> {
>> // Display the error.
>> errorText.Text = xpe.Message.ToString();
>> }
>> }
>> catch (Exception)
>> {
>> // Obviously more should be done here.
>> return;
>> }
>> }
>>
>> Hope this helps.


My System SpecsSystem Spec
Old 11-07-2006   #5 (permalink)
Bob


 
 

Re: How to deploy an XAML-based App with its XAML-UI-File?

In article <46FE02FD-571A-49BB-817A-F428CD8EEC50@microsoft.com>,
ReplyToGroup@NotToEmail.com says...
> According to MS help you cannot include event handling in dynamically loaded
> XAML. I don't know if there is a way around this.
>
> "Solveigh" <Solveigh@discussions.microsoft.com> wrote in message
> news:AF9430F6-6765-47D6-9147-F8C72EE8BB68@microsoft.com...
> >I have a XAML-file defining my window like this:
> > <Window x:Class="XAML_ReloadGUI.Window1"
> > xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
> > xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
> > Title="XAML_ReloadGUI" Height="353" Width="532"
> > >

> > <Grid>
> > <DockPanel VerticalAlignment="Top" Background="Azure" Height="25">
> > <TextBox Name="errorText" HorizontalAlignment="Left" ></TextBox>
> > <Button Height="25" VerticalAlignment="Top"
> > HorizontalAlignment="Right" Click="LoadStackPanel" Name="loadbtn">Load
> > StackPanel</Button>
> >
> > </DockPanel>
> >
> > <StackPanel Name="screenPanel" Margin="12.5,36.04,7.5,-47" >
> > <Button Height="25" Name="button1"
> > VerticalAlignment="Top" HorizontalAlignment="Left"
> > Width="80" Click="Btn1_Click">Button1</Button>
> > <Button HorizontalAlignment="Left" Margin="52,63,0,81"
> > Name="button2" Width="80" Click="Btn2_Click">Button2</Button>
> > <Button Height="25" Width="80" Margin="101,0,116,44" Name="button3"
> > Click="Btn3_Click">Button3</Button>
> > </StackPanel>
> > </Grid>
> > </Window>
> >
> > In the underlying class I use this function to load the new StackPanel:
> > protected void displayScreen(string Xaml)
> > {
> > screenPanel.Children.Clear(); // clear out any children from
> > the stackpanel
> > errorText.Text = Xaml;
> > if (Xaml == null || Xaml == "")
> > return;
> > StringReader stringReader = null;
> > string xamlDocument = Xaml;
> > FileStream stream = null;
> > try
> > {
> > stringReader = new StringReader(Xaml);
> > stream = new FileStream(Xaml, FileMode.Open);
> > UIElement el = (UIElement)XamlReader.Load(stream);
> > this.screenPanel.Children.Add(el);
> > }


If you have control of the XAML that you want to load (it seems you do
as you know the 'button1' name and have an event handler already in
place), then remove the Click="Btn1_Click" from the XAML to load and
then at the end of your displayScreen(string Xaml) method add a hander
as in:
AddHandler(Button.ClickEvent, new RoutedEventHandler(Btn1_Click));

The Delegate has the same name as your existing handler (Btn1_Click)...
Note: you have to use a Type name (Button) not an instance name
(button1) in the first arg. This handler will respond to all buttons so
you will need to add some logic in the handler to filter out the button
your interested in from the sender param...
(If you don't have control of the XAML you may be able to do some string
(byte array?) gymnastics to dynamically filter out the event from the
XAML as you load it in)
This by no means a fix for anything other than your particular case but
it may help.
My System SpecsSystem Spec
Old 11-08-2006   #6 (permalink)
Solveigh


 
 

Re: How to deploy an XAML-based App with its XAML-UI-File?

"Bob" wrote:

> If you have control of the XAML that you want to load (it seems you do
> as you know the 'button1' name and have an event handler already in
> place), then remove the Click="Btn1_Click" from the XAML to load and
> then at the end of your displayScreen(string Xaml) method add a hander
> as in:
> AddHandler(Button.ClickEvent, new RoutedEventHandler(Btn1_Click));
>
> The Delegate has the same name as your existing handler (Btn1_Click)...
> Note: you have to use a Type name (Button) not an instance name
> (button1) in the first arg. This handler will respond to all buttons so
> you will need to add some logic in the handler to filter out the button
> your interested in from the sender param...
> (If you don't have control of the XAML you may be able to do some string
> (byte array?) gymnastics to dynamically filter out the event from the
> XAML as you load it in)
> This by no means a fix for anything other than your particular case but
> it may help.


After having read more on routed event handling I tried to implement this
suggestion.
The loaded XAML-File looks now like:
<Button Command="{x:Static custom:Window1.BtnEvent}"
CommandParameter="ButtonOne"
CommandTarget="{x:Static custom:Window1.BtnEventHandler}"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="25" Width="80" Margin="20,20,0,0" x:Name="button1"
VerticalAlignment="Top" HorizontalAlignment="Left">Button1</Button>

In the underlying class I defined
public static readonly RoutedEvent BtnEvent =
EventManager.RegisterRoutedEvent("Btn1_Click", RoutingStrategy.Direct,
typeof(RoutedEventHandler), typeof(System.Windows.Controls.Button));

If the loading would succed I would call
AddHandler( BtnEvent, new RoutedEventHandler(BtnEventHandler) );

But the loading of the XAML-File causes an error like The key may not be
NULL, Line 1, Position 9 (in german: Der Schlüssel darf nicht NULL sein). It
directs to the definition of the commandhandler.
Is it possible that this error is caused, because the added button does not
correspond to the window class and its formerly defined UI-elements?
My System SpecsSystem Spec
Old 11-08-2006   #7 (permalink)
Solveigh


 
 

Re: How to deploy an XAML-based App with its XAML-UI-File?

I found the solution:
the parent StackPanel has to look like this to redirect all children events
to a specified delegate function:
<StackPanel Name="screenPanel" Margin="17.5,103.04,199.5,-2"
Button.Click="BtnEventHandler"
xmlns:Butt="http://schemas.microsoft.com/winfx/2006/xaml/presentation">

After loading the new UI-file I call button1.Click += new
RoutedEventHandler(Btn1_Click);
My System SpecsSystem Spec
 

Thread Tools


Similar Threads
Thread Forum
Event in Xaml vs c# file. .NET General
Is it possible to include XAML files into another XAML file? .NET General


Vista Forums is an independent web site and has not been authorized,
sponsored, or otherwise approved by Microsoft Corporation.
"Windows Vista", the Start Orb, and related materials are trademarks of Microsoft Corp.
© Designer Media Ltd

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46