Monday, August 16, 2010

Contolling DevExpress XtraGrid Part-2 (Master Detail)

This is a sneak peak for eXpand v10

We have control trhough model all of the options of GridView as shown at  Controlling DevExpress AspxGridControl at runtime 

eXpand had already a very simple implementation of master detail but did not support many levels. Since that implementation was too old i wrote it almost when I started using Xaf I though I give it a try now that I am more experienced so I wrote down some specs about what I wanted

The requirements

  1. Be able to configure the grid views at any level
  2. Be able to control the grid views at any level through controllers
  3. Run Master View actions at child views (eg.delete,save etc)
  4. Support different detailviews per master row
  5. Only special user roles should have the permission to see master detail views

1. Be able to configure the grid views at any level

So say we have a listview that contains a master grid view , our goal will be to expose all associated collections of current type to the model and allow the user to associated a view for each member

That can be done by extending IModelListView with the bellow interface

public interface IMasterDetailRule  {

    IModelListView ChildListView { get; set; }

    IModelMember CollectionMember { get; set; }

}

As you see I have expose a CollectionMember that will have all collections of Master object and ChildListView and now I can associate a Member with a view for a given listview. Then if i go to the ChildListView and set again the values of CollectionMember ,ChildListView I almost support inheritance configuration and by using each listview model attributes I can configure each child list view.

Also if I could assign multiple IMasterDetailRule  to the listview I could support XtraGrid DetailTabs feature and along with eXpand GridViewOptions feature I think I have fully define how the configuration will look .

2. Be able to control the grid views at any level through controllers

That will really mean that i have to create a listview and a frame for each child grid view. That could mean that I have to use some code similar to

CollectionSourceBase collectionSourceBase = _xafApplication.CreateCollectionSource(_objectSpace.CreateNestedObjectSpace(), type, modelListView.Id);

ListView listView = _xafApplication.CreateListView(modelListView, collectionSourceBase, true);

that will create a listview for me along with a GridListEditor and when I add some code like

Window window = _xafApplication.CreateWindow(TemplateContext.View, null, true, true);

it will create a new frame /window for me. And finally when i add the following code

window.SetView(listView);

xaf will create all controls and run all controllers for the new created childlist view. What's left is since I have created all controls/gridlisteditor for the child listview to grab child GridListEditor GridView and associate it as a child grid view of my master GridView.

3. Run Master View actions at child views (eg.delete,save etc)

Master actions will run on the master context which is the Master Listview and will use as CurrentObject,SelectedObjetcs values taken from GridListEditor. So what I have to do is create my own GridListEditor set it as default Xaf GridListEditor override the methods that are responsible for returning the values of CurrentObject,SelectedObjetcs and return values taken from the focused child gridview.

4. Support different detailviews per master row

Since we have a behaviour (child gridview creation) defined and want to make them conditional its time for eXpand logic architecture . So lets redefine the IMasterDetailRule  according to the logic architecture

public interface IMasterDetailRule : IConditionalLogicRule {

    IModelListView ChildListView { get; set; }

    IModelMember CollectionMember { get; set; }

}

inherit from ConditionalLogicRuleViewController and create a list of active IMasterDetailRules that the controller we have create at step 2 and is responsible for associating the gridview  will use .

5. Only special user roles should have the permission to see master detail views

I really not have to do much here since logic architecture supports that be default.

The result? A new conditional module for eXpand called MasterDetail,MasterDetail.Win (2 assemblies)

For example to define a simple 3 level inheritance between Customer,Order,OrderLines you have to create the following rules

image

configure your Customer_ListView

OptionsDetail attributes as

image

and show the detail using OptionsView attributes

image

And do exactly the same for your Orders_ListView .

Or if you like to create a conditional child gridview for example display a different Orders child view for Customers that live in Paris you could create a rule similar to

image

That rule will run for MDCDVCustomer_ListView and it will create a child gridview from the model of MDCDVOrder_ListView_For_Paris listview only for customers that live in Paris (see NormalCriteria attribute).

As I say all that conditional stuff happens cause we have use eXpand logic architecture and that means that we can use instead of model editors, class attributes to define our rules like bellow

[MasterDetail("MDCustomer_Orders", "1=1", "MDOrder_ListView","Orders",View = "MDCustomer_ListView")]

public class MDCustomer : CustomerBase {

    public MDCustomer(Session session) : base(session) {

    }

[MasterDetail("MDOrder_OrderLines", "1=1", "MDOrderLine_ListView", "OrderLines",View = "MDOrder_ListView")]

    public class MDOrder : OrderBase {

        MDCustomer _customer;

or permissions of we want our rules to be applied only to specified user roles

image

Subscribe to XAF feed
Subscribe to community feed

DiggIt!
blog comments powered by Disqus