Showing posts with label eXpand. Show all posts
Showing posts with label eXpand. Show all posts

Monday, August 1, 2011

How to use an eXpand module with an existing XAF application

Let me describe for a moment how we at DX work. We build and sell software which means that we only sell and provide support for products that have been built and tested by us! However I am here as a framework evangelist and huge XAF fan. This makes it my duty to spread the word as much as I can and make XAF even bigger. To this end through collaboration within the XAF community, we have been building and supporting eXpand. This framework follows XAF to the letter and takes things even further. eXpand gets its inspiration from real life situations and bases itself on examples from DX SUPPORT CENTER. eXpand is the first open source project based on the DevExpress eXpressApp Framework (XAF). More info is available at www.expandframework.com and our very existence relies on your efforts! Anyone is welcome to contribute and enjoy the rewards. It is not necessary to be a XAF guru, we can all manage to create a behavior taken from DevExpress code central. Let’s work together to enhance our beloved XAF!

Using an eXpand module with an existing XAF application is an issue that is being raised a lot recently and I am sure it deserves a post and a place in Xpand Wiki. The following information applies to any Xpand module. Note that installing an Xpand module is almost as easy as using a XAF one.

Introduction

Firstly, as a base type for our application components it is imperative to use XpandWinApplication or XpandWebApplication. Therefore we need to reference Xpand.ExpressApp.Win or Xpand.ExpressApp.Web assemblies from our application projects and replace their components’ base types accordingly,

image

Additionally we need to reference Xpand.Persistent.BaseImpl. Having similar architecture with XAF, eXpand modules use interfaces and their implementations are hosted in the BaseImpl assembly. Xpand modules know how to locate the Business Objects they require so this is all we need to do at this point.

Note; BaseImpl assembly has no references to DX BaseImpl and it is possible to use a replace it with a custom one .

Registering in Toolbox

Now, unless we are a XAF guru, we have to register the assemblies in the VS toolbox. I suggest creating the toolbox items within a new Xpand Tab as shown. At this point we don’t have the resources to create our own ToolBoxCreator utility. If any VS IDE guru wants to contribute such a tool, we owe him one!

image image

Registration

Registering and using a module is as easy as dragging and dropping it into the Application Designer. The designer will then add all required references and modules for us.

image

Give us your feedback

Was this post useful to you? Do you want to learn more about Xpand framework? We would love to hear your feedback!

Happy eXpanding!

DiggIt!

Tuesday, March 29, 2011

eXpand moves to Interactive development

For the past two years we concentrated on working with real world projects. We also worked with SC and forum issues from DevExpress. All this we used to gather requirements for eXpand Framework. It was a good starting point and we need your active input to move further. In order to build a proper road map for eXpand we have created several ways which we can use to work together.

The voting system

First off is a voting system based on UserVoice that has been in operation for some time now. Follow the link and you can see the most popular suggestions and you don’t even need to login to cast your votes.

For some time now a voting system based on UserVoice is functional for our site.There you see the most popular suggestions.
But how it works? You just click on Cast your votes

image

 

  1. Searching for an idea is always preferred before posting a new suggestion :)
  2. Remember that you only have 10 votes for all the suggestions in the list. But you get those back if the suggestion you voted for gets implemented. So, vote carefully. Top right frame gives you the summary of the suggestions you voted for.
  3. To stay on top of the changes to the suggestions you can subscribe to the General activity feed
  4. The most important feature is the discussion that we would ideally have about each suggestion. And this is in your own benefit. You have to convince others of the importance of any given suggestion and have then cast their precious votes.

You can also see top 3 suggestions straight from eXpand’s home page:

image 

The project management system

In the first picture (top of this page) at the right frame the first suggestion is “Provide what's new, changed, fixed”. We agree with you that this one should be taken very seriously - users should have a good reason to download latest revision. This suggestion is already assigned to our web master and CI expert Dima Janzen and as far as I know he is considering http://www.redmine.org/ pas a project management system for our web site and he might speak about it when the time comes. We think that Redmine is an excellent and mature system, but do have a look at their web site (which is built on… Redmine!) and contribute to the discussion (Provide a what's new, changed, fixed) if you have a comment or an alternative to suggest.

