Powered by MSDN

US - English
NEW! Silverlight 5 is available Learn More

What happened to Control.InitializeFromXaml? RSS

26 replies

Last post Oct 12, 2008 11:06 AM by Rincewind60

(1)
  • RajeevGoel

    RajeevGoel

    Member

    38 Points

    37 Posts

    What happened to Control.InitializeFromXaml?

    Jun 08, 2008 05:26 AM | LINK

    Ack!  I just upgraded my Silverlight 2 application from Beta1 to Beta2, and it seems that the method Control.InitializeFromXaml has been removed!  Is there a replacement?  I desperately need this functionality.

     Thanks,

    Rajeev

  • Adrian Mascarenhas

    Adrian Masca...

    Member

    36 Points

    13 Posts

    Microsoft

    Re: What happened to Control.InitializeFromXaml?

    Jun 08, 2008 07:43 AM | LINK

    Hi Rajeev, 

    The quick way to fix this is to replace it with XamlReader.Load(string) method. However, this will not work if :

    • The control XAML includes event handlers. (XamlReader.Load() does not hook up events.)
    • The control XAML includes names. (XamlReader.Load() does not create a new namescope.)

     The recommended way to do this is:

     

    BEFORE:

        public class MyControl : Control

        {

            public MyControl() : base()

            {

                System.IO.Stream s = this.GetType().Assembly.GetManifestResourceStream("MyNamespace.UserControl1.xaml");

                FrameworkElement content = this.InitializeFromXaml(new System.IO.StreamReader(s).ReadToEnd());

                this.namedElement = (Rectangle) content.FindName("namedElement");

            }

            private Rectangle namedElement; // xaml contains x:Name="namedElement"

        }

     

    <Grid   

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

          <Rectangle x:Name="namedElement"/>

          <Ellipse />

    </Grid>

     

     

    AFTER:

        public class MyControl : UserControl

        {

            public MyControl() : base()

            {

                // if building outside VS

                Application.LoadComponent(this, new Uri("MyApp;component/MyControl.xaml", UriKind.Relative));

                FrameworkElement content = this.Content;

                this.namedElement = (Rectangle) content.FindName("namedElement");

            }

            private Rectangle namedElement; // xaml contains x:Name="namedElement"

        }

     

    <UserControl x:Class="Namespace.MyControl"

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        >

          <Grid>

                <Rectangle x:Name="namedElement"/>

                <Ellipse />

          </Grid>

    </UserControl>

     

    If you use VS to compile, it will generate a partial class for you so that all you need to do is call InitializeComponent:

     

        public partial class MyControl : UserControl

        {

            public MyControl() : base()

            {

                InitializeComponent();

            }

        }

    Hope this helps.

    Adrian Mascarenhas
    Microsoft
    This post is provided "as-is"
  • RajeevGoel

    RajeevGoel

    Member

    38 Points

    37 Posts

    Re: What happened to Control.InitializeFromXaml?

    Jun 08, 2008 05:49 PM | LINK

    I appreciate the quick response, but unfortunately this doesn't help.  I was previously using InitializeFromXaml precisely because my XAML contains event handlers and names.  (Frankly, any XAML that doesn't contain event handlers and names is a pretty useless piece of XAML.)  So I can't use XamlReader.Load.  I also can't use Application.LoadComponent because my XAML is not in a URI-addressable location or resource.  My XAML is in a local string variable. 

    I would really like to know the reason for removing the InitializeFromXaml API, and the possibilities around putting it back in.  I'm disappointed that the Silverlight team has chosen to remove important functionality, seemingly without consideration of the scenarios that it enabled.  I'm further frustrated that the removal of this API was not mentioned anywhere in any of the Beta2 documentation (http://msdn.microsoft.com/en-us/library/cc189007(vs.95).aspx), despite the fact that the docs enumerate in great detail every other major and minor change that was made between Beta1 and Beta2.  This leads me to wonder whether the decision to remove this important API was perhaps made by someone under the radar, carelessly, and without proper review.

     --Rajeev

     

  • Dave Relyea

    Dave Relyea

    Participant

    1090 Points

    252 Posts

    Microsoft

    Re: Re: What happened to Control.InitializeFromXaml?

    Jun 09, 2008 04:43 AM | LINK

    Application.LoadComponent works fine with event handlers. The generated InitializeComponent the VS makes when you create a new UserControl calls it.

    It is XamlReader that does not work with event handlers.

    Dave Relyea [MSFT]
    http://blogs.msdn.com/devdave
  • Tim Favour

    Tim Favour

    Member

    101 Points

    81 Posts

    Re: Re: What happened to Control.InitializeFromXaml?

    Jun 09, 2008 08:49 AM | LINK

    Hi, 

    I have a control inherited from Canvas that loads XAML as strings through a WCF service from the server. The XAML contains named elements but no event handlers.

    In Beta 1 I used XamlReader.Load to load the Xaml into the plugin and had no problems. In beta 2 the xaml gets loaded but all names are stripped. From the discussion above it seems such a thing is not possible anymore ?

    So tell me, how am I supposed to load a XAML string containing names into the Canvas ?? LoadComponent only works with uris.

    Tim

  • Tim Favour

    Tim Favour

    Member

    101 Points

    81 Posts

    Re: Re: What happened to Control.InitializeFromXaml?

    Jun 09, 2008 11:12 AM | LINK

    After reading this http://msdn.microsoft.com/en-us/library/cc189026(VS.95).aspx I understood the namescope issue and things work now.

    Tim

  • c007

    c007

    Member

    21 Points

    35 Posts

    Re: Re: What happened to Control.InitializeFromXaml?

    Jun 12, 2008 07:11 AM | LINK

    Hey Tim,  thank you so much for the link to the article.

    Would you mind sharing the code you used to go around the issue?

    I have in SL 2.0 Beta 1:

    FrameworkElement _rootElement = this.InitializeFromXaml(xamlString);

    where this is public abstract class ControlBase : Control

    and xamlString is a variable containing XAML with names (it's NOT a file accessible from a Uri).

    How can I reproduce the above in Beta 2 ???

  • Tim Favour

    Tim Favour

    Member

    101 Points

    81 Posts

    Re: Re: What happened to Control.InitializeFromXaml?

    Jun 12, 2008 09:24 AM | LINK

    Hi,

    What I did was to keep a list of all root elements that I have loaded through XamlReader.Load and then loop through all roots in the list and do a FindName on all of them thus searching all namespaces. Not very elegant or efficient but it works. Microsoft suggested a workaround that I haven't tried yet.

    Check out my answer here: http://silverlight.net/forums/p/17951/60325.aspx#60325

    Tim

  • RajeevGoel

    RajeevGoel

    Member

    38 Points

    37 Posts

    Re: Re: What happened to Control.InitializeFromXaml?

    Jun 12, 2008 05:51 PM | LINK

    I just wanted to point out that none of the workarounds or suggestions are fruitful when your XAML contains x:Name attributes and event handlers.  In Beta1, the InitializeFromXaml method handled this nicely, but that no longer exists in Beta2.  Some MSFTies have suggested using Application.LoadComponent, but that doesn't work either because it absolutely requires that the XAML be embedded as a resource in the same .DLL as the calling code.  (This is contrary to the documentation which states that LoadComponent would be able to find the XAML if it were a loose file at the application site of origin, i.e., on the web server.)  All this amounts to meaning that the XAML can't be changed or dynamically generated at run-time, which really sucks for me.

    It would cost MSFT nearly nothing to add an overload of LoadComponent that takes a string parameter for the input XAML directly (instead of a URI pointing at a resource), or to bring back the InitializeFromXaml method.  If I knew who to lobby to make that happen, I would.

    If it makes you feel better, you can go ahead and tell me that what I'm trying to do is not the recommended practice, but the fact is I need this functionality for the application I'm building.  Earlier this week, after I upgraded to Beta2, my blood was boiling when I came to realization that there was no way to build my app with the features I wanted anymore.  I would have to throw away 2 months of hard work, all because of this one tiny API that disappeared.  But now I've managed to calm myself down and use this experience as a valuable lesson about the nature of Microsoft Beta software.  I'm also finally starting to understand why most startups (even those founded by ex-Microsofties) tend to gravite toward non-Microsoft platforms.  They just don't have the time or resources to deal with this kind of flakiness and churn in the platform.

    --Rajeev

     

  • Kevmeister

    Kevmeister

    Member

    249 Points

    125 Posts

    Re: Re: What happened to Control.InitializeFromXaml?

    Jun 13, 2008 01:21 AM | LINK

    Are you generating the XAML on the client-side or the server side? If it was the server-side, I could understand because you need some kind of representational transfer mechanism. On the client side, it seems inefficient to construct XAML (as a string) and then re-parse that to produce the object representation. Why not just construct the object tree directly, hooking up all the event handlers as you go?

    RajeevGoel

    I would have to throw away 2 months of hard work, all because of this one tiny API that disappeared.  But now I've managed to calm myself down and use this experience as a valuable lesson about the nature of Microsoft Beta software.  I'm also finally starting to understand why most startups (even those founded by ex-Microsofties) tend to gravite toward non-Microsoft platforms.  They just don't have the time or resources to deal with this kind of flakiness and churn in the platform.

    I don't know why MS got rid of that function, and using my server-side comment above, if you want to have a server generate XAML and deliver it to the client it looks like you are now screwed - which is not a good thing from a functionality perspective (are you listening, Microsoft).

    BUT, basically you're crapped off because you placed a large dependency on a piece of software that in Beta form was well known could change from one release to the next. Everyone has come onto the platform with that prospect in mind, not just you. If you wanted certainty you should have waited for the 2.0 RTM release perhaps.

    I don't think Microsoft is right in eliminating a piece of functionality that looks like it would have proved useful, but I don't think you can necessarily chastise them for it to the degree you are because you knew what to expect.

    As for people gravitating to other platforms, my impression is that "other platforms" in Beta probably don't have the exposure that Microsoft has with Silverlight and therefore there will be less uptake and less likelihood of being "snookered" only because there are fewer developers. Please don't try intimate that by some miracle the Open Source community (for example) as a whole magically guarantees that their Beta software doesn't change APIs.