This example implements the following scenarios when an end-user clicks on a custom item in the navigation control:
- a custom non-XAF form is opened as a result;
- a standard XAF View containing a custom user control is opened as a result.
Both custom forms and user controls display persistent data from the XAF application database. For that purpose, this example solution provides a set of reusable elements (custom ViewItem and Application Model extensions) organized in a way that you can once implement them in an XAF module and reuse to display custom user controls in various forms.
Take special note that if you do not require a complex and reusable solution for this task, it is recommended to use a much simpler and built-in XAF solution - ControlDetailItem placed within a DashboardView. This item can be added and customized as described at eXpressApp Framework > Task-Based Help > How to: Create a Custom Control Detail Item.
See also the Using a Control that is not Integrated by Default article for other integration options.
If this is not your case, proceed to the instructions below:
1. Define a base structure of the navigation control in your XAF application, as shown in the E911.Module\Model.DesignedDiffs.xafml file.
You can simply copy and paste the contents of the NavigationItems element into the corresponding file (pre-opened via the text editor) of your platform-agnostic module.
The same customizations can be achieved via the Model Editor visually.
Take special note that you can set the View parameter to any View from the list, e.g. AboutInfo_DetailView, BaseObject_ListView, etc.
This navigation structure will be further customized in the WinForms and ASP.NET executable projects later.
2. Intercept events of the navigation control to display a custom form when a custom navigation item is clicked.
To do this, implement a WindowController into your platform-agnostic module and handle events of the ShowNavigationItemController class as per the E911.Module\Controllers\ShowCustomFormWindowController.xx file. This controller will be abstract and be overridden in WinForms and ASP.NET modules.
3. Declare a custom ViewItem class that is supposed to host a custom user control in the standard XAF View. To do this, implement a custom ViewItem descendant and related types in the platform-agnostic module as shown in the E911.Module\Editors\CustomUserControlViewItem.xx file.
This ViewItem will also be abstract and platform-agnostic as it will not create platform-dependent controls, and will just provide a common customization code for both platforms. For instance, the OnControlCreated method will be overridden to bind the created control to data. To access persistent data from the database used by an XAF application, the ViewItem will implement the IComplexViewItem interface that consists of a single Setup method, receiving the IObjectSpace and XafApplication objects as parameters.
To unify our data binding code for both platforms, the IXpoSessionAwareControl interface and an auxiliary XpoSessionAwareControlInitializer class are introduced.
The interface provides a single UpdateDataSource method that is implemented by custom forms and user controls to bind them to data received by means of XPO.
You can use a similar mechanism and modify these auxiliary types to pass other custom data into your custom forms and controls.
4. Define a base structure of the standard XAF View with a custom ViewItem as shown in the E911.Module\Model.DesignedDiffs.xafml file.
You can simply copy and paste the contents of the Views element into the corresponding file (pre-opened via the text editor) of your platform-agnostic module.
5. Create custom forms and user controls in WinForms and ASP.NET executable projects analogous with what is shown in the example. The easiest way to do this is to copy the contents of the E911.Win\Controls and E911.Web\Controls folders and then include the necessary files into your solution. Take special note that these custom forms and controls implement the IXpoSessionAwareControl interface to automatically receive persistent data and other parameters when they are created.
6. Implement platform-dependent behavior to open and customize custom forms and controls. To do this, copy the following files into your WinForms and ASP.NET module projects:
WinForms:
E911.Module.Win\Controllers\WinShowCustomFormWindowController.xx - contains an WinForms version of the WindowController, which is inherited from the platform-agnostic
E911.Module.Win\Editors\WinCustomUserControlViewItem.xx - contains an WinForms version of the ViewItem, which is inherited from the platform-agnostic one;
E911.Module.Win\WinModuleEx.xx - contains a registration code for WinForms version of the ViewItem;
ASP.NET:
E911.Module.Web\Editors\WebCustomUserControlViewItem.xx - contains an ASP.NET version of the ViewItem, which is inherited from the platform-agnostic one;
E911.Module.Web\WebModuleEx.xx - contains a registration code for ASP.NET version of the ViewItem;
E911.Module.Web\Controllers\WebShowCustomFormWindowController.xx - contains an ASP.NET version of the WindowController, which is inherited from the platform-agnostic one;
These platform-dependent versions of the WindowController and ViewItem are required to implement the creation and display of custom forms and controls using the means specific for each platform. They are also designed to provide the capability to be able to set custom forms and control settings via the Model Editor. For that purpose, custom Application Model extensions are implemented for the Navigation Item and View Item model elements.
7. Set the custom forms and controls settings for each platform.
To do this, copy the contents of the E911.Win\Model.xafml and E911.Web\Model.xafml files into the Model.xafml file in the executable WinForms and ASP.NET projects:
WinForms:
ASP.NET:
IMPORTANT NOTES
1. It is also possible to mix the traditional and XAF development approaches (consult our Support Team if you are not sure how to integrate your standard non-XAF solution into XAF), because an XAF application is a regular .NET application built of reusable blocks like View, ViewItem, Property and List Editors, etc. that eventually create and customize platform-dependent controls exactly the same way you do this without XAF. So, using XAF does not mean something absolutely new and allows you to reuse your existing development skills and practices. Of course, it is possible to create your own reusable blocks if the standard ones do not meet your needs. For instance, the example of a custom View class designed to show a custom form can be found on CodeProject here.
2. This solution contains some generic code (e.g., base WindowController and ViewItem) that is mainly required because our XAF application is for both Windows and the Web. You may avoid this generic code and make a simpler implementation if you are developing for only one platform.
3. You can display custom forms not only when interacting with the navigation control, but from any other place. To do this, intercept the events of a required entity, e.g., an XAF Controller, Action or a View. Refer to the product documentation or consult with our Support Team in case of any difficulties.
4. By default controls layout and user customizations are preserved only for built-in XAF ListEditors, because they have special code for that. If you embed a custom user control into XAF, you need to preserve its settings yourself as well, exactly like you would do when implementing this task in the "old way" in a non-XAF application. Refer to the control's documentation to learn more on how to accomplish this task.
Feel free to contact the respective product team if you experience any difficulties customizing this control.
See also:
How to show custom forms and controls in XAF
How to create controls dynamically
How much of XAF's default UI is customizable.
How to Show a Window via an Action
How to: Display a List of Non-Persistent Objects
How to: Display a Non-Persistent Object's Detail View from the Navigation
ShowNavigationItemController.CustomShowNavigationItem Event
XafApplication.CustomProcessShortcut Event
Question Comments
Added By: kenngo at: 11/6/2012 2:24:10 AM
Hi, I would like the custom from to be tabbedMDI, how to set this in the controller class?
Added By: Dennis (DevExpress Support) at: 2/1/2013 6:12:45 AM@Ngo Ken Hui:
Refer to the Q391718 ticket that describes a possible solution.
i have a problem in CustomUserControlViewItem.cs file
in line "new XpoSessionAwareControlInitializer(Control as IXpoSessionAwareControl, theObjectSpace);"
the Control is converted to null
Please submit a new ticket and attach your problematic project there:
http://www.devexpress.com/Support/Center/Question/Create
We will be glad to help you.
The downloaded solution states it is for " v13.1".
The latest version I am aware of is 12.2?
Added By: Carl Howarth 1 at: 10/11/2013 4:00:36 AMJust in case anyony else hits the issue where the model.CustomControlTypeName is null; there are some additional model settings that are not included in the example code below (but are in the actual download).
Have a look at the XML for the E911.Module.Win/Web Model.xafml. You will notice that there are settings within these files that are not detailed below (it may be obvious to some based on the article but I missed it and it cost me the best part of a day).
Win version:
<Application>
<NavigationItems>
<Items>
<Item Id="Default">
<Items>
<Item Id="CustomForm" CustomFormTypeName="E911.Module.Win.Controls.WinCustomForm" />
</Items>
</Item>
</Items>
</NavigationItems>
<Views>
<DashboardView Id="StandardFormWithCustomUserControl">
<Items>
<CustomUserControlViewItem Id="CustomUserControlViewItem" CustomControlTypeName="E911.Module.Win.Controls.WinCustomUserControl" />
</Items>
</DashboardView>
</Views>
</Application>
Web version:
<Application>
<NavigationItems>
<Items>
<Item Id="Default">
<Items>
<Item Id="CustomForm" CustomFormPath="Controls/WebCustomForm.aspx" />
</Items>
</Item>
</Items>
</NavigationItems>
<Views>
<DashboardView Id="StandardFormWithCustomUserControl">
<Items>
<CustomUserControlViewItem Id="CustomUserControlViewItem" CustomControlPath="Controls/WebCustomUserControl.ascx" />
</Items>
</DashboardView>
</Views>
</Application>
Hope this helps.
Cheers
Carl