The blog

Big thanks go to our irreplaceable Dima again who takes care of the web site and who just announced that our blog can republish YOUR blog (it is already republishing mine).

image

Do you have a blog?
Do you blog about XAF / eXpandFramework ?
Do you want us to host your article on our blog?

Please email expand@expandframework.com, and we are more than happy to republish your articles on our site.

DiggIt!

Monday, September 20, 2010

Make your navigation behave

Xaf provides a very easy to configure navigation system and in this post i will speak about expand approach to make Xaf’s navigation system behave better than the one provided by default.

To enable eXpand extended navigation behaviour one can use the ViewShortcutProccesor attribute either at BO level or at View level as shown in the next image

image image

Now what this ViewShortcutProccesor can do to speed up your development?

  1. Navigate to a detailview using a ReadOnlyParameter

    image

    the above readonly parameter taken from eXpand feature center and is defined as

        public class ExternalApplicationKeyParameter : ReadOnlyParameter

        {

            public ExternalApplicationKeyParameter() : base("ExternalApplicationKey", typeof(Guid)) { }

     

            public override object CurrentValue {

                get {

                    return ((User) SecuritySystem.CurrentUser).Session.FindObject<ModelDifferenceObject>(

                            o => o.Name == "ExternalApplication" && o.PersistentApplication.Name == "ExternalApplication").Oid;

                }

            }

        }

     

  2. Navigate to a non persistent object detail view
    image
    the object can be designed as

        [NonPersistent]

        public class WelcomeObject

        {

        }

    or as

        [NonPersistent]

        public class WelcomeObject:XPBaseObject

        {

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

            }

        }

  3. Browse objects directly from a detailview
    The navigation settings here are exaclty the same as the above but also the navigation actions of the detailview will be enabled, allowing you to navigate to the next record.
    if for the current type no objects are found a new one will be created
    image
  4. Navigate to a specific object/ collection of objects detailview
    Setting at ObjectKey the criteria of your choice  you can open a directly a detailview. If object not found a new one will be created again
    image
  5. Desing your navigation using class based attributes
    Using XpandNavigationItem you can design deep tree level menus by just decorating your class
    image
    the above declaration will create the navigation shown in the image bellow
    image
  6. Design time view cloning
    When building a real world application, most probably you are going to have multiple views for your object types. eXpand provides the CloneView class level attribute that can help you create cloned views at design time.

        [CloneViewAttribute(CloneViewType.ListView, "ConditionalControlAndMessage_ListView")]

        public class Customer : CustomerBase {

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

            }

     

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

        public class CloneViewAttribute : Attribute, ISupportViewId {

            readonly CloneViewType _viewType;

            readonly string _viewId;

     

            public CloneViewAttribute(CloneViewType viewType, string viewId) {

                _viewType = viewType;

                _viewId = viewId;

            }

     

     

            public string ViewId {

                get { return _viewId; }

            }

     

     

            public CloneViewType ViewType {

                get { return _viewType; }

            }

     

            public string DetailView { get; set; }

        }

     

    the advantage of using CloneViewAttribute is that your cloned views are not created in the lastlayer, thus later changes on the view are noted easily . As you see in the next image only the NewColumn attribute is mark bold!!
    image 
DiggIt!

Monday, August 30, 2010

Controlling DevExpress XtraGrid Part-3 (The Columns)

Continuning the Controlling XtraGrid Control series..
Contolling DevExpress XtraGrid Part-2 (Master Detail)
Controlling DevExpress AspxGridControl at runtime
Controlling DevExpress XtraGrid Control at runtime

With the great help of DevExpress Support Guys eXpand now has an engine that can push any class property to your model and then using the power of modeldifference module allow you to change its value at runtime.

