Blogs

Gary's Blog

April 2010 - Posts

  • XtraGrid and XtraPivotGrid – Grouping vs Pivoting for Data Display

         

    Choosing the correct grid from our controls can be important when displaying and manipulating data, take this example:

    Let’s say I write an application that analyses the postings made by the Devexpress evangelists. If I store such data in a database and wish to view and manipulate the data, I could choose to use the XtraGrid. Having bound the control to a summary view of the data, in the normal way, and running the application, I see the following:

    image

    As you can see, by default, because we are dealing with summary details, everything is a bit of a mish mash. There are mixed dates in the first column and mixed up names in the second column. To try and make things a little better we can group our data, either on “Date”:

    image

    or on “Name”:

    image

    Both of these are an improvement on the original but still do not make the data very clear. If we swap the XtraGrid for the XtraPivotGrid and again bind to the summary data we get:

    image

    Now, if we drag and drop the “Date” onto the row fields area:

    image

    and the “Name” onto the column fields area:

    image

    and finally, the “Number of Posts” onto the data items area:

    image

    then we can get a nice, clear view of all of our data.

    So, as you can see, whatever your grid needs, at Devexpress we’ve got it covered. :-)

  • XAF – Application Model and Model Editor Improvements V2010 Vol1

         

    In this post I want to let you know about a number of exciting improvements to the Application Model and to the Model Editor that will be available in V2010 Vol1. Firstly, we have greatly optimised the model generation. In fact generation now happens around 100 times faster than in previous versions! So what does that mean for your users? Well it means that the average XAF application now launches around 60% faster than before! But we’re not finished there, application startup time also consists of the time spent collecting information on the types used in the application and we have targeted this area for improvement in the 10.2 release timeframe. If you want to keep up to date with our progress in this particular area, you can track this suggestion.

    The next improvement I want to tell you about is to the Model Editor. If you’ve been using XAF in a non trivial way, you may have noticed that if you open the Model Editor you can be visually swamped by the attributes – wouldn’t it be really cool if you could group those attributes by category? Well, good news, now you can! As of 10.1 you’ll be able to decorate your interface attributes with CategoryAttribute and that will cause the Model Editor to group those attributes by the specified category. All the standard XAF application model attributes belong to one of the common categories described here. If an attribute is not decorated with CategortyAttribute then it will appear in the Misc. category by default. An example of this is shown below:

    Another improvement to the Model Editor is that it is now possible to select members of complex properties in a drop-down editor, containing a tree structure of your business model as shown below:

    screenshot

    Another improvement is that identifiers for the most nodes are now generated automatically. If you extend the application model and follow the naming convention for node identifiers, then their values will be generated automatically. We recommend that you declare the 'Id' property (the last character is in lower case). This property will always be recognized as the key even if the KeyPropertyAttribute doesn't point to it. Although this is a small feature, it will save time when customizing the application model and also overcome some previous limitation, like the one mentioned here.

    The last improvement I’m going to talk about in this post is the fact that it is now possible to use the DC technology to easily inject additional business logic into the application model. Let’s consider a couple of examples:

    Example 1

    Before:

    <Element Name=""EditorStateRule="""" ="" >
      <Attribute Name=""TypeInfo="""" RefNodeName=""/Application/BOModel/Class"" Required=""True"" />
      …

    Now:

    public interface IModelEditorStateRule : IModelNode, IEditorStateRule {
        …
        [ModelPersistentName("TypeInfo")]
        [DataSourceProperty("Application.BOModel"), Required]
        IModelClass ModelClass { get; set; }
        …
    }

    Note that XAF’s DataSourcePropertyAttribute is used in the same manner as when you want to provide a data source for a lookup property in your business class. Since our interface is derived from the IModelNode one we can access its Application property and its nested properties. Also note that for the backward compatibility (for example, not to lose old model differences) the ModelPersistentNameAttribute is used to map the new property to the old name.

    Example 2

    Before:

    <Element Name=""NavigationItems="""" ="" >
      ...
      <Attribute Name=""Current="""" RefNodeName=""{DevExpress.ExpressApp.Core.DictionaryHelpers.CurrentNavigationItemNodeProvider=""}""/>
      ...
    </Element>

    Now:

    public interface IModelNavigationItems : IModelNode, IModelList<IModelNavigationItem> {
    ...
        [Browsable(false)]
        IModelList<IModelNavigationItem> AllItems { get; }
        [ModelPersistentName("Current")]
        [DataSourceProperty("AllItems")]
        IModelNavigationItem StartupNavigationItem { get; set; }
        ...
        [DomainLogic(typeof(IModelNavigationItems))]
        public static class ModelNavigationItemsDomainLogic {
                ...
        public static IModelList<IModelNavigationItem> Get_AllItems(IModelNavigationItems navigationItems) {
            CalculatedModelNodeList<IModelNavigationItem> result = new CalculatedModelNodeList<IModelNavigationItem>();
            foreach(IModelNavigationItem navigationItem in navigationItems) {
                result.Add(navigationItem);
                result.AddRange(GetChildItems(navigationItem));
            }
        return result;
        }
                ...
    }
    …

    Here we have introduced a hidden ([Browsable(false)]) service property (AllItems) and set it as a data source for our StartupNavigationItem attribute. It’s exactly the same as the popular Scenario 4 in the help topic about filtering lookups.

    Example 3

    Before:

    <Element Name="Class" ...="" >
      ...
      <Attribute Name="GroupName" IsReadOnly="True"/>
      <Attribute Name="IsNavigationItem"   IsReadOnly="true" Choice="True,False" />
      ...

    Now:

    public interface IModelClassNavigation {
        [ReadOnly(true)]
        bool IsNavigationItem { get; set; }
        [ReadOnly(true)]
        string GroupName { get; set; }
    }    
    [DomainLogic(typeof(IModelClassNavigation))]
    public static class ModelClassNavigationItemDomainLogic {
        public static bool Get_IsNavigationItem(IModelClass modelClass) {
           ...
        }
        public static string Get_GroupName(IModelClass modelClass) {
           ...
        }
        ...
    }

    Here we added a domain logic to calculate default values for read-only attributes shown for the class node in the BOModel.

    Example 4

    Before:

    <Element Name="Filters" Multiple="False">
      <Attribute Name="CurrentFilterID" 
         RefNodeName="{DevExpress.ExpressApp.Core.DictionaryHelpers.ChildrenRefNodeProvider}" />
      

    Now:

    public interface IModelListViewFilters : IModelNode, IModelList<IModelListViewFilterItem>
    {
        [ModelPersistentName("CurrentFilterId")]
        [DataSourceProperty("this")]
        IModelListViewFilterItem CurrentFilter { get; set; }
    }

    Okay, that’s enough examples for today, I don’t want your heads to start spinning :-)

    If you want to see more examples,  you can check out the sources and the docs (once they are available <grin>). They’ll describe the most common cases, in which domain logic can be effectively used to extend the application model.

    The bottom line is that things become easier with the improvements to XAF. For example, in previous versions to achieve the same tasks you had to use complicated approaches that quite often utilized undocumented schema attributes and internal classes from the DevExpress.ExpressApp.Core.DictionaryHelpers namespace. This, of course, made life difficult for inexperienced users, not to mention the fact that we don’t recommend that developers use undocumented classes :-) 

    Now the same, well-understood technology, used to implement business logic in your classes, can be used in the application model and Model Editor, which means you can now use the same techniques and approaches that you are familiar with.

    Well that’s all for this post, until next time, happy XAFing! :-)

  • XAF Benefits from Improvements to XtraLayout Suite V2010 Vol 1

         

    Okay, who amongst us has been caught out by this one? You’re working away, customizing the layout of an XAF view and then, totally by accident, you hit the “Reset Layout” option when you meant to choose something else and bam, all your changes are lost?

    Yep, me too! Well good news! The XtraLayout Suite guys have put in a small feature for V2010 Vol 1 whereby any selection of “Reset Layout” will result in a confirmation dialog popping up:

    screenshot

    Because this is a feature added to the XtraLayout Suite we XAFers get it for free, as it were, as do many other DXperience controls. Thanks guys!

    Until next time, happy XAFing! :-)

  • XPO – Skip and New DateTime Functions V2010 Vol 1

         

    XPO is getting some cool new functions in 10.1. Firstly, the guys have implemented Skip functionality to allow you to skip a specified number of records. This feature, along with others to help improve performance on slow connections, will be enabled automatically depending on the current bandwidth. This mode will increase the database server workload but will reduce the amount of data transferred to the client.

    Also coming in 10.1 are a number of new DateTime functions added to our core data management library. These functions will help you easily determine the interval between two dates and include the following:

    • DateDiffYear
    • DateDiffMonth
    • DateDiffDay
    • DateDiffHour
    • DateDiffMinute
    • DateDiffSecond
    • DateDiffMilliSecond
    • DateDiffTick

    This list of functions matches the list of new functions supported by the DevExpress WinForms and WPF controls and are used for unbound column value calculations and conditional formatting.

    That’s all for this sneak peek post, ‘til next time, happy XPOing! :-)

  • XAF - Easy MDI and Docking V2010 Vol 1

         

    Previously, creating MDI XAF applications wasn’t an easy task. Now, XAF includes a new MDI Show View Strategy and enabling the multiple document interface is a matter of writing a single line of code. What’s more, the new MDI Show View Strategy comes with docking functionality which allows you dock and undock Views. This means that root List Views can now be opened in separate windows.

    To enable this feature I simply switch an application’s Show View Strategy to MdiShowViewStrategy:

    winApplication.ShowViewStrategy = new MdiShowViewStrategy(winApplication);

    And I now have an MDI application:

    XAF Mdi Application Window

    As docking is also supported, I can dock and undock views (opened in tabs) by simply dragging them:

    XAF Window Docking

    I can even Control + Shift + Click a navigation item and the corresponding View will be invoked in a new window:

    XAF Open View in New Window

    And that is how 10.1 will make your life easier if you work with MDI applications!

    Until next time, happy XAFing! :-)

  • XAF – Property Editors and Easy Ribbon V2010 Vol 1

         

    This sneak peek brings you a couple of UI centric features. Firstly, enhanced ASP.Net property editors. Previously, custom ASP.NET Property Editors were rendered only in edit mode. In view mode, different built-in templates were used for different data types. Now, custom Property Editors are correctly rendered in List Views in both edit and view modes.

    XAF Custom Property Editors

    In this screenshot you can see a custom Property Editor (5-stars rater editor) correctly displaying 4 stars. Before XAF v2010 vol1, a plain number ‘4’ was displayed instead.

    Prior to 10.1 the Ribbon UI - an interface similar to the Microsoft Office 2007/2010 interface was supported via a special module which needed to be included in the application and required manual configuration. Now, the Ribbon UI is automatically supported in all WinForms XAF applications. To enable or disable the Ribbon UI, you only need to specify a single Application Model property.

    XAF Ribbon

    That’s it for this quick sneak peek, ‘til next time, happy XAFing! :-)

  • XAF – Domain Components V2010 Vol 1

         

    In this post we’ll take a quick look at the upcoming technology preview for Domain Components, which will ship with 10.1. The “What’s New” file for this technology preview provides the following elevator pitch:

    “The Domain Components Technology provides an elegant and intuitive way to create reusable modules. Now you can compose an application from reusable blocks abstracted from a particular persistence layer.

    With the Domain Components Technology you basically define interfaces instead of declaring regular business classes. Then you specify the logic that defines how interface members behave. After that you can reuse and combine these interfaces to quickly create required domain components. The actual business classes are automatically generated by XAF at runtime.”

    So the purpose of the DC technology, then, is to allow developers to produce reusable domain libraries that are abstracted from a particular persistence layer.

    Currently, when using XAF, developers implement business classes that encapsulate domain knowledge. This has two disadvantages, firstly XAF only supports XPO as a persistence layer at this time, which means you must inherit from the XPO base classes and reference the XPO assembly. Secondly business classes cannot be combined as there is no multiple inheritance in C#. This means that developing a reusable domain library, abstracted from a persistence layer, is very challenging.

    DC will remedy this by allowing a developer to define interfaces and the implementation of their members. These interfaces can then be used to compose other interfaces before, finally, you register the required interfaces with XAF, which will generate the actual business classes at runtime time.

    Right, let’s have a look at a quick example. We’ll implement several domain components, let’s start with an IPerson interface:

    [DomainComponent, ImageName("BO_Person")]   
    public interface IPerson {
        [RuleRequiredField]
        string LastName { get; set; }
        string FirstName { get; set; }
        string FullName { get; }
        DateTime Birthday { get; set; }        
        bool Married { get; set; }        
        string SpouseName { get; set; }
    }

    There are a couple of things to note here, firstly that you can apply regular XAF attributes (RuleRequiredField, ImageName, etc) just like you’d do with a “normal” business class. Secondly, that the interface is decorated with the [DomainComponent] attribute, specifying that this interface describes a Domain Component. Of course, we could use this interface as is, but that’s not very practical, so let’s go ahead and add an implementation class:

    [DomainLogic(typeof(IPerson))]
    public class PersonLogic {
        public static string Get_FullName(IPerson person) {
            return string.Format("{0} {1}", person.FirstName, person.LastName);
        }
        public void AfterChange_Married(IPerson person) {
            if(!person.Married) person.SpouseName = "";
        }
    }

    The last thing I have to do, before I can use my Person object, is to register the IPerson interface with XAF, like so:

    public sealed partial class MySolutionModule : ModuleBase
    {
        public override void Setup(XafApplication application)
        {
            if (!XafTypesInfo.IsInitialized)
            {
                XafTypesInfo.Instance.AddEntityToGenerate("Person", typeof(IPerson));
            }
            base.Setup(application);
        }
    }

    Which causes XAF to generate my class for me:

    Person

    Now I can go on and define the IOrganiszation interface with a collection of IPerson objects:

    [DomainComponent, ImageName("BO_Organization")]    
    public interface IOrganization {
        string Name { get; set; }
        IList<IPerson> Staff { get; }
    }

    This simple declaration will automatically set up an association:

    Organization

    Here is an example of method implementation and initialization logic:

    [DomainComponent, ImageName("BO_User")]
    public interface IAccount {
        [SizeDc(8)]
        string Login { get; set; }
        [SizeDc(8)]
        string Password { get; set; }
        string GenerateString();
    }
    [DomainLogic(typeof(IAccount))]
    public class AccountLogic {
        public static string GeneratePassword() {
            byte[] randomBytes = new byte[3];
            new RNGCryptoServiceProvider().GetBytes(randomBytes);
            return Convert.ToBase64String(randomBytes);
        }                
        public static void AfterConstruction(IAccount account) {
            account.Login = GeneratePassword();
            account.Password = GeneratePassword();
        }
    }

    Notice the use of the “SizeDC” attribute here. This attribute is analogous to the “Size” attribute that you will be used to decorating your current business classes with. Note also that this name is likely to change before the final version of DC ships. :-)

    Account

    Now that we have a number of interfaces defined, we can package them in an assembly and use it as a domain library. This means that I’d be able to create a new XAF application, reference the domain library, and define a new component this this:

    [DomainComponent, NavigationItem, ImageName("BO_Contact")]
    public interface ICustomer : IAccount, IOrganization {
    }
    public override void Setup(XafApplication application) {
        if(!XafTypesInfo.IsInitialized) { 
            XafTypesInfo.Instance.AddEntityToGenerate("Person", typeof(IPerson));
            XafTypesInfo.Instance.AddEntityToGenerate("Account", typeof(IAccount));
            XafTypesInfo.Instance.AddEntityToGenerate("Organization", typeof(IOrganization));
            XafTypesInfo.Instance.AddEntityToGenerate("Customer", typeof(ICustomer));
        }
        base.Setup(application);
    }

    Now I have a customer domain component which I can use:

    Customer

    We think the this DC technology is a real step towards simple development of reusable libraries and should make the lives of developers a lot easier, we hope you enjoy playing with the technology preview when it ships with 10.1.

    Until next time, happy XAFing! :-)

  • XPO and Distributed Databases

         

    In this sneak peak post we’ll take a look at a new feature for XPO, direct from the “Devexpress Labs”. For sometime now the guys in the lab have been trying to solve the problem of how to make distributed databases more ubiquitous, and it looks like they’ve finally cracked it!

    As you know the advantage of the distributed database model is that the data is distributed, the clue’s in the name really. This means that each node of the distribution graph has less work to do and it also means that it is more secure and more likely to be “always available” – if one node fails then you can simply get the required data from another node. Of course this advantage also forms the basis for the disadvantage of this system, and that is how to guarantee access to all the data in a “sometimes connected” distributed database system?

    Well to solve this problem, the guys in the lab have taken advantage of Stanley Milgram’s work on the Six Degrees of Separation phenomenon. As you know, this work shows that there are only 6 degrees of separation between any two people on the planet. They coupled that with the fact that, in most developed countries in the world, most people have mobile phones. You’ll be aware of the fact that most mobile phones have bluetooth capabilities too.

    So how does it work? Well, quite simply, when you send CommitChanges() to a UnitOfWork instance – and you have distributed database support turned on – then the UnitOfWork collects all the objects that require to be persisted and iterates over them, first taking a hash of the object, so that it can be found later on. It then looks around for a mobile bluetooth device. Having found one, it simply sends the object, as a message, to that device. The UnitOfWork ensures that each object is persisted to a different mobile bluetooth device to ensure the maximum distribution in the system.

    That is the simple part. Reading information from this distributed database is the clever part. When you wish to read the data back, the UnitOfWork simply finds the first available bluetooth enabled mobile device and issues a request for the object with the given hash. If that device has the object then it is returned, if not then the device issues a request for the object to everyone in the address book. If one of them has it then they return the object, if not then each of them issues a request to everyone in their address book and so on and so forth, in a cascade effect. Milgram’s work guarantees that the maximum number of hops, between devices, is six and when found, the object is returned back along the chain of devices to the UnitOfWork.

    I think this is a great use of ubiquitous computing from the guys in the lab, if you want to try it out for yourself then download the update for XPO and have fun.

    Until next time, happy XPOing!

More from DevExpress
Live Chat
Have a pre-sales question?
Need assistance with your evaluation?
We are here to help.
Chat is one of the many ways you can contact members of the DevExpress Team. We are available Monday-Friday between 8:30am and 5:00pm Pacific Time.
If you need additional product information, require pre-sales assistance, or want help with your order, write to us at info@devexpress.com or call us at
+1 (818) 844-3383.