What's new in 2.2

Wisej 2.2 introduces built-in PWA support, dynamic integration with all major JavaScript vendors, native iOS and Android integration (available for Technology Partners), enhancements to all controls, improved memory management, and lots of new functionality across the board.

PWA Support

Progressive Web Application (PWA) support is now built-in into Wisej. It allows a Wisej application to be installed in the desktop or a mobile device along with the locally cached libraries and offline pages.

A new PWA project template includes a set of professionally-designed offline pages end the required manifest file. The worker process script is embedded in the Wisej loader. Wisej will automatically pre-cache locally all the resources and offline pages. Enable PWA support in Default.json by setting enablePWA: true.

The improved offline detection process automatically switches to the offline pages when it detects a disconnection and restores the application when the connection is restored.

A new event Application.BeforeInstallPrompt allows the application to detect when it can be installed as a PWA, and a new client-side method Wisej.showPWAPrompt() displays the browser's PWA installation prompt. Using the Application.BeforeInstallPrompt event allows the application to display a custom notification to the user (the browser's default PWA notification is just a tiny + symbol in the address bar.)

At this time it appears that only Chrome fires the BeforeInstallPrompt event.

Additionally, the application can attach a client side event to a button or an icon to show the PWA installation prompt when the user clicks the control.

It is not possible to show the installation prompt from a server side event. To show the prompt on a button click, add a client event handler for the "execute" event and call "Wisej.showPWAPrompt()".

When the application goes offline, Wisej loads the /Offline/Default.html page. The image below is one of the pages included with the project template. However, you can put an entire JavaScript application inside the /Offline folder. Wisej will pre-cache locally all the files at all level.

Wisej will switch back to the application as soon as it detects that the connection is restored. Unless the session expired, the entire previous state is reloaded and the user is able to keep working from where the disconnection occurred.

iOS and Android Integration

Currently the native integration packages for iOS (Xcode) and Android (Android Studio) are available for free only to Technology Partners. However, we are planning to add new license options to Wisej to make these packages available without having to sign up for the Technology Partner program.

Our integration packages create a hybrid application, where the Wisej web application is able to interact with all native-only features of the mobile device.

The Wisej app can: show native alerts, use the camera, use the microphone, use the GPS, read the magnetometer read the gyroscope, read the accelerometer, play sounds, switch the flashlight, push notifications, read and write NFC chips, authenticate using TouchID or FaceID, create a native Toolbar, create a native TabBar, manage the StatusBar, read all the device information, handle multiple screens, lock the screen orientation, manage the screen brightness, brew coffee, and more…

You can achieve similar functionality for free by using the PhoneGap open source project. In our view, the learning curve is steeper and the functionality offered by PhoneGap is not as powerful as our integration.

For example, this is all the code you need to authenticate a user using FaceID in C# or VB.NET from the server side.

if (Device.Authenticate("Show me your pretty face!"))
{
  AlertBox.Show("Welcome! You are you.");
}

A Wisej hybrid application can also push notifications, read any property of the device, store files locally, and manage a native toolbar, a tabbar, the status bar, and all the available sensors through the Device object.

Wisej 2.2 also greatly improves virtual scrolling and touch integration.

DataGridView

There are two important enhancements in the Wisej.Web.DataGridView control:

Virtual Rows

Starting from Wisej 2.2, the DataGridView doesn't create any row when the grid is data-bound or running with VirtualMode set to true. It instead gets the values directly from the data source or the CellValueNeeded event when virtual.

A simple test with 100K rows and 10 columns in VirtualMode uses about 5MB in Wisej 2.1 and only about 400KB in Wisej 2.2. It basically only needs 1 Int32 per row to keep track of the state of each row.

As the code requests rows, the framework converts virtual rows into real rows transparently. However, if the application is changed to use dataGrid.GetValue(col, row ) and dataGrid.SetValue(col, row, value) instead of addressing the cells directly, it will read and save from/to the data source and will not create any row.

Selection Modes

Now the DataGridView supports all the standard selection modes (CellSelect, FullRowSelect, FullColumnSelect, RowHeaderSelect, NoSelection) and adds a new mode: RowColumnHeaderSelect.

See DataGridViewSelectionMode for a description of each selection mode.

You can use the SelectedCells, SelectedRows and SelectedColumns collection to read the selected objects.

Note that the collections of selected objects depend on the SelectionMode. For example, if the SelectionMode is set to ColumnHeaderSelect, users can select cells or columns. When the user selects a column by clicking on the header, the SelectedColumns collection will return the selected column, but the SelectedCells collection will be empty. However, testing the DataGridViewCell.Selected property of each cell in the selected column will return true.

Toast Notifications

Wisej 2.2 includes a new and lighter notification control: Wisej.Web.Toast.

Unlike the MessageBox and AlertBox, which are static classes, the Toast is a component that you create and can hold on to in your application. You can reuse it and you can update the content while the Toast is visible.

It can be located in any of the 9 standard locations. By default it appears at the TopCenter location. It contains an icon and a text that can display any HTML content (by setting the AllowHtml property to true).

Toasts auto close by default after 5 seconds but they do not auto dispose. To auto dispose a toast instance when it's closed, set the AutoDispose property to true. You can detect when the user clicks on a Toast by handling the Click event, and handle the Close event to run code when the Toast is closed.Populate a ComboBox without keeping the binding link with the data source.

// Show a Toast and update it in the background.
this.myToast = new Toast("Records saved successfully", "icon-save");
this.myToast.Show();

// Or
new Toast("Records saved successfully", "icon-save").Show();

// Update a Toast after it has been made visible.
this.buttonDelete.Click += (s, e) => {
    this.myToast.Text = "Deleted!";
};

DataRepeater