See for example how simple we have define all the the options of a GridColumn and push them to the model

public interface IModelColumnOptions : IModelColumnOptionsBase {

    IModelGridColumnOptions GridColumnOptions { get; set; }

}

 

public interface IModelGridColumnOptions : IModelNode {

    IModelGridColumnOptionsColumn OptionsColumn { get; set; }

    IModelGridColumnOptionsColumnFilter OptionsFilter { get; set; }

}

 

public interface IModelGridColumnOptionsColumn : IModelNode {

}

 

public interface IModelGridColumnOptionsColumnFilter : IModelNode {

}

 

public class GridColumnOptionsController : ColumnOptionsController<GridColumn, IModelGridColumnOptions>

{

    protected override Func<PropertyInfo, bool> ControlPropertiesFilterPredicate() {

        return info => info.PropertyType == typeof(OptionsColumnFilter) || info.PropertyType == typeof(OptionsColumn);

    }

 

    public override Func<PropertyInfo, bool> DynamicPropertiesFilterPredicate() {

        return info => true;

    }

}

as you can see all above interfaces have no members and are here just to serve their name all the work is done by the base ColumnOptionsController that takes as a generic argument the class we are interested in pushing to the model and provides methods (ControlPropertiesFilterPredicate) to allow us to control the properties that are going to be pushed

image

same process exactly for AspxGridView columns

public interface IModelColumnOptions : IModelColumnOptionsBase

{

    IModelGridColumnOptions GridColumnOptions { get; set; }

}

 

public interface IModelGridColumnOptions : IModelNode

{

    IModelGridViewColumnSettings Settings { get; set; }

}

 

public interface IModelGridViewColumnSettings:IModelNode {

}

 

public class GridColumnOptionsController : ColumnOptionsController<GridViewColumn, IModelGridColumnOptions>

{

    protected override Func<PropertyInfo, bool> ControlPropertiesFilterPredicate() {

        return info => info.PropertyType == typeof(GridViewDataColumnSettings);

    }

 

    public override Func<PropertyInfo, bool> DynamicPropertiesFilterPredicate() {

        return info => true;

    }

}

image

DiggIt!

Tuesday, August 3, 2010

3 pictures 3000 words!!!

The last few months i have been silent but not lazy at all so I post the next 3 pictures to give you an idea what eXpand will deliver by v10

 image

image

image

So what you think? I just can’t wait to finish.

DiggIt!

Thursday, April 8, 2010

Controlling DevExpress AspxGridControl at runtime

Using the same approach we did for controlling DevExpress XtraGrid at runtime.

image

image

image

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

DiggIt!

Tuesday, February 16, 2010

New MemberLevel Security module

eXpand has a new module that make its easy to protect selected members from selected object instances.

It does the above by checking if in the current system has been granted a eXpand.ExpressApp.MemberLevelSecurity.Win.Security.ProtectRowMemberPermission with an allow Modifier.

Then it will allow you to protect selected members of an object as shown in the image

image

above I have protected (minus sign) boths phones but not the fax (plus sign). So a user that do not have permission will see

image

or for listviews

image

There is also a non object instance depented permission for use as suggested by K18110

image

So when you create a new role you have to add the following permision by default

role.AddPermission(new MemberAccessPermission(typeof (object), null, MemberOperation.Read,

                                              ObjectAccessModifier.Allow));

role.AddPermission(new MemberAccessPermission(typeof (object), null, MemberOperation.Write,

                                              ObjectAccessModifier.Allow));

if you do not use eXpand new project item VS template then you have to manually reference

eXpand.ExpressApp.MemberLevelSecurity.dll,eXpand.ExpressApp.MemberLevelSecurity.Win.dll

DiggIt!

Monday, January 18, 2010

Collaborating with Xaf and IO module

