Don Wibier's Blog
  • DevExpress @ NDC London this week

    2018 is kicking off in Europe with the NDC London conference. DevExpress is proud to be a partner of it.




    As always, NDC has a top notch line-up with speakers like Scott Guthrie, Steve Sanderson, Scott Hanselman and about 90 more!

    John and I will be available at our booth to show you all the awesome features in our v17.2 release and we'll be handing out some cool goodies.
    Make sure to come by and say hi!

    See you at NDC!

  • XPO for .NET Core 2 Webinar on Channel 9 @ Microsoft

    I got some questions last week about where to find the webinar video "Object-Relational Mapping for .NET Core with DevExpress XPO" I did as kick-off on our v17.2 release webinar series. Well, the reason it took some time is because we prepared it to be hosted on the Microsoft Channel 9 site.

    To show how cross-platform XPO and .NET Core 2 are, I decided to use a Linux Mint environment in the first part, Windows 10 in the second part and Mac OS in the third (Xamarin) part.

    I didn't even mention in the webinar that I was running my MS-SQL Server instance in a Docker container on my Asustor NAS Device (which is Linux based), so it was cross-platform all the way!

    Webinar outline

    After the general introduction on Object Relational Mapping, the coding part took of. I started with a small console application to show the absolute basics of XPO.

    Connecting to the datastore

    The first step is to connect to a datastore which is done throught the DataLayer. XPO has several difference DataLayer implementations for different kinds of applications.
    In the console application, we can use the simple DataLayer and initialize it like this:

       XpoDefault.DataLayer = XpoDefault.GetDataLayer(
          SQLiteConnectionProvider.GetConnectionString("console.db"),
          AutoCreateOption.DatabaseAndSchema);
      

    In the Web API example, there was some more code involved for initializing the DataLayer. Because we're dealing with a multi-threaded web application, we want to initialize a singleton instance of a ThreadSafeDatalayer. Besides that, we also want to setup a database connection pool to make the app as performant as possible:

       string pooledConnectionString = XpoDefault.GetConnectionPoolString(connectionString);
          var dataStore = XpoDefault.GetConnectionProvider(pooledConnectionString,
                                AutoCreateOption.SchemaAlreadyExists);
          var dataLayer = new ThreadSafeDataLayer(dictionary, dataStore); ;
          return dataLayer;
      

    With some extension methods, I'm using the .NET Core dependency injection to create that singleton instance, and I inject a UnitOfWork into any Web API Controller which has a constructor with a parameter of type UnitOfWork:

       public static class CustomXpoExtensions {
          public static IServiceCollection AddXpoPooledDataLayer(this IServiceCollection serviceCollection, string connectionString) {
             return serviceCollection.AddSingleton(XpoHelper.CreatePooledDataLayer(connectionString));
          }
          public static IServiceCollection AddXpoDefaultUnitOfWork(this IServiceCollection serviceCollection) {
             return serviceCollection.AddScoped((sp) => new UnitOfWork());
          }
          public static IServiceCollection AddXpoUnitOfWork(this IServiceCollection serviceCollection) {
             return serviceCollection.AddScoped((sp) => new UnitOfWork(sp.GetService()));
          }
          public static IApplicationBuilder UseXpoDemoData(this IApplicationBuilder app) {
             using(var scope = app.ApplicationServices.GetService().CreateScope()) {
                XpoHelper.CreateDemoData(() => scope.ServiceProvider.GetService());
             }
             return app;
          }
       }
      

    We can use these extension methods in the Startup.cs like this:

       public void ConfigureServices(IServiceCollection services)
       {
          services
             .AddXpoPooledDataLayer(MSSqlConnectionProvider.GetConnectionString("sql-server-ip", "user", "test123", "WebAppDemo"))
             .AddXpoUnitOfWork()
             .AddMvc()
             .AddJsonOptions(options =>
             {
                 // use the custom resolver (above)
                 options.SerializerSettings.ContractResolver = new XpoContractResolver();
                 // don't kill yourself over loop properties (probably not really needed now, I
                 // inserted this originally to work around the This property on the XPO types)
                 options.SerializerSettings.ReferenceLoopHandling = ReferenceLoopHandling.Ignore;
              });
       }
      

    The AddJsonOptions in the above code adds a custom Json serializer to the App to make sure certain fields of our XPO entities are not being serialized to Json. This fields are part of the infrastructure or XPO.

    For the Xamarin example, I used again a ThreadSafe Datalayer because a Xamarin app will be multi-threaded as well.

    Defining entities

    In the examples, I used an Order type together with the OrderItem type. This gave me the opportunity to show how to setup a Master-Detail relation ship as well.

    The first thing you see is that I derived my entities from the XPO based type XPObject.

       public class Order : XPObject
       {
          public Order(Session session) : base(session) { }
    
          //... code omitted
       }
      

    The reason for using this base type is that several nice features of XPO will be made available then like "Change Notifications". This behaviour comes in quite handy when doing some caching to get the most out of your application.

    Please note that the XPObject requires you to supply a Session (or UnitOfWork) to its constructor. This is necessary to let the infrastructure of XPO dot its thing with the object being instantiated.

    In case you have an existing class hierarchy that you want to persist to a database and you don't want to use constructor and Sessions etc. in there, you can also work with plain simple objects (POCO) which is similar as with Entity Framework.

    An example of this is the Xamarin demo which works with the POCO objects created by the project template.

        public class Item
        {
            public string Id { get; set; }
            public string Text { get; set; }
            public string Description { get; set; }
        }
    
        using (var uow = XpoHelper.CreateUnitOfWork())
        {
           item.Id = Guid.NewGuid().ToString();
           // I'm using the Save(..) method which receives the POCO we want to persist
           uow.Save(item);
           uow.CommitChanges();
        }
      

    Another interesting thing is the implementation of properties:

       public class Order : XPObject
       {
          //... code omitted 
    
          public Order(Session session) : base(session) { }
          private DateTime _OrderDate;
          public DateTime OrderDate
          {
             get { return _OrderDate; }
             set { SetPropertyValue("OrderDate", ref _OrderDate, value); }
          }
       }
      

    This SetPropertyValue(..) method is one of the methods made available through the XPObject and deals with the Change Notifications.

    Defining relationships between entities is pretty straight forward. In a master-detail relationship, the master entity (Order) has a collection of detail entities (OrderItem), while the detail entity holds a single reference to its master entity like shown below:

       public class Order : XPObject
       {
          public Order(Session session) : base(session) { }
    
          //... code omitted 
    
          [Association("Order-OrderItems"), Aggregated]
          public XPCollection<OrderItem> OrderItems
          {
             get { return GetCollection<OrderItem>("OrderItems"); }
          }
       }
    
       public class OrderItem : XPObject
       {
          public OrderItem(Session session) : base(session) { }
    
          //... code omitted 
    
          private Order _Order;
          [Association("Order-OrderItems")]
          public Order Order
          {
             get { return _Order; }
             set { SetPropertyValue("Order", ref _Order, value); }
          }
       }
      

    Also note the Association and Aggregated attributes. They tell XPO what kind of relation we are trying to setup.

    Another powerful feature that comes with XPO is the use of the PersistentAlias attribute. With this you can specify that certain (readonly) fields need to be determined/evaluated by the database system being used.

    I used 2 examples in the project, one which calculated the total price per order item, which is Qty * UnitPrice:

        public class OrderItem : XPObject
        {
            //... code omitted 
    
            public int Qty {
               //... code omitted
            }
            public decimal UnitPrice{
               //... code omitted
            }
    
            [PersistentAlias("Qty * UnitPrice")]
            public decimal Price
            {
                get { return Convert.ToDecimal(EvaluateAlias("Price")); }
            }
        }
      

    The second one is doing an aggregated calculation as part of the Order entity which sums the Alias from the detail set OrderItems:

        public class Order : XPObject
        {
    
            //... code omitted 
    
            [Association("Order-OrderItems"), Aggregated]
            public XPCollection OrderItems
            {
                get { return GetCollection("OrderItems"); }
            }
            [PersistentAlias("OrderItems.Sum(Price)")]
            public decimal TotalAmount
            {
                get { return Convert.ToDecimal(EvaluateAlias("TotalAmount")); }
            }
        }
      

    Please not that the syntax being used is part of our database agnostic criteria language. More about it can be found here.

    Querying the datastore

    There are several ways of querying the datastore. In the examples I've used the Linq querying mechanism. This query is initiated through the Session.Query<T>() method:

       using (var uow = new UnitOfWork())
       {
          var orders = from o in uow.Query<Order>()
                where o.OrderDate < DateTime.Now.AddDays(-10)
                orderby o.OrderDate
                select o;
    
          foreach (var o in orders) {
             Console.WriteLine($"Order #{o.OrderNo} / {o.OrderDate}, client {o.Client}, Total Amount { o.TotalAmount }");
             foreach(var i in o.OrderItems) {
                Console.WriteLine($"   {i.Qty} x {i.Description} ({i.UnitPrice}) = {i.Price}");
             }
          }
       }
      

    XPO also supports another query mechanism by using the CriteriaOperator classes. This are super-powerful and they also allow you to select programmatically. This tends to be a problematic with Linq.
    XPO CriteriaOperators allow you to create a very complex filtering clause which will be transformed to the SQL WHERE clause when executed.
    I could rewrite the above code fragement like this:

       using (var uow = new UnitOfWork())
       {
          XPCollection<Order> orders = new XPCollection<Order>(uow,
                new BinaryOperator("OrderDate", DateTime.Now.AddDays(-10), BinaryOperatorType.Less),
                new SortProperty("OrderDate", SortingDirection.Ascending));
       }
    

    Or by using the CriteriaOperator.Parse(...) construct:
    I could rewrite the above code fragement like this:

       using (var uow = new UnitOfWork())
       {
          XPCollection<Order> orders = new XPCollection<Order>(uow,
                CriteriaOperator.Parse("OrderDate < ?", DateTime.Now.AddDays(-10)),
                new SortProperty("OrderDate", SortingDirection.Ascending));
       }
    

    Do note the '?' which is used as a parameter indicator in the query language.

    More on the XPO Criteria Language can be found here.

    This Webinar was only short introduction since XPO involves much more. What to think about inheritance, interface support, a whole set of Attributes to decorate your classes and properties with, support for Views and StoredProcedures.

    I even didn't mention our Visual Designer which comes with VisualStudio as well as our XPO Profiler tool to analyze which SQL is being fired against the database:

    If you want to play around with the samples I did in the webinar, check out my Github repo at: https://github.com/donwibier/DXXPOCore.

    Do note that if you clone the repo, you will need to have your personal DevExpress NuGet feed configured like instructed here.

    Let me know if you want to know more!

  • DevExpress Meetups: Impressions from Munich

    John and I also organized our third meetup at the Wirthaus am Bavariapark in Munich, Germany. Again, we had a full house with customers for all of our product lines and we managed to talk with all. I kicked off with some small welcome words and highlighted a number of features of our v17.2 release.

    It was fun to see the first snow of the season come down on Munich during the day so when we started, it looked quite white outside.

    Below is an impression of the meetup:

     

    And again, if Munich isn't in your neighborhood and you want to meet us? Let me know your location. We are looking to organize some more meetups in the beginning of next year.

  • DevExpress Meetups: Impressions from Frankfurt

    Last week, John and I organized another meetup in Frankfurt Germany.  We hosted this one in the Ambassador Club on the 7th floor of Fleming’s Selection Hotel in Frankfurt-City. Almost everybody who registered showed up and we talked about virtually all the product lines we have.

    Below is an impression of the Frankfurt Meetup:

     
     
     
     

    We are looking to organize some more meetups. Let me know which location would be convenient for you!

  • DevExpress Meetups: Impressions from Utrecht

    Last week, John and I organised the first of a series of meetups. This one was in The Colour Kitchen Oudegracht in Utrecht, The Netherlands.

    There was a lot of interest and we had a full Colour Kitchen. I started with a short welcome presentation where I talked about some of the v17.2 release highlights. After that, we had some interesting conversations about pretty much all of our tools and products.

    Below is an impression of the meetup

     
     

    We hope to see you on one of the future meetups!

  • Germany Meetups: November 29th Frankfurt, November 30th Munich

    After our initial kick-off meetup in Utrecht, The Netherlands on November 27th, John and I will be in Frankfurt at the 29th of November.

    Frankfurt Meetup

    We will be hosting our second meetup in the Ambassador Club on the 7th floor of Fleming’s Selection Hotel at the Eschenheimer Tor 2 in Frankfurt-City.

    You will be informed on the latest features of our v17.2 release, and you’ll be able to discuss them with me or other DevExpress customers. The drinks and snacks are on us and we’re looking forward meeting you.

    If you want to join this meetup, make sure to register you seat by clicking here.

    image
    image

    Munich Meetup

    On November 30, John and I will be in Munich for our 3rd Meetup. We’ll host this one in the Augustiner Keller und Biergarten, and while we go over the awesome new features of v17.2, you’ll be paying attention while having a beer and some snacks.

    I’d love to talk with all of you and hear your comments and feedback, and maybe even some suggestions for our next major release.

    If you want to join this meetup, make sure to register you seat by clicking here.

    If you can't make it to any of these locations, let me know so we can investigate possible other locations for additional meetups.

    I hope to see you in Frankfurt or Munich!

  • DevExtreme: New TypeScript declarations and improved Angular typings (v17.2)

    One of the things we support from the very first release of DevExtreme is TypeScript.

    new-TypeScript-declarations-typings-for-angular-blog

    As many of you know, TypeScript and its tooling allow us to use compile-time type checks and it offers support for classes and interfaces. Because of these features, one is able to build large scale JavaScript applications. In fact Google is using TypeScript for developing Angular.

    With our v17.2 release we have improved our TypeScript declarations for the DevExtreme widgets API as well as the Angular integration layer.

    What does this mean?

    In the previous releases, most of the classes in the DevExtreme API had weakly typed properties (of type ‘any’). This means that compile time type checking always resulted in a successful build even if you try to bind a string value to a property which needs a number.

    With v17.2 we have made the DevExtreme API strongly typed which results in improved code editor hints:

    wrongtype

    One of the cool features of TypeScript is the use of union types (‘|’ sign). This allows us to specify a number of types to be used like shown in the following table:

      v17.1 v17.2
    dxDateBoxOptions value? : any value? : Date | number | string
    All widgets dataSource? : any dataSource? : Array | DataSource | DataSourceOptions | string;

    To make the DevExtreme API more fluent, we’ve also introduced the use of ‘type’ declarations like:

        
         export type format = string | ((value: number | Date) => string) | {        
            type?: string,
            precision?: number,
            currency?: string,
            formatter?: ((value: number | Date) => string),
            parser?: ((value: string) => number | Date)
         };
         //...
         // in dxDateBoxOptions
         displayFormat?: format;
    
      
     

    While we were working on these developer improvements, we worked on the IntelliSense support as well. All the information you normally look up on our documentation site will now show up in the Quick Info tooltip and it is used in the code-completion to increase your productivity.

    uniontype

    What about Angular?

    Because Angular is written in TypeScript, all these developer sweetness works for Angular as well!

    We have strongly typed the Angular Component properties which results in less runtime errors because the build process of an Angular application will do the type-checking for us.

    data-image-png;base…

    And while coding, we are now able to give you short descriptions through the Quick Info panel in IntelliSense as well.

    desc_light

    Try it now?

    So ready for a test-drive?

    These new features are included in the v17.2 pre-beta that is available through npm right now. Please note that this pre-beta may contain some bugs and is not intended to be used in production: 

    npm install devextreme@17.2.1-pre-beta

    Learn more about DevExtreme's pre-releases in this blog post.

    Like it?

    Let me know by replying to this post if you like the features outlined in this post.

  • DevExtreme with and without jQuery (v17.2)

    When we started developing DevExtreme back in 2012, jQuery was the de-facto library everybody used. It gave us the possibility to create a set of feature-rich widgets such as the DataGrid, TreeList, Scheduler and more in a short time-frame.

    jquery-optional-blog

    If we take a look at today’s front-end development landscape, there are a number of really popular JavaScript frameworks like Angular and React and new ones appear every day.

    When using one of those frameworks, jQuery seems to become less important which is understandable since jQuery serves a different purpose.

    jQuery’s primary purpose is DOM-manipulation while those frameworks allow you to follow several design patterns (MVVM/MVC) and support things like client-side model-binding and unit testing.

    Some of those frameworks have some really cool features e.g. Angular’s server-side rendering.
    (Yes, we’re working on that)
    If we want to support server-side rendering, jQuery is preventing us from doing so.

    At the same time we know that jQuery is still a very popular library which is used in a huge number of projects, but we also want you to be able to use everything that your framework of choice has to offer.

    For these reasons we decided to remove the jQuery dependency in DevExtreme v17.2, and have a jQuery integration module like we have for Angular.

    What does this mean?

    If you want to use jQuery with DevExtreme, please do so. The DevExtreme widgets will just work. If you don’t want to use jQuery, then don’t! The widgets will still work.

    If you’re using something like Angular and don’t need to include jQuery, it will reduce the download time of your application. Another nice ‘side-effect’ is that there is a performance improvement of our widgets up to 30% in some scenarios!

    The chart below shows the performance improvements on the jQuery-free widgets vs. the jQuery-included widgets.  

    nojquery-performance

    Server-Side rendering

    As I mentioned before, one of the really cool things for Angular we’re working on is Server-Side rendering (SSR). Without SSR, your web-page will only contain a DOM element like a <DIV> which will be dynamically filled with the UI of your app during page load. As a result, your initial page-load takes a bit longer and because of your ‘empty’ page, indexation by search engines is very difficult because of the client-side rendering. (Search engine spiders only execute some basic  JavaScript)

    With Server-Side rendering, the page with the initial view of your app is fully rendered at the server. Angular makes this possible by executing the same JavaScript on a NodeJS server process.

    For your end-user, it means that they don’t need to look at an ‘empty’ page, but they have the initial view immediately in their browser.

    Making jQuery optional is a first step towards SSR.

    Search Engine Optimization

    SSR will also have a very positive effect on search engine spiders since no client-side JavaScript needs to be executed before your initial view is shown. The spider is able to crawl all the links in the initial view, and will nicely follow and index all of them.

    Your entire Angular app will be index properly!

    Other benefits

    As a result of removing the jQuery dependency, DevExtreme can now work with jQuery.Deferred as well as ES6 Native Promises for asynchronous operations.

    For all of you using DevExtreme in other frameworks like Aurelia, React, VueJS and others, you don’t need to include jQuery anymore and you can skip the jQuery API for creating, updating, event-binding and destroying DevExtreme Widgets.

    Try it now?

    So have we whet your appetite and you want to give it a test-drive?

    These new features are included in the v17.2 pre-release that is available via npm right now. Please note that this pre-release may contain some bugs and is not intended to be used in production: 

    npm install devextreme@17.2.2-pre-beta

    Learn more about DevExtreme's pre-releases in this blog post.

    Like it?

    Let me know by replying to this post if you like this improvement.

  • DevExtreme: A new set of themes and palettes (v17.2)

    Since the first DevExtreme release, we shipped the product with a generic theme in both light and dark color schemes. We wanted to avoid color accents so the widgets would fit in any design.

    For us this meant that we needed to customize quite a bit in our demos like the DevAV and GolfClub projects to give them their own unique visual appearance.

    As a result, we occasionally got questions from you about customizing the generic theme, or use one of those demo themes.

    Because we value your feedback, with v17.2 we will give you 5 totally new themes that you can use in your DevExtreme projects:

    Soft Blue, Carmine, Green Mist, Dark Moon and Dark Violet.

    themes-blog

    Customizing your entire application

    Each new theme makes every single widget, from Button to Data Grid look vivid and shiny. The only thing you need to do is include the desired theme’s css file in your page and optionally add your own customizations to it.

    All the new themes will be available as separate css files e.g. dx.generic.carmine.css. They are included in the installation package and on the DevExtreme CDN which hosts the new release.

    Not enough?

    Ok, so for our visualization widgets, we’ve taken things a bit further; besides the themes, we have added a new palette with every theme for these widgets to make them stand out. 

    palettes

    A palette is basically a set of colors for each series, range or area in widgets like the Chart, Pie Chart, Polar Chart, Circular Gauge, Linear Gauge, Vector Map, Tree Map and Funnel.

    You can apply an individual palette to one control or to all the controls without including different css files.

    If you want to use a palette for a single widget, you can use the palette property like:

    var chartOptions = {
        palette: 'Dark Moon', // or 'Carmine', 'Dark Violet', 'Soft Blue', 'Green Fog'
        //... 
    };
    
      

    If you want to change the palette for all widgets, you can call the changePalette method at the start of your application:

    DevExpress.viz.currentPalette('Dark Moon'); // or 'Carmine', 'Dark Violet', 'Soft Blue', 'Green Fog'
    
    
      

    Play around with the demos

    Once we have officially released our v17.2 version, the DevExtreme web-site will be updated as well so you can have a look how those new themes look by selecting one in the dropdown of the DevExtreme Gallery.

    widgetsgallery

    The ThemeBuilder

    One of the things I love about the new themes is that we have created them with our own DevExtreme ThemeBuilder. And now that we have those themes, the ThemeBuilder itself will be updated with the official v17.2 release to include these themes as well.

    This means that you can use one of the themes as a starting point to create your own!

    Can’t wait for the official release?

    You can start with the Soft Blue, Carmine, Green Mist, Dark Moon and Dark Violet themes today by getting the pre-beta version of DevExtreme through npm or bower by using the following command in your project folder:

    npm install devextreme@17.2.2-pre-beta
      

    Let me know what you think of these new themes!

  • Chart enhancements on WinForms (v17.2)

    In v17.2 of our WinForms Charts, we’ve added some useful features that both of you, the developer, and your end-users might appreciate.

    Criteria Based Filtering

    The Chart control already supported filtering on series, but in this release we have replaced the DataFilter property with the FilterCriteria and FilterString properties. This makes filtering more powerful and is also inline with several other controls like the Grid, Reporting and XPO. It allows you to use the DevExpress Criteria Language to filter series.

    It also allows you to use the FilterControl or the Filtering UI Context to select the data which is used by the Chart control without writing any code.

    FilteringUIContext

    Because of this change, you can use one filter control which manages the data for a Grid as well as a Chart!

    EqualFilter

    Bind a Chart to Grid data

    In the previous releases you always needed to bind the data to a DataSource like a collection of objects or a DataReader. In scenarios which involve a grid and a chart, these DataSources where used by both controls. With custom unbound grid columns, grouping and filtering  you always needed to code some additional mechanism to get that data in the chart as well.

    With v17.2, we have added a ControlRowSource component which allows you to bind the chart directly to the Grid control. With this feature, the chart doesn’t use the same DataSource as the grid, but it will actually use the rows and columns available in the grid as its DataSource. It will make use of things like Grouping, Sorting, Filtering which might have been set in the Grid when supplying data to the Chart.

    This also works in combination with the Treelist, Listbox and VerticalGrid controls.

    Grid Data In Chart

    Use a Chart as Grid Cell Editor

    With v17.2 we implemented a long requested feature; Use a chart as Grid Cell Editor!

    This gives you the possibility to design beautiful master-detail data visualizations as you can see:

    Cell Chart

    This functionality is based on the RepositoryItemAnyControl class and is now possible because we have implemented the IAnyControlEdit interface on the Chart control.

    Conclusion

    With this release we’ve taken a big step in letting different controls make use of each others functionality. For you this means writing less code and better performance. This will result in an even better experience for your end-users.

    Talking about performance and user experience; have you seen Julian’s blog post about that we’ve done with the XtraGrid in v17.2?

1
2 3 4 5 6 7 8 9
LIVE CHAT

Chat is one of the many ways you can contact members of the DevExpress Team.
We are available Monday-Friday between 7:30am and 4:30pm Pacific Time.

If you need additional product information, write to us at info@devexpress.com or call us at +1 (818) 844-3383

FOLLOW US

DevExpress engineers feature-complete Presentation Controls, IDE Productivity Tools, Business Application Frameworks, and Reporting Systems for Visual Studio, along with high-performance HTML JS Mobile Frameworks for developers targeting iOS, Android and Windows Phone. Whether using WPF, ASP.NET, WinForms, HTML5 or Windows 10, DevExpress tools help you build and deliver your best in the shortest time possible.

Copyright © 1998-2018 Developer Express Inc.
All trademarks or registered trademarks are property of their respective owners