예제 #1
0
        /// <summary>
        /// Gets an <see cref="IMVCController" />  for a given document type, and finding the right GUI user control for it.
        /// </summary>
        /// <param name="args">The argument list. The first element args[0] is the document for which the controller is searched. The following elements are
        /// optional, and are usually the parents of this document.</param>
        /// <param name="overrideArg0Type">If this parameter is not null, this given type is used instead of determining the type of the <c>arg[0]</c> argument.</param>
        /// <param name="expectedControllerType">Type of controller that you expect to return.</param>
        /// <param name="copyDocument">Determines whether to use the document directly or a cloned copy.</param>
        /// <returns>The controller for that document when found. The controller is already initialized with the document. If no controller is found for the document, or if no GUI control is found for the controller, the return value is null.</returns>
        public IMVCController GetControllerAndControl(object[] args, System.Type overrideArg0Type, System.Type expectedControllerType, UseDocument copyDocument)
        {
            if (!ReflectionService.IsSubClassOfOrImplements(expectedControllerType, typeof(IMVCController)))
            {
                throw new ArgumentException("Expected controller type has to be IMVCController or a subclass or derived class of this");
            }

            IMVCController controller = GetController(args, overrideArg0Type, typeof(IMVCController), copyDocument);

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

            FindAndAttachControlTo(controller);

            return(controller);
        }
예제 #2
0
        /// <summary>
        /// Try to attach a control to the controller. To determine the type of gui, the viewTemplate is analysed.
        /// </summary>
        /// <param name="controller"></param>
        /// <param name="viewTemplate"></param>
        public void FindAndAttachControlUsingGuiTemplate(IMVCController controller, object viewTemplate)
        {
            foreach (var guiType in RegisteredGuiTechnologies)
            {
                if (ReflectionService.IsSubClassOfOrImplements(viewTemplate.GetType(), guiType))
                {
                    InternalFindAndAttachControlUsingGuiType(controller, guiType);
                    if (controller.ViewObject != null)
                    {
                        return;
                    }
                }
            }

            if (controller.ViewObject == null)
            {
                FindAndAttachControlTo(controller);
            }
        }
예제 #3
0
        /// <summary>
        /// Gets an <see cref="IMVCController" />  for a given document type.
        /// </summary>
        /// <param name="creationArgs">The argument list. The first element args[0] is the document for which the controller is searched. The following elements are
        /// optional, and are usually the parents of this document.</param>
        /// <param name="overrideArg0Type">If this parameter is not null, this given type is used instead of determining the type of the <c>arg[0]</c> argument.</param>
        /// <param name="expectedControllerType">Type of controller that you expect to return.</param>
        /// <param name="copyDocument">Determines wether to use the document directly or use a clone of the document.</param>
        /// <returns>The controller for that document when found.</returns>
        public IMVCController GetController(object[] creationArgs, System.Type overrideArg0Type, System.Type expectedControllerType, UseDocument copyDocument)
        {
            if (!ReflectionService.IsSubClassOfOrImplements(expectedControllerType, typeof(IMVCController)))
            {
                throw new ArgumentException("Expected controller type has to be IMVCController or a subclass or derived class of this");
            }

            object result = null;

            // 1st search for all classes that wear the UserControllerForObject attribute
            ReflectionService.IAttributeForClassList list = ReflectionService.GetAttributeInstancesAndClassTypesForClass(typeof(UserControllerForObjectAttribute), creationArgs[0], overrideArg0Type);

            foreach (Type definedType in list.Types)
            {
                if (ReflectionService.IsSubClassOfOrImplements(definedType, typeof(IMVCANController)))
                {
                    IMVCANController mvcan = (IMVCANController)Activator.CreateInstance(definedType);
                    mvcan.UseDocumentCopy = copyDocument;
                    if (mvcan.InitializeDocument(creationArgs))
                    {
                        result = mvcan;
                    }
                }
                else
                {
                    result = ReflectionService.CreateInstanceFromList(list, new Type[] { expectedControllerType }, creationArgs);
                }

                if (result is IMVCController)
                {
                    break;
                }
            }

            return((IMVCController)result);
        }
