Wednesday, March 31, 2010

Pivoting at web

Similar to New Pivoting module all features have been implemented for web as well so you can apply the PivotedPropertyAttribute along with inline editing to create complex views like

image 

the above view has been created declaratively !!! No line of code was written for it

you can also control your pivot settings at runtime

image

see for example the pager options

image

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Monday, March 29, 2010

Position your actions anywhere

When working with Xaf and MVC pattern in order to create actions we are using controllers and initialize them upon them. The default behavior of Xaf is to place our actions in the default toolbar of our view.

What if we want to position our actions somewhere else in the view? Then we need to create a custom detailviewItem and write our code against the interface exposed by the detailviewitem. I really did not like the idea , I really wanted to continue to design my actions behavior against the controller interface so i have added an ActionButtonDetailItem for both win and web platforms that can be installed declaratively using the model like

image

bind it to the action we want like

image

and position it anywhere we want using Dx layout component to create our views like

image

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Friday, March 26, 2010

Xaf tip 12--How to pass parameters between controllers

After working with MVC pattern exposed by Xaf I have realized that the best way to to pass parameters between controllers is by using events like

public class PricePricetypeController:ViewController {

    public event EventHandler<AdjustingPriceTypeEventArgs> AdjustingPriceType;

 

    public void OnAdjustingPriceType(AdjustingPriceTypeEventArgs e)

    {

        EventHandler<AdjustingPriceTypeEventArgs> handler = AdjustingPriceType;

        if (handler != null) handler(this, e);

    }

    protected override void OnFrameAssigned()

    {

        base.OnFrameAssigned();

        Frame.GetController<PersistenceValidationController>().ContextValidating+=OnContextValidating;

    }

 

 

    void OnContextValidating(object sender, ContextValidatingEventArgs contextValidatingEventArgs) {

 

        var adjustingPriceTypeEventArgs = new AdjustingPriceTypeEventArgs(contextValidatingEventArgs.TargetObjects);

        OnAdjustingPriceType(adjustingPriceTypeEventArgs);

    }

But there is also another way of passing parameters by using the following design pattern

var showViewParameters = simpleActionExecuteEventArgs.ShowViewParameters;

 

            var objectSpace = Application.CreateObjectSpace();

            var collectionSource = new CollectionSource(objectSpace, typeof(ShellSite));

            showViewParameters.Context = TemplateContext.View;

            showViewParameters.TargetWindow = TargetWindow.NewModalWindow;

            showViewParameters.Controllers.Add(new MyCustomController(true));

            showViewParameters.CreatedView = Application.CreateListView("Site_ListView", collectionSource, true);

public class MyCustomController : ViewController{

    public MyCustomController():this(false) {

    }

 

    public MyCustomController(bool appropriateContext){

        Active["AppropriateContext"] = appropriateContext;

    }

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Wednesday, March 24, 2010

Controlling DevExpress XtraGrid Control at runtime

When I first met DevExpress I was amazed by their XtraGrid control. What a configuration monster!. Xaf exposes some of the configuration but not all.

eXpand allows you to control all configurations of XtraGridControl per view as shown bellow

image

image

image

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Monday, March 22, 2010

The ModelArtifactState Module

This one is the most complex implementation of the logic architecture cause this module is really a facade module. ActionState and ControllerState modules are hosted within it. But the implementation for each one of them as you see in the image bellow really looks alike

image  

image

In order to control the different in model schema than the one that is provided bu defaul I have override the require methods of ControllerStateModule

public class ControllerStateModule :ConditionalLogicRuleProviderModuleBase<TArtifactStateRule> where TArtifactStateRule : IConditionalLogicRule {

        public override string LogicRulesNodeAttributeName {

            get { return ControllerStateRulesNodeWrapper.NodeNameAttribute; }

        }

 

        public override string RootNodePath {

            get { return ModelArtifactStateModule.ModelArtifactStateAttributeName; }

        }

        protected override System.Collections.Generic.IEnumerable<IControllerStateRule> CollectRulesFromModelCore(LogicRulesNodeWrapper<IControllerStateRule> wrapper, DevExpress.ExpressApp.DC.ITypeInfo typeInfo) {

            var collectRulesFromModelCore = base.CollectRulesFromModelCore(wrapper, typeInfo).ToList();

            foreach (ControllerStateRule controllerStateRule in collectRulesFromModelCore) {

                var controllerType = ((IControllerStateRule)controllerStateRule).ControllerType;

                controllerStateRule.ControllerType = Application.Modules[0].ModuleManager.ControllersManager.CollectControllers(

                                        info => info.FullName == controllerType).

                                        Single().GetType();

            }

 

            return collectRulesFromModelCore;

        }

 