.NET provides a lot of ways to collaborate between systems. All of them are based on data serialization. XPO is missing that, and have a client project that could not live without some generic type of serialization. So I create a simple but powerful IO engine

  • It can serialize any object that inherits DevExpress.Xpo.XPBaseObject.
  • It will also serialize any object that is related to the root object of serialization.
  • To control the export engine A serialization graph can be provided .
  • Object's properties can be serialized according to Serialization Strategy enumeration 

    public enum SerializationStrategy

    {

        SerializeAsValue = 0,

        SerializeAsObject,

        DoNotSerialize

    }

  • Friendly keys support. For importing data from other RDBMS systems that do not have a GUID primary key

Scenario

  1. From a non xaf application I need to import customers based on some filtering taken from a xaf application.
  2. The design of Customer object differs between applications. In the Xaf application Customer inherits user but in the non Xaf does not. Property names also differ

The above problems can be solved with IO module with easy

2 apps communicating
Lets try to build a WCF service to enable communication. We are going to host it on IIS so create a new WCF Service Application

 image
reference the following assemblies take a not that I also reference Solution3.Web which is my client front end

 image

add an HttpModule to setup an application instance at HttpApplication init. We need to setup an application instance to be sure that the XPDictionary modifications through controllers take place

image

    public class InitXafAppModule:IHttpModule

    {

        public void Init(HttpApplication context) {

            WebApplication.SetInstance(context.Session, new Solution3AspNetApplication());

 

            if (ConfigurationManager.ConnectionStrings["ConnectionString"] != null) {

                WebApplication.Instance.ConnectionString =

                    ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString;

            }

 

            WebApplication.Instance.Setup();

            WebApplication.Instance.Start();

 

        }

 

        public void Dispose() {

 

        }

    }


Our service is going to have the following contract

    [ServiceContract]

    public interface IIOService {

        [OperationContract]

        string Export(string typeName, string criteria);

 

        [OperationContract]

        void Import(string xml);

    }

and implemented as

    public class IOService : IIOService

    {

        public string Export(string typeName, string criteria)

        {

            var session = WebApplication.Instance.ObjectSpaceProvider.CreateUpdatingSession();

            var xpBaseObjects = new XPCollection(session, ReflectionHelper.GetType(typeName), criteria).OfType<XPBaseObject>();

            XDocument xDocument = new ExportEngine().Export(xpBaseObjects);

            var stringWriter = new StringWriter();

            xDocument.Save(stringWriter);

            return stringWriter.GetStringBuilder().ToString();

        }

 

        public void Import(string xml)

        {

            var unitOfWork = new UnitOfWork(WebApplication.Instance.ObjectSpaceProvider.CreateUpdatingSession().DataLayer);

            var importEngine = new ImportEngine();

            importEngine.ImportObjects(XDocument.Parse(xml), unitOfWork);

            unitOfWork.CommitChanges();

        }

    }

Now we are able to call the WCF service to get the xml of Customers of the Xaf application and transform it using extension methods defined in IO module like

var xElement = XDocument.Parse(xml).Root;


IEnumerable<NonXafCustomer> customers =xElement.SerializedObjects("Customer").Select(element => new NonXafCustomer {Name = element.Property("UserName").Value});



ps:Import/Export action within a xaf application are inside export predefined category and they are available for all objects



image

DiggIt!

Monday, November 16, 2009

Dynamic types in any application?

WorldCreator a module designed to work with Xaf can really work without it!!!!

Suppose you have a non xaf application and you use Xpo as your dataLayer and you want dynamic types then WorldCreator can for sure help you.

You just reference WorldCreator and eXpand.BaseImpl assemblies and use an approach similar to the specs bellow