예제 #4
0
        /// <summary>
        /// Searchs for a appropriate control for a given controller and attaches the control to the controller.
        /// </summary>
        /// <param name="controller">The controller a control is searched for.</param>
        public void FindAndAttachControlTo(IMVCController controller)
        {
            // if the controller has
            System.Type ct             = controller.GetType();
            object[]    viewattributes = ct.GetCustomAttributes(typeof(ExpectedTypeOfViewAttribute), false);

            if (viewattributes != null && viewattributes.Length > 0)
            {
                if (viewattributes.Length > 1)
                {
                    Array.Sort(viewattributes);
                }

                foreach (ExpectedTypeOfViewAttribute attr in viewattributes)
                {
                    Type[] controltypes = ReflectionService.GetNonAbstractSubclassesOf(new System.Type[] { typeof(System.Windows.Forms.Control), attr.TargetType });
                    foreach (Type controltype in controltypes)
                    {
                        // test if the control has a special preference for a controller...
                        object[] controlForAttributes = controltype.GetCustomAttributes(typeof(UserControlForControllerAttribute), false);
                        if (controlForAttributes.Length > 0)
                        {
                            bool containsControllerType = false;
                            foreach (UserControlForControllerAttribute controlForAttr in controlForAttributes)
                            {
                                if (ReflectionService.IsSubClassOfOrImplements(ct, controlForAttr.TargetType))
                                {
                                    containsControllerType = true;
                                    break;
                                }
                            }
                            if (!containsControllerType)
                            {
                                continue; // then this view is not intended for our controller
                            }
                        }

                        // all seems ok, so we can try to create the control
                        object controlinstance = System.Activator.CreateInstance(controltype);
                        if (null == controlinstance)
                        {
                            throw new ApplicationException(string.Format("Searching a control for controller of type {0}. Find control type {1}, but it was not possible to create a instance of this type.", ct, controltype));
                        }

                        controller.ViewObject = controlinstance;

                        if (controller.ViewObject == null)
                        {
                            throw new ApplicationException(string.Format("Searching a control for controller of type {0}. Find control type {1}, but the controller did not accept this control.", ct, controltype));
                        }

                        return;
                    }
                }
            }
            else // Controller has no ExpectedTypeOfView attribute
            {
                System.Windows.Forms.UserControl control =
                    (System.Windows.Forms.UserControl)ReflectionService.GetClassForClassInstanceByAttribute(
                        typeof(UserControlForControllerAttribute),
                        new System.Type[] { typeof(System.Windows.Forms.UserControl) },
                        new object[] { controller });

                if (control == null)
                {
                    return;
                }

                controller.ViewObject = control;
            }
        }
예제 #5
0
        /// <summary>
        /// Searchs for a appropriate control for a given controller and attaches the control to the controller.
        /// </summary>
        /// <param name="controller">The controller a control is searched for.</param>
        /// <param name="guiControlType">Base type of the underlying Gui system.</param>
        private void InternalFindAndAttachControlUsingGuiType(IMVCController controller, System.Type guiControlType)
        {
            // if the controller has
            System.Type ct             = controller.GetType();
            object[]    viewattributes = ct.GetCustomAttributes(typeof(ExpectedTypeOfViewAttribute), false);
            if (null == viewattributes || viewattributes.Length == 0)
            {
                viewattributes = ct.GetCustomAttributes(typeof(ExpectedTypeOfViewAttribute), true);
            }

            bool isInvokeRequired = Current.Dispatcher.InvokeRequired;

            if (viewattributes != null && viewattributes.Length > 0)
            {
                if (viewattributes.Length > 1)
                {
                    Array.Sort(viewattributes);
                }

                foreach (ExpectedTypeOfViewAttribute attr in viewattributes)
                {
                    Type[] controltypes = ReflectionService.GetNonAbstractSubclassesOf(new System.Type[] { guiControlType, attr.TargetType });
                    if (controltypes.Length > 1)
                    {
                        // retrieve priorities for the types, and then sort controltypes using priority descending

                        var priorities = new int[controltypes.Length];
                        for (int i = 0; i < controltypes.Length; ++i)
                        {
                            object[] pattributes = controltypes[i].GetCustomAttributes(typeof(UserControlPriorityAttribute), false);
                            if (null != pattributes && pattributes.Length > 0)
                            {
                                priorities[i] = -((UserControlPriorityAttribute)pattributes[0]).Priority;
                            }
                        }
                        Array.Sort(priorities, controltypes); // the negation of priority (see above) ensures that the sorting is priority descending
                    }

                    foreach (Type controltype in controltypes)
                    {
                        // test if the control has a special preference for a controller...
                        object[] controlForAttributes = controltype.GetCustomAttributes(typeof(UserControlForControllerAttribute), false);
                        if (controlForAttributes.Length > 0)
                        {
                            bool containsControllerType = false;
                            foreach (UserControlForControllerAttribute controlForAttr in controlForAttributes)
                            {
                                if (ReflectionService.IsSubClassOfOrImplements(ct, controlForAttr.TargetType))
                                {
                                    containsControllerType = true;
                                    break;
                                }
                            }
                            if (!containsControllerType)
                            {
                                continue; // then this view is not intended for our controller
                            }
                        }

                        // all seems ok, so we can try to create the control

                        if (isInvokeRequired)
                        {
                            Current.Dispatcher.InvokeIfRequired(CreateAndAttachControlOfType, controller, controltype);
                        }
                        else
                        {
                            CreateAndAttachControlOfType(controller, controltype);
                        }
                        return;
                    }
                }
            }
            else // Controller has no ExpectedTypeOfView attribute
            {
                if (isInvokeRequired)
                {
                    Current.Dispatcher.InvokeIfRequired(CreateControlForControllerWithNoExpectedTypeOfViewAttribute, controller, guiControlType);
                }
                else
                {
                    CreateControlForControllerWithNoExpectedTypeOfViewAttribute(controller, guiControlType);
                }
            }
        }