        protected override bool IsDefaultContext(ExecutionContext context) {

            return true;

        }

and ActionStateModule

public class ActionStateModule : ConditionalLogicRuleProviderModuleBase<TArtifactStateRule> where TArtifactStateRule : IConditionalLogicRule

{

     public override string LogicRulesNodeAttributeName {

         get { return ActionStateRulesNodeWrapper.NodeNameAttribute; }

     }

 

 

     public override string RootNodePath {

         get { return ModelArtifactStateModule.ModelArtifactStateAttributeName; }

     }

     protected override void ModifySchemaAttributes(Core.DictionaryHelpers.AttibuteCreatedEventArgs args)

     {

         base.ModifySchemaAttributes(args);

         if (args.Attribute.IndexOf("ActionId") > -1)

             args.AddTag(@"Required=""True"" RefNodeName=""/Application/ActionDesign/Actions/*""");

     }

 

     protected override bool IsDefaultContext(ExecutionContext context) {

         return true;

     }

 

     public override Schema GetSchema() {

         var schema = base.GetSchema();

         var dictionaryNode = schema.RootNode.GetChildNode("Element", "Name", ModelArtifactStateModule.ModelArtifactStateAttributeName);

         var findChildNode = schema.RootNode.FindChildNode("Element","Name",LogicRulesNodeAttributeName);

         schema.RootNode.RemoveChildNode(findChildNode);

         dictionaryNode.AddChildNode(findChildNode);

         return schema;

     }

As you can see with the logic architecture everything is well defined and very flexible

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Friday, March 19, 2010

The AdditionalViewControlsProvider Module

 AdditionalViewControlsProvider is a module that it only knows how to display a given control in a given position . So one could easily define an interface for the parameters needed when this behavior is implemented as

public interface IAdditionalViewControlsRule:IConditionalLogicRule {

    string Message { get; set; }

    string MessagePropertyName { get; set; }

    Type DecoratorType { get; set; }

    Type ControlType { get; set; }

    AdditionalViewControlsProviderPosition AdditionalViewControlsProviderPosition { get; set; }

    bool UseSameIfFound { get; set; }

}

take a note that I inherit IConditionalLogicRule  thus logic engine can evaluate the IAdditionalViewControlsRule like it is a conditional rule meaning that is going to create all properties of conditionalLogic+ logic for my attributes, model , permission

image

Everything you see in the above image is automatically generated for you if you provide the require classes

image

the above classes implementation is just a property implementation without any logic at all see for example

[AttributeUsage(AttributeTargets.Class, Inherited = false, AllowMultiple = true)]

public class AdditionalViewControlsAttribute : ConditionalLogicRuleAttribute,IAdditionalViewControlsRule

{

    public AdditionalViewControlsAttribute(string id,string message,

                                           AdditionalViewControlsProviderPosition

                                               additionalViewControlsProviderPosition, Type controlType,

                                           Type decoratorType,  string messagePropertyName, string normalCriteria, string emptyCriteria) : base(id,Nesting.Any,normalCriteria,emptyCriteria,ViewType.Any,

                                                                                                                                                          null) {

        Message = message;

        AdditionalViewControlsProviderPosition = additionalViewControlsProviderPosition;

        ControlType = controlType;

        DecoratorType = decoratorType;

        MessagePropertyName = messagePropertyName;

    }

 

    public string Message { get; set; }

    public string MessagePropertyName { get; set; }

    public Type DecoratorType { get; set; }

    public Type ControlType { get; set; }

    public AdditionalViewControlsProviderPosition AdditionalViewControlsProviderPosition { get; set; }

    public bool UseSameIfFound { get; set; }

}

all the logic should be hosted in a ConditionalLogicRuleViewController derived class so for this case this class will look like

public abstract class AdditionalViewControlsRuleViewController :ConditionalLogicRuleViewController<IAdditionalViewControlsRule> {

 

