Log In
Home
Support
Demos
Documentation
Blogs
Training
Webinars
[Expand]General Information
[Expand]WinForms Controls
[Expand]ASP.NET Controls and MVC Extensions
[Expand]ASP.NET Bootstrap Controls
[Expand]WPF Controls
[Expand]Xamarin Controls
[Expand]Windows 10 App Controls
[Expand]Document Server
[Expand]Reporting
[Expand]Report Server
[Expand]Dashboard
[Collapse]eXpressApp Framework
 [Expand]Fundamentals
 [Expand]Getting Started
 [Collapse]Concepts
  [Expand]Application Solution Components
  [Expand]Business Model Design
  [Expand]Application Model
  [Expand]UI Construction
  [Collapse]Extend Functionality
   [Expand]Built-in Controllers and Actions
    Controllers
    Actions
    Customize Controllers and Actions
    Add Actions to a Popup Window
    Dialog Controller
    Activate a Controller for the Logon Form
    Determine Why an Action, Controller or Editor is Inactive
    Determine an Action's Controller and Identifier
  [Expand]Data Manipulation and Business Logic
  [Expand]Security System
  [Expand]Localization
  [Expand]System Module
  [Expand]Extra Modules
  [Expand]Debugging and Error Handling
  [Expand]Filtering
  [Expand]Application Life Cycle
 [Expand]Design-Time Features
 [Expand]Functional Testing
 [Expand]Deployment
 [Expand]Task-Based Help
 [Expand]Frequently Asked Questions
 [Expand]API Reference
[Expand]CodeRush
[Expand]Cross-Platform Core Libraries
[Expand]Tools and Utilities
[Expand]End-User Documentation

Customize Controllers and Actions

To implement a new feature in the eXpressApp Framework, create a new Controller. If the feature requires end-user interaction, add Actions to it. At the same time, you may need to customize a Controller or Action provided by the eXpressApp Framework or a third party. Most of built-in controllers expose events you can handle to add your custom code. Another approach is to inherit from the existing Controller and override its virtual methods. In some situations, it is easier and more effective to handle the Controller's events or the Action's events. In this topic, we will detail the situations in which each of these approaches to customize the provided features is more appropriate.

Expanded Access Controller's Events and Properties

This approach to customizing a particular feature is more appropriate if several additional independent customizations of an Action's behavior or a Controller's behavior are required. For instance, two modules declare business objects that demand additional initialization when they are created via the New Action. In this instance, both of these modules should extend the New Action behavior independently. In this case, handling events is more appropriate than inheriting from a Controller.

Note

In specific situations, you may need to handle a chain of events, rather than a single event.

You can access any built-in Controller built-in Controller from your custom controller using the Frame.GetController<ControllerType> method.

The following code demonstrates how to remove the Person item from the New Action's items list, to prohibit end-users from creating Person objects. A new Controller is created for this purpose. In its OnActivated method, the NewObjectViewController is accessed to subscribe to its NewObjectViewController.CollectDescendantTypes event. This event is fired when generating the New Action's items list. In the CollectDescendantTypes event handler, the Person item is removed from this list. The OnDectivated method unsubscribes the CollectDescendantTypes event.

Important

To avoid possible null reference exceptions in nested List Views, always ensure that the Frame.GetController<ControllerType> method result is not null when the XafApplication.OptimizedControllersCreation property is true.

Expanded Inherit From a Controller

When building an XAF application, you may face the following task: a Controller provides a useful feature, but you need to slightly customize it. This customization does not depend on any conditions, so you will not need to modify the customizations in another module. In this instance, the best technique is to inherit from the required Controller and override its virtual methods. You may need to customize a particular Action as well. In this instance, since Actions are contained in Controllers, you will also need to inherit from the Action's Controller and override its virtual methods.

All of the Controllers that do not have descendants are instantiated for a Frame. Also, since a descendant Controller inherits the base Controller's Actions, it generally does not make sense to create several descendants of a Controller within modules that might be used together in an XAF application. In this situation, all of these descendants will be instantiated, and there will be several copies of the base Controller's Actions available. This situation causes an exception because Actions must have unique IDs. Thus, it is better to create only one descendant of the base Controller and perform all the customizations in it. If required, however, you can have several descendant Controllers, but in this instance you will need to manually disable inherited Actions in the Controllers' code.

Important

  • Take a special note on selecting an appropriate built-in controller type when creating its descendant. In most cases, creating a descendant of a built-in controller requires selecting the last descendant in the inheritance chain. For example, if a controller has WinForms or ASP.NET-specific descendants (such as the WinModificationsController and WebModificationsController descendants of the ModificationsController class), it is necessary to create their descendants rather than a descendant of the parent class. Otherwise, both the built-in controller and your descendant will be activated, and duplicate actions will be displayed, as mentioned above.
  • Do not change the ViewController.TargetObjectType, ViewController.TargetViewType, ViewController.TargetViewId or ViewController.TargetViewNesting property values when inheriting a built-in Controller. Otherwise, you will lose the functionality of the inherited Controller in other Views that do not match the conditions specified by these properties.

When inheriting from a Controller, the Application Model will contain information on both the base and inherited Controllers. In the ActionDesign | Controllers node, the new Controller will contain Actions declared in it. The inherited Actions will be displayed under the base Controller's node.

As an example of this customization type, consider the WebModificationsController Controller. It contains the following Actions: Cancel, Save, SaveAndClose and Edit. Each Action has a virtual method: Cancel, Save, SaveAndClose and ExecuteEdit. This method is invoked when an end-user performs a certain operation with the Action. So to customize a default execution process, you can inherit from the WebModificationsController Controller and override any of these virtual methods. In this case, all of the UI settings (Category, Caption, Image, Shortcut, Tooltip, etc.) and the management state (Active and Enabled) of the actions will be reused.

By default, after executing the SaveAndClose Action in an ASP.NET application, a Detail View is displayed in a view mode. With the Controller demonstrated in the code below, the Incident Detail View is closed after executing this Action.

In this example, an Action behavior is customized via a single method. However, Controllers and Actions can be more complex, so, you may need to override several virtual methods.

Expanded See Also

How would you rate this topic?​​​​​​​