Шаблони в XtraLayoutControl 14.1.5

    При створенні користувальницьких інтерфейсів в WinForms додатках розробникам доводиться робити нецікаву повторювану роботу. Страшно уявити скільки людино-годин у всьому світі витрачено на фрагменти користувача інтерфейсу, показані нижче. Заощаджений час можна було б провести з близькими людьми, наприклад, на море…
 
Форма для редагування адреси.
 
 
Login форма.
 
У цій статті ми розглянемо існуючі підходи до вирішення проблеми повторного використання елементів користувальницького інтерфейсу, запропонуємо ще один і обговоримо коли який спосіб краще. Стаття призначена для WinForms розробників, знайомих з нашою лінійкою контролов.
 
 
Найпростіше і універсальне, але не візуальне рішення для повторного використання елементів інтерфейсу користувача — генерація їх з коду. Недолік цього підходу очевидна — неможливо візуально відредагувати результат. Цей недолік може компенсувати використання правильних контролов. Наприклад, наш XAF а так само Dashboard за замовчуванням генерує простий UI з метаданих за допомогою XtraLayoutControl , який згодом користувач може в Рантайм змінити. Користувальницькі зміни зберігаються в XML файл і кожного разу після генерації UI відбувається завантаження з цього файлу. Причому рантайм кастомизация та завантаження / збереження лайаута в XML це вбудований функціонал XtraLayoutControl.
Першим відомим автору візуальним рішенням для створення реюзабельних елементів інтерфейсу була фіча Form Visual Inheritance в Delphi. Дещо пізніше ця фіча з'явилася в Visual Studio, але реалізована вона досі погано і завдає чимало головного болю розробникам компонентів, які хоч трохи складніше кнопки. Не використовуйте Visual Inheritance. Замість цього добре працює розбиття користувача інтерфейсу на окремі UserControls. Наприклад, форму оформлення замовлення можна розбити на HeaderUserControl, AddressUserControl, OkCancelButtonsUserControl, які можна використовувати скільки завгодно на формах у проекті. Це хороший спосіб, але і він не позбавлений недоліків. UserControl з'являється в Toolbox студії тільки в тому проекті, в якому він створений. При модифікації UserControl зміни будуть застосовані скрізь, де його використовували, а це не завжди добре. Так само таке розбиття додає складнощів з лайаутом додатки, але якщо використовувати XtraLayoutControl, а при розбитті великої форми створювати не UserControl а DX версію XtraUserControl, то проблем з лайаутом не буде. У 14.1 версії ми серйозно попрацювали над поліпшенням цього сценарію використання: XtraUserControl вміє транслювати MinimumSize і MaximumSize своїх Чайлд на верхній рівень, і ситуація коли XtraUserControl'y дістається на формі менше місця ніж потрібно не повинна виникати більше.
Ну і, нарешті, розповімо про пропонований підході до реалізації реюзабельного UI. Ми написали свій механізм для роботи з типовими шаблонами на XtraLayoutControl .
 
 
 
Якщо відкрити XtraLayoutControl CustomizationForm в дизайнера студії і виставити прапорець Show Templates, в списку Hidden Items з'являться зумовлені шаблони. Ця експериментальна фіча стане доступною у версії 14.1.5, яку ми випускаємо сьогодні. Поки ми відключили можливість створювати власні шаблони, тому що у нас не готовий дизайн деяких елементів, ми сподіваємося що цей функціонал буде доступний до наступного оновленню.
Шаблон містить інформацію про типи контролов, про збірки які необхідно додати в проект при киданні контрола з шаблону на DesignSurface, фрагмент InitializeComponent що відноситься до обраних контролем. Приклад такого фрагмента показаний нижче
 
 
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();
    }
}


 
При киданні шаблону, отримуємо наступну послідовність:
 - Додати залежні збірки в проект
 - Створити інстанси контрола по типу, зазначеному в шаблоні.
 - Скомпілювати тимчасову збірку, в якій міститься не започатковано метод.
 - Викликати ініціалізацію контрола методом з тимчасових збірки.
 - Додати ініціалізований контрол на DesignSurface.
 
Найбільша проблема в описаній процедурі — це зв'язки між компонентами. Наприклад, користувач зробив кастомізацію зручних йому дефолтних значень для XtraGridControl. Якщо у гріда заданий DataSource, то в Ініціалізується методі буде рядок grid.DataSource = bindingSource1. У шаблоні НЕ БУДЕ bindingSource1 і ця строчка видасть помилку при ініціалізації. На жаль, ми поки не змогли придумати евристику яка правильно вичищала б зовнішні зв'язки в шаблоні. Швидше за все будемо видавати помилку в цьому випадку на етапі створення шаблону.
  
 Отже, починаючи з 14.1.5 в арсеналі наших користувачів з'являється ще один візуальний спосіб повторного використання фрагментів користувача інтерфейсу — шаблони. У яких ситуаціях слід віддавати йому перевагу?
 - Шаблони, доступні з будь-якого проекту, а не тільки в проекті де їх створили, головне щоб. NET зміг знайти всі необхідні шаблоном збірки в момент ініціалізації шаблону.
 - Не завжди зручно створювати окремий UserControl в проекті заради кількох контролов.
 - Застосування змін UserControl у всіх місцях, де він використовується не завжди бажано, шаблони створюють незалежні копії контролов які легко модифікувати прямо на формі. Напевно, тут доречно провести аналогію шаблонів зі сниппета. Мови. NET надають багато способів уникнути дублюючого коду, але незважаючи на це існують сніпети в студії, які іноді просто зручніше.
    
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.