Forum Xamarin.Forms

Xaml-On-Demand

CaptainXamtasticCaptainXamtastic GBUniversity ✭✭✭

I have a use for loading Xaml-On-Demand and in that context would like to be able to load Styles (etc) from a string ... ... basically, anything with an x:Key ... and if loaded from a string, the Xaml could be obtained from anywhere, such as a WebService.

Is it likely that the XamlLoader will be made public in a near release, or a similar object (XamlReader?) be introduced?

Posts

  • MelbourneDeveloperMelbourneDeveloper AUMember ✭✭✭

    Try this code. It works perfectly, but it is not supported by the Xamarin Forms team. I still don't understand why they won't make these methods public, but that's another matter. BTW: This is modified from some other code I found on the web.

    public static class XamlReader
    {
        #region Fields
        private static readonly Func<BindableObject, string, BindableObject> loadXaml;
        #endregion
    
        #region Static Constructor
        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() ??
                                typeof(Xamarin.Forms.Xaml.Extensions)
                                    .GetMethods(BindingFlags.Static | BindingFlags.Public)
                                    .FirstOrDefault(m => m.GetParameters().Last().ParameterType == typeof(string));
    
            // If we didn't find it, it may be because the extension method may be public now :)
    
            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 });
            }
        }
        #endregion
    
        #region Private Static Methods
        /// <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);
        }
        #endregion
    
        #region Public Static Methods
        /// <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);
        }
        #endregion
    }
    
Sign In or Register to comment.