locked
Loading XAML at runtime with events RRS feed

  • Question

  •  Hi,
        I have a XAML that looks something like this

    <TabItem Header="A" xmlns="..." xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="Test.TabItemOne" >
    ...
    ...
    <Button Content="Press" Click="Show" />
    </TabItem>

    This is linked to a partial class defenition using c# and the event handler for the button is written as follows

    namespace Test
    {
    public
    partial class TabItemOne : TabItem
    {
        public TabItemOne()
        {
        }
        void Show(object sender, RoutedEventArgs e)
        
    {
        MessageBox
    .Show("Click");
        }
    }

    }

    I am loading the TabItem at runtime using XamlReader.Load()  like this..
    TabItem tabOne;
    FileStream fstream = (FileStream)File.Open("TabItemOne.xaml", FileMode.Open, FileAccess.Read);
    tabOne = (
    TabItem)XamlReader.Load(fstream);
    tabCtrl.Items.Add(tabOne);


    The project compiles fine. But when i run, it throws an exception saying that the class attribute is not present in that namespace.

    My question really is...
    I have XAML code which contains TabItems. Each TabItem contains controls within it and there are events fired for each of these controls that are in the TabItem.
    Based on a certain selection in my application, I want to load different Tabitems stored in different XAML files at runtime and put them in a Tab Control. 
    Does anyone know how to do this... or what am i doing wrong in the above block of code?

    Please Help..

    Regards
    Sharath
    Wednesday, June 11, 2008 1:38 PM

Answers

  • Hi Sharath,

        Your project compiles fine because there is no validation done to loosely included Xaml files (only reason you'd need to use to use File.Open).  The "Class" attribute and event hookup are not meant to work with loose Xaml... rather, there is a process that turns a .xaml and .xaml.cs file into .g.cs files and compiles them to "BAML".   Setting up events or declaring a class will simply not work for loose XAML.

    If you have a legitimate reason to load the XAML at runtime like this, there are definitely ways to make it work.  The best I think would be to set up your Button's Click event handlers and whatever other special behavior in the .ctor for TabItemOne ...  this way, you can indeed reference the namespace and assembly TabItemOne is contained within, the event gets hooked up, and everything is happy, like below:

    xmlns:myNameSpace="clr-namespace:Namespace.Of.TabItemOneClass" 
    ...  
    <myNameSpace:TabItemOne Grid.Row = "1" ... /> 

    Another solution would be to not include events, just name controls, and find the controls manually and set up events after loading the XAML. 

    Hope this helps,
    Matt
    SDET : Deployment/Hosting
    • Marked as answer by Marco Zhou Tuesday, June 17, 2008 10:20 AM
    Wednesday, June 11, 2008 6:31 PM
  • in .NET 4 you can load loose XAML with events in it. there are 2 approaches for doing this.
    Please take a look at the post
    http://blogs.msdn.com/llobo/archive/2009/11/11/xaml-2009-features-xaml-event-handling.aspx
    Friday, January 29, 2010 4:20 PM

All replies

  • Hi Sharath,

        Your project compiles fine because there is no validation done to loosely included Xaml files (only reason you'd need to use to use File.Open).  The "Class" attribute and event hookup are not meant to work with loose Xaml... rather, there is a process that turns a .xaml and .xaml.cs file into .g.cs files and compiles them to "BAML".   Setting up events or declaring a class will simply not work for loose XAML.

    If you have a legitimate reason to load the XAML at runtime like this, there are definitely ways to make it work.  The best I think would be to set up your Button's Click event handlers and whatever other special behavior in the .ctor for TabItemOne ...  this way, you can indeed reference the namespace and assembly TabItemOne is contained within, the event gets hooked up, and everything is happy, like below:

    xmlns:myNameSpace="clr-namespace:Namespace.Of.TabItemOneClass" 
    ...  
    <myNameSpace:TabItemOne Grid.Row = "1" ... /> 

    Another solution would be to not include events, just name controls, and find the controls manually and set up events after loading the XAML. 

    Hope this helps,
    Matt
    SDET : Deployment/Hosting
    • Marked as answer by Marco Zhou Tuesday, June 17, 2008 10:20 AM
    Wednesday, June 11, 2008 6:31 PM
  • Hi, Matt!
    I also wanna join to this interesting question, but wanna extend it to more convenient architecture. As we know, XAML form compiled into three files: form.cs - user's code, form.baml - binary XAML presentation and form.g.cs - most interesting stuff, glue code which AUTOMATICALLY joins controls with handlers. So question: why we cannot have project like this:
    form.cs - our custom code
    form.g.cs - generated glue
    form.layout1.baml
    form.layout2.baml
    ...and so on...
    At runtime we create form and just load one of predefined BAMLs, which automatically join necessary handlers?
    But it's just my theory, how PRACTICALLY do it?
    Friday, January 29, 2010 8:39 AM
  • in .NET 4 you can load loose XAML with events in it. there are 2 approaches for doing this.
    Please take a look at the post
    http://blogs.msdn.com/llobo/archive/2009/11/11/xaml-2009-features-xaml-event-handling.aspx
    Friday, January 29, 2010 4:20 PM