[Test]
public void Can_Create_Types_In_A_Non_Xaf_Context() {
    new PersistentClassInfo(Session.DefaultSession){Name = "Test"}.Save();
    var typeCreator =
        new TypeCreator(
            new TypesInfo(new List<Type> {
                                             typeof (PersistentClassInfo),
                                             typeof (ExtendedCollectionMemberInfo),
                                             typeof (ExtendedReferenceMemberInfo),
                                             typeof (ExtendedCoreTypeMemberInfo),
                                             typeof (InterfaceInfo)
                                         }), new UnitOfWork(Session.DefaultSession.DataLayer));

    Type dynamicModule = typeCreator.GetDynamicModule();

    Assert.IsNotNull(dynamicModule);
    Assert.IsNotNull(dynamicModule.Assembly.GetTypes().Where(type => type.Name=="Test").FirstOrDefault());
}
Technorati Tags: ,
DiggIt!

Monday, November 9, 2009

Filtering a listview of objects according to their childs

 The Problem 1
A common requirement in any OOP application is the ability to filter a listview of objects according to their childs in whatever level they belong.

eXpand can solve the above by the use of propertypath filters. So in an Customer—>Orders--->OrderLines relationship

the filter bellow are enough to filter your customer list view according to any property value of their Orders child collection

image

with the one bellow you can filter customer list view by any property value of orderlines collection of customers orders collection

image

In the video bellow i demo

1. the above functionality that is hosted at eXpand.ExpresApp assembly,
2. eXpand.ViewVariants module for creating views without the model editor (that is badly needed now that we can have multiple filters on a view)
3. A more complex filtering scenario using recursive filtering (provided by eXpand.TreeListEditors.Win) and a combination of filtering

DiggIt!

Monday, November 2, 2009

Dynamic Types with WorldCreator source code is out

WorldCreator is a xaf module that provide dynamic persistent types for your application and runtime members for your existing classes. That means that you can define dynamic types at runtime through a UI (xaf views) save them in the database and let your imagination free !!!

Installation
Very simple you just register the selected assemblies bellow

image image

 

and add the required classes you want from .Persistent.BaseImpl

image

At my previous post IOC by BaseImpl I have explain the use of DevExpress.Persistent.BaseImpl assembly so in the same concept eXpand now has its own eXpand.Persistent.BaseImpl that will host a default implementation of persistent interfaces used from eXpand

image

As you can see at the above image there are to types of prefixes on those classes

Persistent—>Using those classes you describe your dynamic types
Extended-->Using those classes you add runtime types to your existent classes

I have already demo how you can model a domain at Yes Xaf can do it before lunch!!! so I am not going to repeat my self on that. Instead I will speak about some new features

Support for Custom attributes

As you see in the above image there is a PersistentMetaData namespace that hosts attributes. I did not implement all XPO,Xaf attributes

But its very easy to do so or to implement your own custom attribute, see for example PersistentCustomAttribute bellow

[DefaultProperty("PropertyName")]
public class PersistentCustomAttribute : PersistentAttributeInfo
{
    public PersistentCustomAttribute(Session session) : base(session) {
    }

    private string  _value;

    public PersistentCustomAttribute() {
    }
    private string _propertyName;
    public string PropertyName
    {
        get
        {
            return _propertyName;
        }
        set
        {
            SetPropertyValue("PropertyName", ref _propertyName, value);
        }
    }
    public string Value
    {
        get
        {
            return _value;
        }
        set
        {
            SetPropertyValue("Value", ref _value, value);
        }
    }
    public override AttributeInfo Create() {
        return new AttributeInfo(typeof(CustomAttribute).GetConstructor(new[] { typeof(string), typeof(string) }), PropertyName,Value);
    }
}

the trick is at create method, there you pass the constructor of the attribute you want to create and an array of arguments for that constructor and you are done!! One more attribute supported

so if anyone implement any more attributes I would be glad to host them in eXpand.

image

Inheritance
image

In the above image you see how you could extend your User class

You can inherit from Dynamic or existent class

Runtime member for existent Types

image

In the above image you can see how you can extend current user with an aggregated association collection.

Be carefull
If you create runtime members on existent classes and try to apply any validation rule on those members your application will throw an exception at start up. I have register an issue on that on DevExpress support so if you would like to implemented real soon from Dx please vote on it

