예제 #1
0
        /// <summary>
        /// Loads the component template of the specified control.
        /// </summary>
        /// <param name="control">The instance of <see cref="Control"/> for which to load a component root.</param>
        /// <param name="template">The component template that specifies the control's component layout.</param>
        /// <returns>The <see cref="UIElement"/> which serves as the specified control's component template.</returns>
        public static UIElement LoadComponentTemplate(Control control, XDocument template)
        {
            Contract.Require(control, nameof(control));

            if (template == null)
            {
                return(null);
            }

            var componentContext  = UvmlInstantiationContext.ForControl(control.Ultraviolet, control);
            var componentTemplate = default(UvmlTemplate);

            if (!componentTemplateCache.TryGetValue(template, out componentTemplate))
            {
                var componentElement = template.Root.Element("View")?.Elements().SingleOrDefault();
                if (componentElement == null)
                {
                    return(null);
                }

                var componentType = default(Type);
                if (!control.Ultraviolet.GetUI().GetPresentationFoundation().GetKnownType(componentElement.Name.LocalName, out componentType))
                {
                    throw new UvmlException(PresentationStrings.UnrecognizedType.Format(componentElement.Name.LocalName));
                }

                var cultureRequested = (String)template.Root.Attribute("Culture");
                var cultureInfo      = CultureInfo.GetCultureInfo(cultureRequested ?? String.Empty);

                AddUvmlAnnotations(componentContext.DataSourceType.Name, componentElement);

                componentTemplate = CreateTemplateFromXml(control.Ultraviolet, componentElement, control.GetType(), componentType, cultureInfo);
                componentTemplateCache[template] = componentTemplate;
            }

            var componentTemplateInstance = (UvmlTemplateInstance)componentTemplate.Instantiate(control.Ultraviolet, componentContext);
            var component = (UIElement)componentTemplateInstance.FinalizeInstance();

            componentContext.Namescope.PopulateFieldsFromRegisteredElements(control);

            return(component);
        }
예제 #2
0
        /// <summary>
        /// Loads the content of the template as an instance of an object and returns the root element of the content.
        /// </summary>
        /// <param name="dataSource">The object's data source.</param>
        /// <param name="dataSourceType">The object's data source type.</param>
        /// <returns>The root element of the content.</returns>
        public DependencyObject LoadContent(Object dataSource, Type dataSourceType)
        {
            var uv        = UltravioletContext.DemandCurrent();
            var namescope = default(Namescope);
            var wrapper   = CreateDataSourceWrapper(dataSource, out namescope);
            var context   = new UvmlInstantiationContext(uv, null, wrapper, wrapper?.GetType(), namescope);
            var dobj      = (DependencyObject)((UvmlTemplateInstance)template.Instantiate(uv, context)).Finalize();

            var element = dobj as FrameworkElement;

            if (element != null)
            {
                element.TemplatedNamescope = namescope;
            }

            if (dataSource != null)
            {
                namescope.PopulateFieldsFromRegisteredElements(dataSource);
            }

            return(dobj);
        }
예제 #3
0
        /// <summary>
        /// Loads an instance of the <see cref="PresentationFoundationView"/> from an XML node.
        /// </summary>
        /// <param name="uv">The Ultraviolet context.</param>
        /// <param name="uiPanel">The <see cref="UIPanel"/> that is creating the panel.</param>
        /// <param name="uiPanelDefinition">The <see cref="UIPanelDefinition"/> that defines the view.</param>
        /// <param name="vmfactory">A view model factory which is used to create the view's initial view model, or <see langword="null"/> to skip view model creation.</param>
        /// <returns>The <see cref="PresentationFoundationView"/> that was loaded from the specified XML element.</returns>
        public static PresentationFoundationView Load(UltravioletContext uv, UIPanel uiPanel, UIPanelDefinition uiPanelDefinition, UIViewModelFactory vmfactory)
        {
            Contract.Require(uv, nameof(uv));
            Contract.Require(uiPanel, nameof(uiPanel));
            Contract.Require(uiPanelDefinition, nameof(uiPanelDefinition));

            var viewElement = uiPanelDefinition.ViewElement;

            if (viewElement == null)
            {
                return(null);
            }

            // Determine which culture to use when parsing values.
            var cultureRequested = (String)uiPanelDefinition.RootElement.Attribute("Culture");
            var cultureInfo      = CultureInfo.GetCultureInfo(cultureRequested ?? String.Empty);

            // Determine the type of view model used by this view.
            var viewModelType     = default(Type);
            var viewModelTypeName = (String)viewElement.Attribute("ViewModelType");

            if (viewModelTypeName != null)
            {
                viewModelType = Type.GetType(viewModelTypeName, false);

                if (viewModelType == null)
                {
                    throw new UvmlException(PresentationStrings.ViewModelTypeNotFound.Format(viewModelTypeName));
                }

                var viewModelWrapperAttr = viewModelType.GetCustomAttributes(typeof(ViewModelWrapperAttribute), false)
                                           .Cast <ViewModelWrapperAttribute>().SingleOrDefault();
                if (viewModelWrapperAttr != null)
                {
                    viewModelType = viewModelWrapperAttr.WrapperType;
                }
                else
                {
                    var viewModelWrapperName = PresentationFoundationView.GetDataSourceWrapperNameForView(uiPanelDefinition.AssetFilePath);
                    var viewModelWrapperType = uv.GetUI().GetPresentationFoundation().GetDataSourceWrapperTypeByName(viewModelWrapperName);
                    if (viewModelWrapperType == null)
                    {
                        throw new UvmlException(PresentationStrings.CannotFindViewModelWrapper.Format(viewModelWrapperName));
                    }

                    viewModelType = viewModelWrapperType;
                }
            }

            // Create a UVML template which will instantiate the view.
            var viewTemplate = new UvmlTemplate(viewElement, typeof(PresentationFoundationView), (puv, pname) =>
            {
                var view      = new PresentationFoundationView(puv, uiPanel, viewModelType);
                var viewModel = vmfactory == null ? null : vmfactory(view);
                if (viewModel != null)
                {
                    view.SetViewModel(viewModel);
                }

                var root = view.LayoutRoot;
                root.BeginInit();

                var rootAdornerDecorator = new AdornerDecorator(puv, null);
                rootAdornerDecorator.BeginInit();
                root.Child = rootAdornerDecorator;

                var rootGridTemplate = CreateTemplateFromXml(puv, viewElement, null, typeof(Grid), cultureInfo);
                var rootGridContext  = UvmlInstantiationContext.ForView(puv, view);

                var rootGridTemplateInstance = (UvmlTemplateInstance)rootGridTemplate.Instantiate(puv, rootGridContext);
                var rootGrid = (Grid)rootGridTemplateInstance.Finalize();

                rootAdornerDecorator.Child = rootGrid;

                return(view);
            });

            // Instantiate the view template.
            var viewTemplateInstance = (UvmlTemplateInstance)viewTemplate.Instantiate(uv, null);
            var viewInstance         = (PresentationFoundationView)viewTemplateInstance.Finalize();

            var viewRoot = viewInstance.LayoutRoot;
            var viewRootAdornerDecorator = (AdornerDecorator)viewRoot.Child;

            viewRootAdornerDecorator.EndInit();
            viewRoot.EndInit();
            viewRoot.CacheLayoutParameters();

            var viewInstanceViewModel = viewInstance.ViewModel;

            if (viewInstanceViewModel != null)
            {
                viewInstance.Namescope.PopulateFieldsFromRegisteredElements(viewInstanceViewModel);
            }

            return(viewInstance);
        }