Overview

Wisej Premium Extensions include a comprehensive collection of high-performance and responsive UI widgets for use in traditional web and next-gen mobile applications.

Concept

For the premium Syncfusion, DevExtreme, Ignite UI, and Telerik KendoUI integration packages we have used an approach different from the other integrations we publish on the open Wisej repositories. In this case we wanted to use all the features that are available to javascript, angular, react, blazor developers instead of trying to build a limited .NET object hierarchy.

When you look at the code, you will find a common base class [ej|dx|ej2|ig]Base for all the widgets classes, overloaded constructors that indicate which class to use, and a number of initialization options that may be different for some widgets.

The [ej|dx|ej2|ig]Base class uses a custom implementation that takes care of the creation and registration of events, methods, and templates. It also provides some simple methods to override in each derived class.

Each specific class has it's own nested .js file that may add specific functionality to filter event data to make it serializable for the server, make sure the wrapped widget fits the container, and whatever else may be needed to make the integration as smooth as possible.

All the premium extensions are open projects, meaning that we will keep adding, fixing, changing, and expanding them according to the requirements of our Technology Partners and needs we find on our projects using these extensions.

Demo

Live demos of the premium extension projects can be found here:

License

To use these extensions you need to acquire the appropriate JavaScript Bundle license from the vendor.

How to use

All the integrated widgets have 3 types of members: options, methods, and events. The options (you'll find them under "Configuration" in the API Reference documentation) are represented by a single JavaScript map. Methods are JavaScript functions. Events in the widgets are callback methods defined in the options map.

Options

When using the extension control classes in your .NET Wisej application, you have access to the entire set of options using a single property, Options. It is a dynamic .NET object and you can use it directly or assign it.

When you set the Options using the designer, you can simply copy and paste (and edit) any JSON string.

When you set (or change) the Options by code, you can

  • Assign the fields directly using the built-in dynamic objects,

  • Assign an object that has the properties you want to use,

  • Assign an anonymous class.

Assigning the fields directly will automatically update the widget on the client when the property that changes is on the first level. In case your code changes properties deeper than the first level in the hierarchy, you need to call widget1.Update().

this.dxCircularGauge1.Options.containerBackgroundColor = "blue";

this.dxCircularGauge1.Options.scale.startValue = 0;
this.dxCircularGauge1.Options.scale.endValue = 50;
this.dxCircularGauge1.Update();

The function BuildRanges() in the code sample below returns a .NET array of .NET classes with the members that match the fields expected by the dxCircularGauge widget.

this.dxCircularGauge1.Options.rangeContainer.ranges = buildRanges();

Anonymous classes (example below) allow for a syntax very similar to JavaScript. However, once you assign an anonymous class instance, you cannot change the value of it's properties. To change a value you have to reassign the anonymous object.

this.dxCircularGauge1.Options.rangeContainer.ranges = new object[] {
    new { startValue = 50, endValue = 90 },
    new { startValue = 90, endValue = 130 },
    new { startValue = 130, endValue = 150 }
};

You will find the complete set of options at the component vendor documentation site.

Methods

All the methods exposed by the JavaScript widget are available to your .NET extension class as C# or VB.NET methods using the Instance dynamic member. All methods are also available as async methods with the "Async" suffix.

Note: When using VB.NET you need to use Option Strict Off to allow the .NET dynamic compiler to handle the calls into the Instance object.

// C#
this.dxLinearGauge1.Instance.value(15);

// Calls a method "getFrameData" on client RangeChart widget.
// see:  https://docs.webix.com/api__ui.rangechart_getframedata.html.
this.rangeChart1.Instance.getFrameData((Action<object>)((result)=> {
    AlertBox.Show(result.ToJSON());
});

// or
var data = await this.rangeChart1.Instance.getFrameDataAsync();

However, some methods may return values that are not immediately usable in .NET, or you need to use several methods together in a single JavaScript function in a way that wouldn't make sense from the server. When you need to add a method to your widget instance, or your derived class, use the WidgetFunctions property in the designer (can be used at runtime as well) to register a new JavaScript function.

this.dxHtmlEditor1.WidgetFunctions = new[] {
    
    new WidgetFunction() {
        Name = "formatTextOptions",
        Source = @"
            this.widget.formatText(
            arguments[0], 
            arguments[1],
            { "bold": arguments[2], 
            "underline": arguments[3]});
        ";
    }
};

this.dxHtmlEditor1.Call("formatTextOptions", 0, 5, true, true);

// In alternative (C#):
this.dxHtmlEditor1.Instance.formatText(0, 5, new { bold = true, underline = true });

The code above adds a JavaScript function "formatTextOptions" to the widget and then calls it to set the text formatting for a specific block of text in the editor.

Be careful not to override existing methods. The extension will simply not register your new method and log an error in the JavaScript console.

You can also use the above WidgetFunction in the widget's Optionsconfiguration as a string. Call the function immediately using ()=>myfunction() or attach the function to a property using ()=>myFunction(without the parentheses).

Events

The events registered by the class (see constructor for each component in the source code) are also available as .NET events exposed by the Instance object:

When attaching events using the Instance member, you must prepend on to the name of the event.

// C#
// see: https://js.devexpress.com/Documentation/ApiReference/UI_Components/dxGantt/Events/#taskClick
this.dxGantt1.Instance.onTaskClick += new WidgetEventHandler(dxGantt1_WidgetEvent);

Note: Unfortunately in VB.NET you cannot use AddHandler or Handles to handle dynamic events. You can attach only a single handle using the syntax above, or attach to the existing WidgetEvent event and check the e.Type property.

Events fired by the widgets are callbacks, not events. The .NET classes representing each widget already registers a set of events and routes them to the .NET widget's WidgetEvent event. However, if your app needs to handle an event in JavaScript, you can use the WidgetEvents collection to register your event callback.

Event data is automatically filtered when returned to the server and can be accessed in the WidgetEventHandler e.Data member.

this.dxHtmlEditor1.WidgetEvents = new []{
  new WidgetEvent() {
    Name = "contextMenuClick",
    Source = @"
      this.makeLowerCase(); // this is not an actual method in the dxHtmlEditor widget.
    "
  }
};

The event args object sent by the widget is available as e and the code can refer to the widget simply using this. Note that in the event code this refers to the widget, while in function code this refers to the Wisej widget and this.widget refers to the wrapped widget.

Last updated