After Dx implements that you can use the model to tell for which classes you want to describe their runtime member

image

WorldCreator is part of eXpand framework and you can get it here

DiggIt!

Wednesday, October 21, 2009

Yes Xaf can do it before lunch!!!

Maybe not with the build in modules and not exactly before lunch but the difference between traditional programming and Xafing is really great.

I am going to continue my posts on WorldCreator module and going to inform you about the progress up to here.

  • New persistent objects have been designed and added to eXpand.BaseImpl assembly in order module consumers to be able to change that implementation
  • The code that creates the Dynamic types and synchronies Xpo dictionary and model dictionary  at application startup is there as well
  • Sample application installation created and can be download, so I can get some feedback on it from anyone will play with it

Not Implemented
Create Dynamic types without restarting the application
Not tested for web 
Cannot create associations between Dynamic Types and existent types yet
Scripting not supported yet

Your feedback/help on this one is greatly appreciated

Download Sample Application file1 , file2

UserName:Sam
Pass: empty

DiggIt!

Thursday, October 15, 2009

Sneak Peak: Dynamic Types with World Creator module

Dynamic Types is one of the most wanted feature in any framework. Luckily me I met Emilio DabDoub of Signia software and one of the Coordinators of XERP project and he hire me to port an old code that he had that could provide that feature and much more into xaf. Also he agreed to publish that module into eXpand.

Technorati Tags: ,
DiggIt!

Wednesday, October 14, 2009

Saving settings to database instead of cookies

 

THE PROBLEM –> HTTP 400 Bad Request (The data is invalid)

Xaf provides peristent of your web listview setting to cookies using Options | SaveListViewStateInCookies attribute in the Application Model. But due to the limit in request buffer size of IIS your web browser will receive a HTTP 400 Bad Request (The data is invalid) when you overcome it.

DevExrpess suggest you either persist individual listviews in order you never overcome that limit or as Microsoft also suggested here to add a registry value to raize that limit.

SOLUTION

ModelDifference module provides the Options | SaveListViewStateInDataStore that can persist your listview settings to your user model and thus to the database and since your model is persistent also at database

Technorati Tags: ,,
DiggIt!

Thursday, October 8, 2009

One way associations

If you are tired of writing both parts of an association or if you want to add an association to an object that you do not own check eXpand’s ProvidedAssociation attribute.

Creating OneTo Many

public class Employee:BaseObject
{
    public Employee(Session session) : base(session)
    {
    }
    private EmplyoeeContract _EmplyoeeContract;
    [ProvidedAssociation]
    [Association("EmplyoeeContract-Employees")]
    public EmplyoeeContract EmplyoeeContract
    {
        get
        {
            return _EmplyoeeContract;
        }
        set
        {
            SetPropertyValue("EmplyoeeContract", ref _EmplyoeeContract, value);
        }
    }
}

in the above code i have decorated EmplyoeeContract with ProvidedAssociation and that is the only needed to create an collection of Employess at EmplyoeeContract class for use in both runtime and designtime.

public class Employee:BaseObject
{
    public Employee(Session session) : base(session)
    {
    }
    [Association("Employee-EmplyoeeContracts")]
    [ProvidedAssociation]
    public XPCollection<EmplyoeeContract> EmplyoeeContracts
    {
        get
        {
            return GetCollection<EmplyoeeContract>("EmplyoeeContracts");
        }
    }
}

in the above code I decorate a colection thus saying to eXpand to create a reference object of type Employee at EmplyoeeContract type

Many To Many

public class Employee:BaseObject
{
    public Employee(Session session) : base(session)
    {
    }
    [Association("Employee-EmplyoeeContracts")]
    [ProvidedAssociation(RelationType.ManyToMany)]
    public XPCollection<EmplyoeeContract> EmplyoeeContracts
    {
        get
        {
            return GetCollection<EmplyoeeContract>("EmplyoeeContracts");
        }
    }
}

to make that happen just used RelationType.ManyToMany with ProvidedAssociation