    public override void ExecuteRule(LogicRuleInfo<IAdditionalViewControlsRule> logicRuleInfo, ExecutionContext executionContext) {

        if (logicRuleInfo.Active){

            IAdditionalViewControlsRule additionalViewControlsRule = logicRuleInfo.Rule;

            var calculator = new AdditionalViewControlsProviderCalculator(additionalViewControlsRule, logicRuleInfo.View.ObjectTypeInfo.Type);

            object control = Activator.CreateInstance(calculator.ControlsRule.ControlType);

            AddControl(control, logicRuleInfo, calculator, executionContext);

        }

    }

Also in order to control the default execution context for this module I did it like

public sealed partial class AdditionalViewControlsProviderAspNetModule : ConditionalLogicRuleProviderModuleBase<IAdditionalViewControlsRule>

{

 

    protected override bool IsDefaultContext(ExecutionContext context) {

        return context == ExecutionContext.ViewControlAdding;

    }

 

}

In the next post I am going to speak how i inherit the conditionalmodule in order to implement the ModelartifactState module

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Thursday, March 18, 2010

The Conditional Logic Module

Say you want to make your rules conditional , meaning that you want your rules to be executed when certain criteria are valid for a given object. That is implemented at eXpand.ExpressApp.ConditionalLogic.dll assembly.

I have extend ILogicRule interface like

public interface IConditionalLogicRule : ILogicRule

{

    /// <summary>

    /// Criteria to apply when show DetailView or filled ListView

    /// </summary>

    string NormalCriteria { get; set; }

 

    /// <summary>

    /// Criteria to apply when show ListView empty

    /// </summary>

    string EmptyCriteria { get; set; }

}

and create derived classes

1.from LogicAttribute

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]

public abstract class ConditionalLogicRuleAttribute:LogicAttribute, IConditionalLogicRule {

    protected ConditionalLogicRuleAttribute(string id, Nesting targetViewNesting, string normalCriteria, string emptyCriteria, ViewType viewType, string viewId) : base(id, targetViewNesting,  viewType, viewId) {

        NormalCriteria = normalCriteria;

        EmptyCriteria = emptyCriteria;

    }

    /// <summary>

    /// Criteria to apply when show DetailView or filled ListView

    /// </summary>

    public string NormalCriteria { get; set; }

    /// <summary>

    /// Criteria to apply when show ListView empty

    /// </summary>

    public string EmptyCriteria { get; set; }

 

}

2.from LogicRuleNodeWrapper

public abstract class ConditionalLogicRuleNodeWrapper : LogicRuleNodeWrapper, IConditionalLogicRule {

    public const string NormalCriteriaAttribute = "NormalCriteria";

    public const string EmptyCriteriaAttribute = "EmptyCriteria";

 

    protected ConditionalLogicRuleNodeWrapper(DictionaryNode ruleNode)

        : base(ruleNode) {

    }

    #region IConditionalLogicRule Members

    public string NormalCriteria {

        get { return Node.GetAttributeValue(NormalCriteriaAttribute); }

        set { Node.SetAttribute(NormalCriteriaAttribute, value); }

    }

 

    public string EmptyCriteria {

        get { return Node.GetAttributeValue(EmptyCriteriaAttribute); }

        set { Node.SetAttribute(EmptyCriteriaAttribute, value); }

    }

    #endregion

}

I did the same for the other require classes so now we have a structure we can inherit if we want to create conditional logic rules.

In the next post I am going to speak how I inherited that structure to refactor AdditionalViewControlsProvider upon it.

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Monday, March 15, 2010

The Logic Module

Xaf architecture and especially the model part is great. What it really teach us is how to parameterized our logic/behavior/code and store that parameter in the model in the form of attributes on already existing nodes or on rule nodes see Xaf Validation system or ConditionalEditorState system. eXpand has provided a similar architecture through its ModelArtifactState module.

But after you start using such “ruling” modules for some times the most “logical” question will come into your mind.

How I could define a uniform way of describing a behavior in terms of an interface and apply a ruling system upon it.

The above problem exactly is address by logic module. What it does ? First look at ILogicRule interface

public interface ILogicRule

{

    string ID { get; set; }

    string ExecutionContextGroup { get; set; }

    ViewType ViewType { get; set; }

    Nesting Nesting { get; set; }

    string Description { get; set; }

    ITypeInfo TypeInfo { get; set; }

    string ViewId { get; set; }

    int Index { get; set; }

}

So given the properties of the above interface the logic system expects you to provide

1. A LogicAttribute derived class so you can apply it above your domain object classes

[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, AllowMultiple = true)]

public abstract class LogicAttribute : Attribute, ILogicRule

{