Now the DataRepeater supports items of variable height (when in vertical mode) and width (when in horizontal mode). It can auto size the child items to fit the content, or you can set the size of each item programmatically.

Additionally, the virtual scrolling, mobile scrolling, and prefetching have been improved considerably. The DataRepeater can now handle unlimited items seamlessly without a glitch.

Applications using the DataRepeater can set the AutoSize property of the panel template to true to automatically resize each item panel to fit its content, or you can set the height or width of each item while handling the ItemUpdate event

Data Binding

All controls that support data binding have been improved with two new methods:

  • Fill

    Populates the control from a data source object without keeping the control linked to the data source.

  • Append

    Appends the data source object to a previously populated control without keeping the control linked to the data source.

These new methods allow a control to retrieve the data from the data source without keeping the bidirectional binding link. All the properties that specify the fields to bind to are still used, making the population of list controls much easier.

// Fill the ComboBox with data
// this.comboBox1.DataSource = options;
this.comboBox1.Fill(options);

// Add a second set of options without having to create a new data source.
this.comboBox1.Append(options2);

Wisej 2.2 also adds full data binding support to the ListView control, including support for the new Fill and Append methods.

The new ListView control supports the following data binding properties:

  • DataSource

    Returns or sets the data source for the ListView control.

  • DataMember

    Returns or sets the name of the list or table in the data source for which the ListView is displaying data.

  • ColumnHeader.DisplayPropertyName

    Returns or sets the property to display in the ListView items.

  • ListViewItem.DataBoundItem

    Returns the data-bound object for the ListViewItem.

The DisplayPropertyName property can only be set on column headers in order to be able to data bind items and sub-items.

Integrations

All the premium integration libraries are now free. Each library is a GitHub ongoing project. The libraries for Wisej 2.1 include some extra dynamic code that is not built-in the Wisej.Web.Widget class in Wisej 2.2.

The Wisej.Web.Widget class exposes a new Instance property. It's a dynamic object that is able to convert any method call into a JavaScript call on the third-party widget and can attach custom event handler to events fired by the implementation.

// In Wisej 2.1
this.gage.Call("value", 10);

// In Wisej 2.2
this.gage.Instance.value(10);
this.gage.Instance.onValueChanged += (s, e) => {

  AlertBox.Show($"New value:{(int)e.getData()}");

};

You must buy a license directly from the vendor of the widget library. Wisej doesn't include any free license!

Lazy Loading

The ComboBox and the ListBox control have a new LazyLoading property, similar to the existing TreeNode.LazyLoading.

When LazyLoading is set to true, the list items (or child nodes in a TreeNode) are sent to the client the first time the ComboBox is dropped down, or when the ListBox "appears" on the client browser. It reduces the size of the data sent to the browser when creating a page and speeds up the initial loading of pages and windows.

All Controls

All controls in Wisej 2.2 have some enhancement:

  • Control.ToolTipText

    All controls have a new ToolTipText property. It allows an application to set the tooltip text on any control without having to add the Wisej.Web.ToolTip provider.

    However, if the application needs to modify some additional aspects of tooltips, it should still use the Wisej.Web.ToolTip provider which exposes the additional tooltip properties.

  • PictureBox.Filter

    Sets a CSS filter on the PictureBox image.

  • TabControl.ScrollStep

    Sets the number of pixels to scroll when the scroll buttons are pressed to bring a tab into view.

  • ListBox.IncrementalSelection

    When true (default) the ListBox caches keystrokes for less than a second allowing a user to type and incrementally select the list items, i.e. typing "ab" selects the first item that start with "ab". When false, typing "ab" will select the first item that starts with "b".

  • TextBoxBase.SelectOnEnter, ComboBox.SelectOnEnter, DateTimePicker.SelectOnEnter, UpDownBase.SelectOnEnter

    When SelectOnEnter is true, the entire content in the editable area is always selected when the control gains the focus.

  • TreeView.RighClickSelection, ListBox.RightClickSelection

    When true, right clicking a TreeNode or a ListBox item (i.e. to show a ContextMenu) will select the item.

  • TagTextBox.KeepWatermark

    When true, the TagTextBox keeps showing the Watermark text in the editable portion of the control after the tags.

  • DataGridView.SelectionDelay

    When set to a value greater than 0 (the default), the grid waits the specified number of milliseconds before notifying the server that the selected element has been changed using the keyboard.

    This property prevents the server from being flooded with row selection events when a user rapidly navigates and selects different rows using the up/down keys.

  • FileDialog.LoadPath, FolderBrowserDialog.LoadPath

    The file and folder dialogs expose a new LoadPath event. It is fired for each file and each folder loaded by the dialogs. An application can handle this event and set the icon to display, the size, and the dates related to the file or folder. The event is cancelable, allowing the handler to set e.Cancel to true to filter out specific files or folders from the list.

  • Application.SetSessionTImeout

    Changes the session timeout for the current session only.

Application Events

The Application object exposes two new global events:

  • ActiveWindowChanged

    This event is fired when the active floating window changes. Allows an application to react to the change of the active window globally.

  • FocusedControlChanged

    This even is fired when the focused control changes, regardless of where it's located. Allows an application to process changes to the currently focused control.

Configuration

There are two new settings that are supported in the Default.json configuration file:

  • threadPool

    ThreadPool is a map defined as {minWorkerThreads, minCompletionPortThreads, maxWorkedThreads, maxCompletionPortThreads} that corresponds to the system's ThreadPool settings that can be applied by code or in machine.config. See ThreadPool.SetMinThreads. All properties are optionals. A typical settings is "threadPool":{minWorkerThreads: 100}.

  • enablePWA

    Enables PWA support. When set to true, the Wisej bootstrapper will include the built-in service worker. It will preload and cache locally the Wisej libraries and all the assets found in the /Offline directory.

Last updated