What about adding more attributes to the other type than the Association attribute?

for eg how about making in the first example to make the collection of the other part aggregated?

public class Employee:BaseObject
{
    public Employee(Session session) : base(session)
    {
    }
    
    public static IEnumerable<Attribute> MoreAttributes
    {
        get { yield return new AggregatedAttribute(); }
    }
    
    private EmplyoeeContract _EmplyoeeContract;
    [ProvidedAssociation("Employees",RelationType.Undefined, "MoreAttributes")]
    [Association("EmplyoeeContract-Employees")]
    public EmplyoeeContract EmplyoeeContract
    {
        get
        {
            return _EmplyoeeContract;
        }
        set
        {
            SetPropertyValue("EmplyoeeContract", ref _EmplyoeeContract, value);
        }
    }
}
ps: In order ProvidedAssociation to do its magic you have to use eXpand.ExpressApp.dll
image

see also : How to get eXpand latest version

Technorati Tags: ,
DiggIt!

Wednesday, October 7, 2009

ModelDifference Module

DictionaryDifferenceStore has been refactored and added the following features

  • Localization Support
  • Multiple application support
  • Ability to change application model without restarting
  • User,Role differences for web and win environments
  • Persist web settings instead of cookies to the database
  • Ability to work as a standalone module without  having to inherit eXpand.ExpressApp.Win.WinComponent/WebComponent as you saw in previous videos

Martin Praxmarer provided great help in that refactoring and I am going to host him here to speak on some of the above subjects and I ll speak on the rest

Here are the issues implemented / fixed issues

see also:How to get eXpand latest version

Technorati Tags: ,

DiggIt!

Monday, October 5, 2009

How to get eXpand latest version

I have some bad and some good news.

The bad first, until we manage to have full continuous integration in order eXpand new features to be immediately available (nightly builds) we are not going to make any more releases. eXpand release policy will be the same as DevExpress that is we make a release exactly after DevExpress

And now for the good. eXpand will provide build scripts that you can use them to compile the source code. The trunk of source code will contain the most current work.

So you first download the code by going to http://github.com/eXpand/eXpand 

image

and along with the code a set of batch files will be downloaded.

image

You just double click at buildall.bat and eXpand will be compiled and register to the gac. To unregister it use the clear.bat.

DiggIt!

Monday, September 21, 2009

How to zero your application startup time

For this question don’t we all of us spend a lot of time ? But I think it is allowed to use a trick to spend our selves that time.

Add to your model to attributes NotifyIcon, MinimizeOnClose. Since I am using Xaf I am going to present that with it but the code should be very similar to any other windows application

so here are our attributes

image

NotifyIcon: will add a tray icon for your app at the system tray with a context menu that will allow you to terminate your application and display it when you double click the icon

image

public partial class NotifyIconController : WindowController

{

    public const string NotifyIconAttributeName = "NotifyIcon";

    public NotifyIconController()

    {

        InitializeComponent();

        RegisterActions(components);

    }

    protected override void OnFrameAssigned()

    {

        base.OnFrameAssigned();

        Frame.TemplateChanged+=FrameOnTemplateChanged;

 

    }

 

    private void FrameOnTemplateChanged(object sender, EventArgs args){

        if (Frame.Context == TemplateContext.ApplicationWindow && Application.Info.GetChildNode("Options").GetAttributeBoolValue(NotifyIconAttributeName))

        {

            var form = Frame.Template as XtraForm;

            if (form != null)

            {

                IContainer  container=new Container();

 

                var strip = new ContextMenuStrip(container);

                strip.Items.Add(GetMenuItem("Maximize",(o,eventArgs) => changeFormVisibility(form)));

                strip.Items.Add(GetMenuItem("Minimize",(o,eventArgs) => changeFormVisibility(form)));

                if (Application is ILogOut)

                    strip.Items.Add(GetMenuItem("LogOut", (o, eventArgs) => ((ILogOut) Application).Logout()));

                strip.Items.Add(GetMenuItem("Exit", (o, eventArgs) => Application.Exit()));

 

                var notifyIcon1 = new NotifyIcon(container){Visible = true, ContextMenuStrip = strip};

                setIcon(notifyIcon1);

                notifyIcon1.DoubleClick += (o, eventArgs) => changeFormVisibility(form);

            }

        }

    }

 