    protected LogicAttribute(string id,Nesting targetViewNesting, ViewType viewType,string viewId)

    {

        ViewId = viewId;

        ID=id;

        ViewType = viewType;

        Nesting = targetViewNesting;  

    }

    string ILogicRule.ExecutionContextGroup { get; set; }

    public ViewType ViewType { get; set; }

    public Nesting Nesting { get; set; }

    public string ID { get; set; }

    public string Description { get; set; }

    ITypeInfo ILogicRule.TypeInfo { get; set; }

    public string ViewId { get; set; }

    public int Index { get; set; }

}

2.A LogicRule derived class

public abstract class LogicRule : ILogicRule

{

    readonly ILogicRule _logicRule;

 

    protected LogicRule(ILogicRule logicRule){

        _logicRule = logicRule;

    }

 

    public string ID {

        get { return _logicRule.ID; }

        set { _logicRule.ID = value; }

    }

 

    public string ExecutionContextGroup {

        get { return _logicRule.ExecutionContextGroup; }

        set { _logicRule.ExecutionContextGroup = value; }

    }

 

    public ViewType ViewType {

        get { return _logicRule.ViewType; }

        set { _logicRule.ViewType = value; }

    }

 

    public Nesting Nesting {

        get { return _logicRule.Nesting; }

        set { _logicRule.Nesting = value; }

    }

 

    public string Description {

        get { return _logicRule.Description; }

        set { _logicRule.Description = value; }

    }

 

    public ITypeInfo TypeInfo {

        get { return _logicRule.TypeInfo; }

        set { _logicRule.TypeInfo = value; }

    }

 

    public string ViewId {

        get { return _logicRule.ViewId; }

        set { _logicRule.ViewId = value; }

    }

    public int Index

    {

        get { return _logicRule.Index; }

        set { _logicRule.Index = value; }

    }

 

}

3.a LogicRuleNodeWrapper, derived class so you can control the model

image

image

4.A LogicRulePermission derived class so you can control your behavior from the xaf security system

image

as you see all expected classes should implement the same interface such achieving polymorphism ..

So given that you have provided the above classes then Rule Logic system will attach to the events defined by the following contexts

[Flags]

public enum ExecutionContext

{

    All=0,

    ViewChanging=2,

    ObjectChanged=4,

    ObjectSpaceReloaded=8,

    CurrentObjectChanged=16,

    ViewControlsCreated=32,

    ViewActivated=64,

    ViewControlAdding=128,

    TemplateViewChanged=256

}

and for the rule that are valid according to the ExecutionContextGroup and all other properties defined at I LogicRule interface it will provide a method within a controller to override and place your own logic for that spesific rule.

public override void ExecuteRule(LogicRuleInfo<IActionStateRule> logicRuleInfo, ExecutionContext executionContext) {

    //put your logic here

}

In the next post I ll speak about how I extended the logic module to create the conditional logic module. The logic module is exposed by eXpand.ExpressApp.Logic.dll assembly

Subscribe to XAF feed
Subscribe to community feed

DiggIt!

Sunday, March 14, 2010

ModelArtifactState - AdditionalViewControls breaking changes

I have been pretty silent the last few weeks , but I have not been lazy so eXpand has now many more modules and features that I am going to speak about in my next posts. A Logic Module has been implemented and that lead to some breaking changes to ModelArtifactState / AdditionalViewControlsProvider modules

ModelArtifactState

The previous schema of ModelArtifactState rules was like

<ModelArtifact>

    <ConditionalControllerState IsNewNode="True">

      <ControllerStateRule ID="tests" TypeInfo="DevExpress.ExpressApp.SystemModule.AboutInfo" IsNewNode="True" />

    </ConditionalControllerState>

  </ModelArtifact>

image

but now has been changed so to conform with the Logic modules architecture to

<ModelArtifactState>

    <ConditionalControllerState>

      <Rules>

        <ControllerStateRule ID="test" TypeInfo="DevExpress.ExpressApp.SystemModule.AboutInfo" ControllerType="DevExpress.ExpressApp.CloneObject.CloneObjectViewController" IsNewNode="True" />

      </Rules>

    </ConditionalControllerState>

  </ModelArtifactState>

image

so you have to manually update your model.xafml files .

The same procedure has to be applied to AdditionalViewControlsProvider module.

In the next post I am going to speak about the Core Logic module.

Subscribe to XAF feed
Subscribe to community feed

DiggIt!