locked
Load Xaml Dynamically At Runtime RRS feed

  • Question

  • User37558 posted

    Everybody knows that this is an absolute necessity. Everybody is howling about this, and has been for years. However, it still seems as though it is impossible, through normal means to render Xamarin Forms UI at runtime with dynamic Xaml. I'm not really interested in why this hasn't been done yet. What I want to know is WHEN is it going to be done? And, if there is no answer to that, how do we work around this gaping, chasm of a deficiency?

    As I see it, there may be two possible approaches to working around this disgusting, blatant inadequacy:

    1) Write a Xaml parser that dynamically builds objects and sets their bindings programmatically. This will be hard work, and I don't have time to be doing this. Has anyone else started an open source project to try to achieve this?

    2) Take the internal XamlLoader (https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Xaml/XamlLoader.cs) code, and make a version which is public. Has anyone had any luck doing this?

    Note: incidentally, you can see the code for the XamlLoader here: https://github.com/xamarin/Xamarin.Forms/blob/master/Xamarin.Forms.Xaml/XamlLoader.cs . There doesn't seem to be an explanation for why this class is not public.

    Wednesday, February 1, 2017 1:59 AM

Answers

  • User37558 posted

    In short, my problem has been successfully worked around. But, a) I have not tested this code in all scenarios. And, b) the next guy who wants to do what I want to do will be asking exactly the same question because as you can see from the code above, the Xamarin Forms team have inexplicably left the "LoadFromXaml" method, and the "XamlLoader" class internal. So, as @NMackay pointed out, I have created a thread on the Xamarin.Forms Evolution board here:

    https://forums.xamarin.com/discussion/87810/please-make-xamlloader-public

    If you are reading this and want to achieve the same result as us, please take the time to put your comments on this thread and request that the Xamarin Forms team make the method public.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Wednesday, February 1, 2017 10:13 PM
  • User37558 posted

    I have been working on a library and I have included dynamic rendering of XAML. According to the Xamarin Forms team, they are not intending on disabling the dynamic functionality so I think you would be safe to use this. Clone this repo to see the sample:

    https://github.com/MelbourneDeveloper/Adapt.Presentation.git

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Saturday, July 1, 2017 8:15 AM

All replies

  • User76049 posted

    I'd post this on the evolution forum, if you post it here it'll just fall away and not get attention. Follow the posting guidelines though or it will be removed.

    https://forums.xamarin.com/categories/xamarin-forms-evolution

    I was looking into this recently but opted for loading contentviews into a viewcell in a LIstview (RadListview in my case but it works with vanilla listview too) and a bit of Prism magic to autowize the contentview's to the correct binding context. This way I can build teh users dashboard based on their security rights.

    Wednesday, February 1, 2017 10:01 AM
  • User37558 posted

    I have half an answer. This article provides some kind of workaround: http://www.cazzulino.com/dynamic-forms.html

    The writer of this article has provided his code here: https://github.com/MobileEssentials/DynamicForms/blob/master/src/Xamarin.Forms.Dynamic.Desktop/BindingObjectExtensions.cs#L38

    I modified this code slightly to make it less ugly and more like Silverlight/WPF/UWP:

    public static class XamlReader
    {
        static Func<BindableObject, string, BindableObject> loadXaml;
    
        static XamlReader()
        {
            // This is the current situation, where the LoadFromXaml is the only non-public static method.
            var genericMethod = typeof(Xamarin.Forms.Xaml.Extensions)
                .GetMethods(BindingFlags.Static | BindingFlags.NonPublic).FirstOrDefault();
    
            // If we didn't find it, it may be because the extension method may be public now :)
            if (genericMethod == null)
                genericMethod = typeof(Xamarin.Forms.Xaml.Extensions)
                .GetMethods(BindingFlags.Static | BindingFlags.Public)
                .FirstOrDefault(m => m.GetParameters().Last().ParameterType == typeof(string));
    
            if (genericMethod == null)
            {
                loadXaml = (view, xaml) => { throw new NotSupportedException("Xamarin.Forms implementation of XAML loading not found. Please update the Dynamic nuget package."); };
            }
            else
            {
                genericMethod = genericMethod.MakeGenericMethod(typeof(BindableObject));
                loadXaml = (view, xaml) => (BindableObject)genericMethod.Invoke(null, new object[] { view, xaml });
            }
        }
    
        /// <summary>
        /// Applies the given XAML to the view.
        /// </summary>
        private static TView LoadFromXaml<TView>(this TView view, string xaml) where TView : BindableObject
        {
            return (TView)loadXaml(view, xaml);
        }
    
        /// <summary>
        /// Applies the given XAML to the view.
        /// </summary>
        public static TView LoadFromXaml<TView>(string xaml) where TView : BindableObject
        {
            var theView = (TView)Activator.CreateInstance(typeof(TView));
            return LoadFromXaml(theView, xaml);
        }
    
    }
    
    Wednesday, February 1, 2017 10:10 PM
  • User37558 posted

    In short, my problem has been successfully worked around. But, a) I have not tested this code in all scenarios. And, b) the next guy who wants to do what I want to do will be asking exactly the same question because as you can see from the code above, the Xamarin Forms team have inexplicably left the "LoadFromXaml" method, and the "XamlLoader" class internal. So, as @NMackay pointed out, I have created a thread on the Xamarin.Forms Evolution board here:

    https://forums.xamarin.com/discussion/87810/please-make-xamlloader-public

    If you are reading this and want to achieve the same result as us, please take the time to put your comments on this thread and request that the Xamarin Forms team make the method public.

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Wednesday, February 1, 2017 10:13 PM
  • User37558 posted

    The Xamarin Forms team eventually closed this topic...

    Tuesday, June 20, 2017 3:05 AM
  • User37558 posted

    I have been working on a library and I have included dynamic rendering of XAML. According to the Xamarin Forms team, they are not intending on disabling the dynamic functionality so I think you would be safe to use this. Clone this repo to see the sample:

    https://github.com/MelbourneDeveloper/Adapt.Presentation.git

    • Marked as answer by Anonymous Thursday, June 3, 2021 12:00 AM
    Saturday, July 1, 2017 8:15 AM
  • User29117 posted

    @MelbourneDeveloper said: I have been working on a library and I have included dynamic rendering of XAML. According to the Xamarin Forms team, they are not intending on disabling the dynamic functionality so I think you would be safe to use this. Clone this repo to see the sample:

    https://github.com/MelbourneDeveloper/Adapt.Presentation.git

    I assume this has been taken down since then? Was looking forward to seeing your example

    Wednesday, January 24, 2018 1:32 PM