Using non persistent objects to display modal dialogs in your XAF web application

A XAF web application does not include any build-in functionality to show modal dialog forms. One possibility to empower your XAF web application for such functionality is the corresponding usage of non-persistant business objects.

Defining a non persistent object

To use this approach you have to define a corresponding non persistent object for each modal dialog you want to embed. All input data of the dialog should be described with a corresponding property within the referring business object.

For this you could use any POCO class but in case you need any additional functionality within your non persistent object (like some custom bussiness logic while creating or saving the object) you are free to inherit your non-persistent object from the IXafEntityObject, IObjectSpaceLink and/or INotifyPropertyChanged interfaces (preferable with the help of the “non persistent XPO object template” which can be found in the “Add item” selection of your visual studio).

Please ensure that one identifier property is defined (using the KeyAttribute). Surely it is possible to build references to any persistent objects within your non persistent entity in the common way (however you dont have to use the AssociationAttribute in this case and you cant use the SetPropertyValue method and have to implement your own property changed notifier):

 PersistentObject persistentObject;
 public PersistentObject PersistentObject
 {
    get
    {
       return persistentObject;
    }
    set
    {
       if (this.PersistentObject != value)
       {
          this.PersistentObject = value;
          this.OnPropertyChanged("PersistentObject");
       }
    }
 }

Enhancing the non persistent objectspace

For any non persistent entity XAF does only use the corresponding “non persistent objectspace provider”. Doing so your references to persistent objects cant get populated. So we have to ensure that any corresponding non persistent objectspace will get an additional persistent one to his side. With the help of the following window control this requirement can be archieved:

public class AdditionalPersonObjectSpaceController : WindowController {
    public AdditionalPersonObjectSpaceController()
        : base() {
        TargetWindowType = WindowType.Main;
    }
    private IObjectSpace additionalObjectSpace;
    protected override void OnActivated() {
        base.OnActivated();
        Application.ObjectSpaceCreated += Application_ObjectSpaceCreated;
        additionalObjectSpace = Application.CreateObjectSpace(typeof(AnyPersistentEntity));
    }
    protected override void OnDeactivated() {
        base.OnDeactivated();
        Application.ObjectSpaceCreated -= Application_ObjectSpaceCreated;
        if (additionalObjectSpace != null) {
            additionalObjectSpace.Dispose();
            additionalObjectSpace = null;
        }
    }
    private void Application_ObjectSpaceCreated(Object sender, ObjectSpaceCreatedEventArgs e) {
        if (e.ObjectSpace is NonPersistentObjectSpace) {
            ((NonPersistentObjectSpace)e.ObjectSpace).AdditionalObjectSpaces.Add(additionalObjectSpace);
        }
    }
}

Creating the dialog view

After defining the non persistent object the corresponding view can be triggered with default XAF mechanism, i.g. with the help of any PopupWindowShowAction:

private void Escalation_CustomizePopupWindowParams(object sender, CustomizePopupWindowParamsEventArgs e)
 {
   var objectSpace = Application.CreateObjectSpace(typeof(NonPersistentObject));

   var newObject = objectSpace.CreateObject<NonPersistentObject>();

   // Initialize some default values of the wizard
   // newObject.Prop1 = defaultValue;

   e.View = Application.CreateDetailView(objectSpace, newObject);
}

Doing so the XAF application comes up with a well integrated modal dialog form (optionally enhanced with default validations and conditional formatting):
untitled

The handling of the cancelation or confirming of the dialog can be done in a XAF standardized way as well:

 private void Escalation_Execute(object sender, PopupWindowShowActionExecuteEventArgs e)
 {
    var nonPersistentObject= e.PopupWindowViewCurrentObject as NonPersistentObject;

    // Validate the user input
    Validator.RuleSet.Validate(this.View.ObjectSpace, nonPersistentObject, ContextIdentifier.Save);

    // Maybe create some new data
    var newEscalation = new PersistentObject(session)
    {
       // initialize members...
    };
    session.CommitTransaction();

    // Display the feedback
    this.ShowFeedbackMessage();
 }


A sample project of this approach can be found under the following URL:

https://github.com/wolfhermann/Wiki.Sample.NonPersistentObjects