Thursday, December 2, 2010

Modular User interface

I was discussing with a friend some days ago about his project requirements.

  • Solution had roles but they where fixed (Like Manager, Receptionist etc)
  • Different UI is needed for each role
  • At runtime there should be a way to change the UI using an action

He told me that he was aware of eXpand Role models and he thought that they could help his case.

For those of you that are XAF newbies a XAF model is really a description of your application structure /behavior over a xafml file

Sure I told him ModelDifference module can help , however the approach would be slightly different from the one you had in your mind and here is why:

Although the application have roles since there is no login (wanted to change UI from an action ) we could not use ModelDifference Role models.  What I suggested was to use disabled application models and then use eXpand api to just enabled them at runtime. In fact we could create as many application models as the fixed roles are in the updater with a code similar to

    public class Updater : ModuleUpdater {

        public Updater(Session session, Version currentDBVersion) : base(session, currentDBVersion) { }

        public override void UpdateDatabaseAfterUpdateSchema() {

            base.UpdateDatabaseAfterUpdateSchema();

            CreateDisabledModelDifferenceObject(typeof(ManagerModelStore));

            CreateDisabledModelDifferenceObject(typeof(ReceptionistModelStore));

        }

 

        void CreateDisabledModelDifferenceObject(Type storeBaseType) {

            var modelDifferenceObject = Session.FindObject<ModelDifferenceObject>(o => o.Name == storeBaseType.Name);

            if (modelDifferenceObject == null) {

                ModelDifferenceObject differenceObject = new ModelDifferenceObject(Session).InitializeMembers(storeBaseType.Name);

                var layer = new ModelApplicationBuilder(differenceObject.PersistentApplication.ExecutableName).GetLayer(storeBaseType);

                differenceObject.CreateAspects(layer);

                differenceObject.Disabled = true;

                differenceObject.Save();

            }

        }

    }

 

also we need 2 modelstores that will point to our Manager,Receptionist models

 

    public class ReceptionistModelStore : ModelApplicationFromStreamStoreBase {

        protected override Stream GetStream() {

            return GetType().Assembly.GetManifestResourceStream(GetType(), "Receptionist.xafml");

        }

    }

    public class ManagerModelStore : ModelApplicationFromStreamStoreBase {

        protected override Stream GetStream() {

            return GetType().Assembly.GetManifestResourceStream(GetType(), "Manager.xafml");

        }

    }

  

2 design time models Manager.xafml,Receptionist.xafml

image

 

of course eXpand Model Editor addin in order to be able to modify the models

image

 

The code we wrote at the update will create 2 disabled application models in our modeldifference listview as shown bellow

image

Disabled models means that they wont load when application starts. In order to load them on demand we have to create some actions and use ModelDifference api. A simple controller like the one bellow will do the job.

 

using DevExpress.ExpressApp;

using DevExpress.ExpressApp.Actions;

using DevExpress.ExpressApp.Win;

using DevExpress.Persistent.Base;

using Xpand.ExpressApp.ModelDifference.Core;

 

namespace Solution1.Module.Win {

    public class ActionsController : ViewController {

 

        public ActionsController() {

            var managerAction = new SimpleAction(this, "Manager", PredefinedCategory.View);

            managerAction.Execute += ManagerActionOnExecute;

            var receptionistAction = new SimpleAction(this, "Receptionist", PredefinedCategory.View);

            receptionistAction.Execute += ReceptionistActionOnExecute;

        }

 

        void ReceptionistActionOnExecute(object sender, SimpleActionExecuteEventArgs simpleActionExecuteEventArgs) {

            var modelApplicationLoader = new ModelApplicationLoader();

            modelApplicationLoader.EnableModel(o => o.Name == "ReceptionistModelStore", new[] { "ManagerModelStore" });

            RecreateWindows();

        }

 

        void ManagerActionOnExecute(object sender, SimpleActionExecuteEventArgs simpleActionExecuteEventArgs) {

            var modelApplicationLoader = new ModelApplicationLoader();

            modelApplicationLoader.EnableModel(o => o.Name == "ManagerModelStore", new[] { "ReceptionistModelStore" });

            RecreateWindows();

        }

 

        void RecreateWindows() {

            var showViewStrategyBase = (WinShowViewStrategyBase)Application.ShowViewStrategy;

            showViewStrategyBase.CloseAllWindows();

            showViewStrategyBase.ShowStartupWindow();

        }

    }

}

and that was it!!
The above solution needs eXpand v10.1.8 or newer http://expandframework.com/download.html

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

0 comments:

Post a Comment