Don Wibier's Blog
  • DevIntersection Europe is around the corner

    DEVEurope_DWibier_336x280

    From November 14th till November 16th, DevIntersection Europe is being held in Haarlem, The Netherlands. Guess what…? DevExpress is sponsoring this great conference.

    If you check the awesome speaker line-up, you’ll see that I will do 2 sessions as well, so you’re invited to join me. To make it even more attractive to attend, I have a special discount code you can use when purchasing the tickets and you’ll save 10% on your ticket!

    John and I will be there with our booth giving demos and handing out T-Shirts and other goodies. We will be raffling off some cool prizes like a platform subscription of choice every day.

    If you’re there, make sure to come by our booth to say hello and get your raffle ticket!

  • DevExpress Meetups in the Netherlands

    Over the coming weeks, DevExpress is organizing a few informal meetups with our clients. They will give you an opportunity to talk with me directly, let me know what you’re doing with our controls and tools, and give me feedback on features and areas that we could improve.

    John Martin, our Developer Advocate, and I will be hosting these events and the only thing they will cost you is a bit of time. We shall be taking care of providing the beer and snacks!

    We are organizing 2 meetups in The Netherlands and we hope to see many of you.

    So far we have the following meetups planned:

    Date

    Time Location
    November 15th 17:00h – 21:00h Haarlem
    December 6th 18:00h – 20:00h Rotterdam

    To make sure we have enough capacity we would like you to register for free through Eventbrite.

    If any of these locations are too far from you, let me know and we certainly consider adding new meetups.

  • Watch the webinar on how to get started with our MVVM Framework for WinForms

    Recently, I did a webinar “Rock Your WinForms Apps with DevExpress MVVM".

    image

    In the webinar, I showed you what MVVM is all about and how to apply this design pattern on your WinForms applications by using our framework.

    You can re-watch the recording on YouTube, were you will see some of the powerful designtime and runtime features. The project being built in the webinar is available on GitHub. If you want to perform unit tests on your ViewModel like I mentioned, check out the WPF counterpart on my GitHub account. It has a test project in the solution to give you an idea on how to test your code.

    If you have any questions, leave a reaction, email or tweet me.

  • Impressions from .NET Developer Days Poland

    Last week, we were proud to be a gold sponsor of .NET Developer Days in Warsaw, Poland.

    John, Ivan, Tatyana and I were manning our booth where we talked with lots of people, handed out T-Shirts and other goodies and gave some cool demos of our products.

    Amongst other great sessions, I presented 3 sessions as well.

    We’d like to thank the organizers and attendees for making this such a great event!

  • DevExpress at BASTA! Fall 2016

    This week DevExpress is proud to be Gold Sponsor at the BASTA! conference in Mainz, Germany. John, Oliver and I are there with our awesome booth and lots of give-aways.

    image

    Oliver and I are both speaking at the conference. More info about our sessions can be found at https://basta.net/speaker/oliver-sturm/ and https://basta.net/speaker/don-wibier.

    We will be doing daily raffles where you can win a nice gadget like this can-racer or a platform subscription of choice!

    image

    Tonight we will be sponsoring the Pit-Stop event. The person who takes the least amount of time changing the tire, walks off with this nice RC racing car.

    image

    Make sure to visit our booth at Basta!

  • WPF: Asynchronous server mode for lookup editors (new in v16.1)

    In our v16.1 release we have introduced a very nice feature to improve the U.I experience on the LookUpEdit, ComboBoxEdit and ListBoxEdit.

    We call it asynchronous server mode and it means that we use our server mode functionality for the data being shown in the dropdown pane.

    Server mode is a very clever way of selecting small chunks of data to populate the visible area of the control. All data-aware operations like sorting, filtering and grouping are being performed in a background thread. This results in an instant feedback U.I. experience for the end-user as the editor and application will always remain responsive for user actions.

    When such an operation is in progress, we provide visual feedback in the form of an animation to indicate the status of the operation.

    When editors operate in server mode they also support auto complete when the dropdown is closed.

  • Webinar: Using DevExpress MVVM Magic with WPF

    This week, I presented a webinar about our MVVM framework which ships with our WPF control suite. In case you missed it, you can watch it here.

    image

    What is MVVM and why?

    MVVM stands for Model-View-ViewModel and it is a design pattern which requires you to make some architectural choices before you start on a project. I will only spend a little time on the ‘why’ since there are tons of great articles out there doing a way more detailed job.

    image

    The most important advantages in my opinion are:

    Seperation of concerns

    In this case, the View (U.I.) does not have any direct relation with the DataLayer (Models). The ViewModel provides all the presentation logic and accesses the DataLayer if needed.

    In most applications, data is stored in a relational database. The structure of your database is in most cases optimized to select and/or update information as quickly as possible. Also in most cases, this is not the most optimal way for presentation purposes. The ViewModel gives us the possibility to transform the data coming out of the DataLayer into an optimized (different) structure for presentation purposes.

    By using this approach, we can use one of the very powerful features of the WPF platform – databinding. The View databinds certain elements in the U.I. to properties or commands exposed by the ViewModel. As a result, in most cases there is no code-behind in a View.

    UnitTestable

    Another cool side effect of this pattern is that – because the ViewModel doesn’t care what is bound to it – we can replace the View with a UnitTest. Since all presentation logic is coded in the ViewModel, this means that we can UnitTest the presentation logic.

    Why did we build such a framework?

    While WPF is designed to support a lot of aspects of the MVVM design pattern, some things do require some coding in the ViewModels. To give you an example: A ViewModel is unable to interact directly with the UI, but what happens when some validation code in the ViewModel needs to raise a confirmation on the UI?

    This is implemented through Services and Behaviors and is something available out of the box through our framework. There are a couple more difficulties in this loosely coupled architecture which are managed easily through the framework.

    We also provide you with some really awesome design-time support built in to easily bind all kinds of things to the ViewModel. This support is provided with all DevExpress WPF controls.

    This all results in less code in your ViewModels which keeps things nice and clean.

    An introduction of the Framework

    The MVVM framework is convention based. This means that there are certain guidelines you need to follow and by doing so, you’ll be able to build applications in less time.

    In the webinar I created a ViewModel based on a number of those conventions. The bare minimum code for a ViewModel looks as follows:

    [POCOViewModel]
    public class TrackViewModel
    {
        public virtual TrackInfo Track { get; set; }
    
        [ServiceProperty(SearchMode = ServiceSearchMode.PreferParents)]
        protected virtual IMessageBoxService MessageBoxService { get { return null; } }
    
        protected TrackViewModel()
        {
            // for test purposes only !!
            Track = new TrackList()[15];
        }
        public static TrackViewModel Create()
        {
            return ViewModelSource.Create(() = > new TrackViewModel());
        }
    
        public bool CanResetName()
        {
            return Track != null & amp; & !String.IsNullOrEmpty(Track.Name);
        }
        public void ResetName()
        {
            if (Track != null)
            {
                Track.Name = "";
            }
        }
    }
    

    In the code there are a couple of interesting points.

    • The class is decorated with the [POCOViewModel]
    • Properties (for binding purposes) are marked virtual
    • The constructor is marked protected which means that we cannot instantiate such a ViewModel directly
    • There is a public static Create method which instantiates a new instance of this ViewModel through the ViewModelSource factory
    • The method bool CanResetName has a relation with method ResetName

    The creation of an instance of this class through that factory is essential for the magic to happen. What happens under the hood is that the framework creates a new ViewModel class which is derived from our ViewModel. In this derived class, we add all kinds framework related things to the ViewModel. For instance, we create Commands for public methods, we set constraints depending on the results of those bool Can… methods.

    Also the IMessageBoxService MessageBoxService property - which just returns null - will have changed behavior in the derived class.

    Once we have set everything up according to those conventions (and did a build), we’re able to switch to the View. Through the Task Menu of any of the controls, we’ll be able to use those design-time features which come with the framework.

    image

    During the webinar I introduced a second View + ViewModel and I demonstrate how one ViewModel activates another and synchronize some data. I also show how easy it is to map events (from the grid) to commands in the ViewModel by binding expressions.

    UnitTesting

    If you want to perform a test on one of the ViewModels, you can setup a test like:

    [TestFixture]
    class TrackViewModelTests
    {
        const string INITIAL_TRACKNAME = "My Test Track";
        const string MODIFIED_TRACKNAME = "My Modified Test Track";
    
        [SetUp]
        protected void SetUp()
        {
            // initialize your test here
        }
    
        [Test]
        public void TestResetNameCommandNo()
        {
    
            var vm = TrackViewModel.Create(new TrackInfo() { Name = INITIAL_TRACKNAME });
            var serviceContainer = (vm as ISupportServices).ServiceContainer;
    
            IMessageBoxService msgSvc = new DummyServiceForMessageBox(MessageResult.No);
            serviceContainer.RegisterService(msgSvc);
    
            //Testing the ResetName behaviour while clicking No on the confirmation dialog...
            vm.ResetName();
            Assert.That(vm.Name, Is.EqualTo(INITIAL_TRACKNAME));
        }
    }
    

    Do note that the DummyServiceForMessageBox can be a simple class which looks like:

    internal class DummyServiceForMessageBox : IMessageBoxService
    {
        private readonly MessageResult resultToTest;
        public DummyServiceForMessageBox(MessageResult resultToTest)
        {
            this.resultToTest = resultToTest;
        }
        MessageResult IMessageBoxService.Show(string messageBoxText, string caption,
            MessageButton button, MessageIcon icon, MessageResult defaultResult)
        {
            return this.resultToTest;
        }
    }

    Because these services are interfaced based, we can simple change the implementation of this DummyServiceForMessageBox from showing the dialog to an immediate Yes or No.

    The Demo Project

    The project I have created during the webinar is available on github at: https://github.com/donwibier/DXWPF-MVVM-Magic.git

    I have also included an NUnit test project to demonstrate how to test one of those ViewModels.

    Let me know what you think of the framework and if you are ready for a deep-dive webinar!

  • Creating Desktop Apps for Windows, Mac OS and Linux with DevExtreme

    Last week I did a webinar on creating desktop applications with DevExtreme and Electron. In case you missed it, it is available on our YouTube Channel

    image

    This was also one of the first webinars where a swift introduction on DevExtreme with Visual Studio Code, Git, Node/NPM (Node Package Manager) and the Command-Line was performed. In case you have heard the term NPM, but don’t know exactly what it is; NPM is for Node what Nuget is for dotNet.

    For all of you wanting to redo the demo project on your own – a simple ToDo app – I have written down the steps that where performed in the webinar.

    Prerequisites

    Before opening a command prompt, make sure you have the latest versions installed of the following:

    With these tools setup, you can fire up a command prompt and create a folder which will hold the project and navigate into it.

    Make sure you use some short folder structure like C:\Src\App1, since the MAX_PATH value in Windows is reached fairly quickly when using NPM and node modules!

    C:\cd \Src
    C:\Src>md App1
    C:\Src>cd App1

    No project template?

    Because Visual Studio Code doesn’t support Project templates out of the box, I decided to use a GitHub repo as project template by cloning it.

    The repo can be found at: https://github.com/donwibier/DXDevExtremeKnockoutTemplate, and we can clone it to our App1 folder with the following command at the command prompt:

    C:\Src\App1>git clone https://github.com/donwibier/DXDevExtremeKnockoutTemplate . 
    (don’t forget the dot at the end)

    image

    Once the cloning is finished, we can start VSCode like:

    C:\Src\App1>code .
    (mind the dot)

    The package.json already includes the required NPM packages but if you’re new to NPM, it might be worth taking a look at it. You could e.g. change the application name and version number.

    image

    If you’re used to the full Visual Studio experience and have used the project template which comes with DevExtreme, you might recognize the folder structure as well as several files provided with this clone.

    One thing which is slightly different, is the lack of JavaScript files in the /js folder and the references in the index.html. This is because we will use NPM to get all dependencies for this project.

    Because we made a fresh clone, we need to get all those dependencies through NPM. This is done by the following command:

    C:\Src\App1>npm install

    image

    After some time – depending on your internet speed – NPM finishes. In our case it comes with a couple of warnings which we can safely ignore. This project will not use Angular, Globalize or Webpack.

    Now, we can start the project in our browser by issuing the command:

    C:\Src\App1>npm start

    The package.json will be checked for the scripts / start setting which will execute the lite-server and show a browser with our SPA (Single Page Application).

    image

    Lite-server is a small web-server – much like IIS Express for ASP.NET development – to test SPA web-based apps. It is written in Node by John Papa and Christopher Martin. It is specified as dev-dependency in the package.json, so it was downloaded and configured during our npm install command. It has a couple of convenient features like browser-sync. This feature monitors the source folder for changed files and automatically refreshes the browser used for testing.

    We will not be using this since we’re going to create a desktop app. Let’s hit Ctrl+C in our terminal window to exit the lite-server.

    Getting Electron in the project

    So, let’s turn this into a Desktop app by adding the Electron package to the project. This is done by entering the following command:

    C:\Src\App1>npm install electron-prebuilt –save

    This will download the Electron package and stores the dependency in our package.json file so it will look like this:

    image

    The npm install only caused step 1 to be added to the package.json file because of the –save option. Since we’re not using the lite-server anymore, we could either remove the lite-server dev-dependency manually from the package.json file or we could issue the command:

    C:\Src\App1>npm remove lite-server –save-dev

    If we want the electron runtime to boot up when we issue the npm start command, we need to change the scripts / start option manually to electron main.js as mentioned in step 3.

    Initializing the Electron app

    So now everything is almost setup to run our JavaScript SPA as a desktop application. If you look closely to the start configuration and next to your project folder, you might notice that one file is missing – main.js.

    The main.js file is a JavaScript file containing the bootstrap code for initializing the main process of the desktop application. It initializes the bare chromium browser window and determines what to do when certain thing concerning that window are happening – like minimizing / maximizing and closing the window.

    The content of this file is pretty much the same as found on the Quick start guide available at the http://electron.atom.io/.

    const electron = require('electron');
    // Module to control application life.
    const app = electron.app;
    // Module to create native browser window.
    const BrowserWindow = electron.BrowserWindow;
    
    global.settings = {
        databaseFolder : app.getPath("documents")
    }
    // Keep a global reference of the window object, if you don't, the window will
    // be closed automatically when the JavaScript object is garbage collected.
    let mainWnd;
    
    function createWindow() {
        // Create the browser window.
        mainWnd = new BrowserWindow({ width: 1200, height: 700 });
        // and load the index.html of the app.
        mainWnd.loadURL(`file://${__dirname}/index.html`);
        // Open the DevTools.
        //mainWnd.webContents.openDevTools();
        // Emitted when the window is closed.
        mainWnd.on('closed', () => {
            // Dereference the window object, usually you would store windows
            // in an array if your app supports multi windows, this is the time
            // when you should delete the corresponding element.
            mainWnd = null;
        });
    }
    // This method will be called when Electron has finished
    // initialization and is ready to create browser windows.
    // Some APIs can only be used after this event occurs.
    app.on('ready', createWindow);
    // Quit when all windows are closed.
    app.on('window-all-closed', () => {
        // On macOS it is common for applications and their menu bar
        // to stay active until the user quits explicitly with Cmd + Q
        if (process.platform !== 'darwin') {
            app.quit();
        }
    });
    app.on('activate', () => {
        // On macOS it's common to re-create a window in the app when the
        // dock icon is clicked and there are no other windows open.
        if (mainWnd === null) {
            createWindow();
        }
    });

    The code inside the main.js file is actually being executed in the Node context of an Electron application. One of the nice things in Node is the use or the require(…) construct to include npm packages.

    A nice side-effect is that we can also use the require method inside our render process(es) to include npm packages. Render processes are basically the rendering of our SPA app – html/CSS/JavaScript assets inside the Chromium window.

    The reason that we can use require(..) in our render process is because Electron adds a couple methods to the JavaScript Window object, which also allows us to exchange data between the main and render processes and to facilitate the Electron API to access local resources and O.S. specific features.

    JQuery comment

    Those extra methods mentioned before are causing JQuery to fail while initializing inside an Electron window for various reasons. This can be fixed easily by changing the index.html script sections at the bottom of the page. Let’s also make use of the require construct:

    Original code in index.html:
    <body>
        <div class="dx-viewport"></div>
        <script src="./node_modules/jquery/dist/jquery.js"></script>
        <script src="./node_modules/knockout/build/output/knockout-latest.js"></script>
        <script src="./node_modules/devextreme/dist/js/dx.all.js"></script>
        <script src="./js/db.js"></script>
        <script src="./index.js"></script>
        <script src="./layouts/Desktop/DesktopLayout.js"></script>
        <!-- ViewModels -->
        <script type="text/javascript" src="./views/home.js"></script>
    </body>
    		  
    Electron changes in index.html:
    <body>
        <div class="dx-viewport"></div>
        <script>
            //because of electron, we need to include jQuery slightly different
            window.$ = window.jQuery = require("jquery");
            window.ko = require("knockout");
            var dxapp = dxapp || {};
    
            require("./node_modules/devextreme/dist/js/dx.all.js");
            require("./layouts/Desktop/DesktopLayout.js");
            require("./js/db.js");
            require("./index.js");
            require("./views/tasks.js");
        </script>
    </body>
    
    	  

    With these modifications in place, we're ready to boot up our desktop app by entering the command:

    C:\Src\App1\npm start

    Final comments on the webinar project

    In the webinar, I showed how to use a local SQLite database to store the ToDo items. For this I replaced the /js/db.js file with the one hosted on github. I also added the npm package sqlite-sync to the project with:

    npm install sqlite-sync –save

    This script also requires the app.json file to be present in the root folder of our project and it shows you how to work with configuration settings in an Electron app.

    The db.js script shows you a way on how to create a DevExtreme Datasource with a custom store which supports paged results, sorting and filtering. This functionality is used in the /views/tasks.js file to create a proper viewmodel for the view /views/tasks.html file. Here I added a dxDataGrid widget.

    The entire project created during the webinar is also available on github and can be tested with the following commands in your terminal window:

    C:\Src>md app2
    C:\Src>cd app2
    C:\Src\app2>git clone https://github.com/donwibier/DXDevExtremeElectron .
    C:\Src\app2>npm install && npm start

    In case you want to know more on Electron, please check their documentation at http://electron.atom.io/docs/ . This also contains information about packaging you application for the specific platforms, best practices and things to consider when building a cross-platform app.

    Don’t forget to test it on a Linux machine as well as a Mac and do let me know what you have created with DevExtreme and Electron!

  • DevExtreme: New client-side export for Charts and Data Visualization

    DevExtreme comes with some really powerful Charting and other data visualization controls like Maps, Gauges and Range widgets. One of the issues faced in the pre-v16.1 versions of our suite was that exporting such a widget to e.g. PNG, JPG or PDF was a bit of a tedious job.

    You would need the specific widget bound to a dxExporter widget on the client, and a specially customized PhantomJS instance configured on the server:

    img1[3]

    Besides the fact that you would need this extra server, you can imagine that this process takes some time to configure and test.

    Exporting in v16.1

    In our v16.1 release we have added export functionality to all the widgets. This means that there is no need for this custom PhantomJS server, and that it will work pretty much out of the box.

    img2

    How does it work?

    If you want to enable export functionality for a specific widget, the only thing you need to specify in the configuration object of the widget is:

    options = {
        export: {
            enabled: true
        },
        ...
    } 

    What about customization?

    Just like the older releases, v16.1 supports exporting as well as printing to JPG, PNG, GIF, PDF and SVG.

    img3

    You can even specify a default filename of the export – even without extension – by specifying the fileName property. We’ll add the extension to the filename automatically depending on the chosen format.

    options = {
        export: {
            fileName: "Sales2016ByMonth"
        },
        ...
    }

    In the v16.1 release, we added a number of additional features such as specifying the background color for an exported chart:

    options = {
        export: {
            backgroundColor: "#282828"
        },
        ...
    }

    This is great for creating a uniform look or complying with your corporate identity.

    img4

    Menu enhancements

    In previous versions, the export menu was provided by the dxExporter class. To add this menu to your widget, you would add a reference to that visualization widget in the dxExporter configuration object. To specify a custom menu or to call exporting/printing via custom events on your page, you would have to use the dxExporter API.

    img5

    We have made this way easier with v16.1. Since all the widgets have the export functionality included, they also include a default export menu. This menu will be shown automatically if exporting of the widget is enabled.

    image

    Because this menu is now part of the widget, we make sure that it is perfectly aligned and positioned inside the widget.

    All this out-of-the-box behavior is part of the exporting API which comes with the visualization widgets. This gives you the possibility to customize and fine-tune several exporting options according to your needs.

    chartInstance.exportTo("myExample", "pdf");

    Conclusion

    The new client-side exporting features in v16.1 are easier and faster to setup. They also allow you to change several aspects of the default export behavior.

    Let me know what you think of this!

  • DevExtreme: New project template for WebAPI back-end and client (Coming soon in v16.1)

    We already had a very nice project template in the previous versions of DevExtreme which allows you to create an OData service based on an existing database in minutes.

    The OData protocol is a data access protocol specifically designed to use a uniform way to query and manipulate datasets. As a result, this service includes CRUD operations and execution of paged/sorted queries.

    With another project template – The MultiChannel one – you could then create the base for your DevExtreme app including CRUD operations and views. The project template is able to query the meta-data of the OData service to fetch entities as well as fieldnames and types to create JavaScript models and HTML views. Yet another nice feature made possible by the OData protocol.

    One of the more difficult aspects of OData are security and identity aspects. This is something easier done with a WebAPI.

    Creating a WebAPI back-end in minutes

    With the upcoming v16.1 release we have added another project template – DevExtreme WebAPI OData service – which combines the best of both worlds.

    image

    Once the wizard has finished, you will have a WebAPI project with controllers for all database entities selected in the wizard.

    Using MS Identity to secure your WebAPI service

    One of the options in the Wizard is whether you want to have Authentication or not. When you select Individual User Accounts, the project will be created including the configuration for MS Identity.

    image

    You can now start securing your Controllers and / or your action methods on the controllers.

    namespace MyWebAPIService {
    [Authorize]
    public class InvoiceController : ODataController
    {
    private ChinookConnection db = new ChinookConnection();

    // GET: odata/Invoice
    [EnableQuery]
    [OverrideAuthorization]
    public IQueryable<Invoice> GetInvoice()
    {
    return db.Invoice;
    }

    // ... more code ...
    }

    Another thing we have configured with the WebAPI service is CORS and JSONP. This means that you can call the WebAPI endpoints from another domain without getting JavaScript errors.

    What about the Client App?

    Once you try to access the secured WebAPI back-end from within a DevExtreme Client App, you will need to authenticate before data is returned. (You would need a login-view and optionally a registration-view)

    We have added additional functionality to our MultiChannel project template which will add the additional views and code for authenticating and registering. We also include a profile view.

    image

     

    If the app tries to access a secure end-point on the WebAPI back-end, you will be automatically taken to the login view to authenticate out of the box!

    Windows Phone 10 Support

    The last new feature I’d like to mention is that we have deprecated the “cordova-wp8” platform and upgraded to the “cordova-windows” platform.

    This means that you are now able to deploy for Windows 8, 8.1 and 10. The result of the deployment wizard will in this case be an .appx package instead of the older .xap package.

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-2017 Developer Express Inc.
All trademarks or registered trademarks are property of their respective owners