    private ToolStripMenuItem GetMenuItem(string text, EventHandler clickHandler){

        var item = new ToolStripMenuItem(text);

        item.Click+=clickHandler;

        return item;

    }

 

 

    private void changeFormVisibility(XtraForm form){

        if (form.Visible)

            form.Hide();

        else

            form.Show();

    }

 

    private void setIcon(NotifyIcon notifyIcon1){

        string path = Path.Combine(Path.GetDirectoryName(System.Windows.Forms.Application.ExecutablePath),"ExpressApp.ico");

        if (File.Exists(path))

            notifyIcon1.Icon=new Icon(path);

        else{

            Stream resourceStream = typeof(eXpandSystemModule).Assembly.GetManifestResourceStream("eXpand.ExpressApp.Resources.ExpressApp.ico");

            if (resourceStream != null) notifyIcon1.Icon = new Icon(resourceStream);

        }

    }

 

 

    public override Schema GetSchema()

    {

        const string CommonTypeInfos = @"<Element Name=""Application"">

                                            <Element Name=""Options"">

                                                <Attribute Name=""" +NotifyIconAttributeName+ @""" Choice=""False,True""/>

                                            </Element>

                                        </Element>";

        return new Schema(new DictionaryXmlReader().ReadFromString(CommonTypeInfos));

    }

 

}

MinimizeOnClose: attribute will prevent your application from closing

public partial class MinimizeOnCloseController : WindowController

{

    private static bool editing;

    public const string MinimizeOnCloseAttributeName = "MinimizeOnClose";

    public MinimizeOnCloseController()

    {

        InitializeComponent();

        RegisterActions(components);

    }

    protected override void OnFrameAssigned()

    {

        base.OnFrameAssigned();

        Frame.TemplateChanged += FrameOnTemplateChanged;

    }

 

    private void FrameOnTemplateChanged(object sender, EventArgs args)

    {

        if (Frame.Context == TemplateContext.ApplicationWindow &&

            Application.Info.GetChildNode("Options").GetAttributeBoolValue(MinimizeOnCloseAttributeName)){

            var form = Frame.Template as XtraForm;

            if (form != null){

                form.FormClosing += FormOnFormClosing;

                SimpleAction action =

                Frame.GetController<DevExpress.ExpressApp.Win.SystemModule.EditModelController>().Action;

                action.Executing+=(o,eventArgs) =>  editing = true;

                action.ExecuteCompleted += (o, eventArgs) => editing = false;

            }

        }

    }

 

    private void FormOnFormClosing(object sender, FormClosingEventArgs e){

        if (!editing && e.CloseReason == CloseReason.UserClosing)

        {

            if (Application != null) e.Cancel = Application.Model.RootNode.GetAttributeBoolValue(MinimizeOnCloseAttributeName, true);

            if (e.Cancel)

                ((XtraForm)sender).Hide();

        }

    }

 

 

    public override Schema GetSchema()

    {

        const string CommonTypeInfos = @"<Element Name=""Application"">

                                            <Element Name=""Options"">

                                                <Attribute Name=""" + MinimizeOnCloseAttributeName + @""" Choice=""False,True""/>

                                            </Element>

                                        </Element>";

        return new Schema(new DictionaryXmlReader().ReadFromString(CommonTypeInfos));

    }

 

}

Now your application never closes and user can display its UI instantaneously but just double clicking the tray icon

Those 2 controllers are already at eXpand and in next version i think i add a LoadWithWindows attribute that will zero my application load time

Technorati Tags: ,,,
DiggIt!