📜 ⬆️ ⬇️

Templates in XtraLayoutControl 14.1.5

When creating user interfaces in WinForms applications, developers have to do uninteresting repetitive work. It is terrible to imagine how many man hours all over the world are spent on the user interface fragments shown below. Saved time could be spent with loved ones, for example, at sea ...

The form for editing the address.


Login form.

In this article we will look at the existing approaches to solving the problem of reusing user interface elements, suggest another one and discuss which way is better. This article is intended for WinForms developers familiar with our line of controls.

')
The simplest and universal, but not visual, solution for reusing user interface elements is to generate them from code. The disadvantage of this approach is obvious - it is impossible to visually edit the result. This deficiency can compensate for the use of correct controls. For example, our XAF as well as the Dashboard by default generates a simple UI from metadata using XtraLayoutControl , which the user can later change in runtime. User changes are saved in the XML file and each time after the generation of the UI is loaded from this file. Moreover, customization and loading / saving layouts to XML is the built-in XtraLayoutControl functionality.
The first known author of the visual solution for creating reusable interface elements was the Form Visual Inheritance feature in Delphi. Somewhat later, this feature appeared in Visual Studio, but it is still poorly implemented and gives a lot of headaches to developers of components that are a little more complicated than buttons. Do not use Visual Inheritance. Instead, splitting the user interface into separate UserControls works well. For example, the order form can be divided into HeaderUserControl, AddressUserControl, OkCancelButtonsUserControl, which can be used as many as you like on the forms in the project. This is a good way, but it is not without flaws. UserControl appears in Toolbox studio only in the project in which it was created. When modifying UserControl, changes will be applied wherever it is used, and this is not always good. Also, such a partition adds complexity to the application layout, but if you use XtraLayoutControl, and when splitting a large form, you will not create a UserControl but a DX version of XtraUserControl, then there will be no problems with the layout. In version 14.1, we seriously worked on improving this usage scenario: XtraUserControl knows how to translate MinimumSize and MaximumSize of its children to the upper level, and the situation when XtraUserControl'y gets less space on the form than necessary should not arise anymore.
And finally, we will talk about the proposed approach to the implementation of the reusable UI. We wrote our mechanism for working with sample templates on XtraLayoutControl .



If you open XtraLayoutControl CustomizationForm in the studio designer and select the Show Templates checkbox, predefined templates appear in the Hidden Items list. This experimental feature will be available in version 14.1.5, which we are releasing today. While we have disabled the ability to create our own templates, because we are not ready for the design of some elements, we hope that this functionality will be available for the next update.
The template contains information about types of controls, about assemblies that need to be added to the project when throwing controls from a template to DesignSurface, a fragment of the InitializeComponent related to the selected controls. An example of such a fragment is shown below.

public class textEdit1 : DevExpress.XtraEditors.TextEdit { public void InitializeInstance(DevExpress.XtraEditors.TextEdit target) { ((System.ComponentModel.ISupportInitialize)(target.Properties)).BeginInit(); target.Location = new System.Drawing.Point(0, 0); target.Name = "textEdit1"; target.Size = new System.Drawing.Size(100, 20); target.TabIndex = 4; ((System.ComponentModel.ISupportInitialize)(target.Properties)).EndInit(); } } 


When throwing a pattern, we get the following sequence:
- add dependent assemblies to the project
- create an instance control of the type specified in the template.
- compile a temporary assembly, which contains the initializing method.
- call the initialization of the control method from the assembly time.
- add initialized control to DesignSurface.

The biggest problem in the procedure described is the connections between the components. For example, the user has made customization of default values ​​for XtraGridControl convenient for him. If the DataSource is set for the grid, then the initializing method will have the line grid.DataSource = bindingSource1. The template will not be bindingSource1 and this line will generate an error during initialization. Unfortunately, we have not yet been able to come up with a heuristics that would properly clean up the external relations in the template. Most likely we will give an error in this case at the stage of creating a template.

So, starting from 14.1.5, in the arsenal of our users, there appears another visual way to reuse user interface fragments — templates. In what situations should be given preference?
- Templates are available from any project, and not only in the project where they were created, the main thing is that .NET can find all the necessary assembly templates at the time of initialization of the template.
- It is not always convenient to create a separate UserControl in a project for the sake of several controls.
- Applying UserControl changes in all places where it is used is not always desirable, templates create independent copies of controls that can be easily modified directly on the form. Probably, it is appropriate to draw an analogy of templates with snippet. .NET languages ​​provide many ways to avoid duplicate code, but despite this there are snippets in the studio, which are sometimes just more convenient.

Source: https://habr.com/ru/post/230111/


All Articles