Поделиться через


Общие сведения о настройке и создании форм с помощью средства разработки Service Manager

Форма — это окно, обеспечивающее возможность взаимодействия пользователей с объектами базы данных. С помощью формы пользователи могут просматривать и изменять свойства объектов. Каждая форма связана с определенным классом и отображает сведения только для экземпляров целевого класса. Форма содержит поля. Как правило, каждое поле привязано к определенному свойству целевого класса формы. Форма инцидента, например, связана с объектом инцидента. Следовательно, в форме инцидента отображаются сведения об объектах инцидентов, содержащихся в базе данных.

Форма Service Manager состоит из реализации формы Windows Presentation Foundation (WPF) в сборке Microsoft платформа .NET Framework и определении формы в пакете управления Service Manager. Определение формы определяет класс, который представляет форма, вместе с другими свойствами формы.

Основные понятия о формах

Перед внесением изменений в формы ознакомьтесь с основными концепциями форм.

Использование форм

Когда пакет управления, содержащий определения форм, импортируется в Service Manager, определения форм хранятся в базе данных. Позже, когда пользователь инициирует задачу консоли Service Manager, требующую отображения объекта, Service Manager должен найти форму для отображения запрошенного объекта. Service Manager обращается к базе данных и ищет форму, определенную для этого объекта. Если для объекта не определена форма, Service Manager выполняет поиск формы, определенной для родительского объекта объекта. Service Manager продолжает искать иерархию наследования всего объекта, пока не найдет определенную форму.

Универсальные формы

Если Service Manager не удается найти любую форму для объекта или для каких-либо родительских объектов, Service Manager динамически создает универсальную форму по умолчанию для этого объекта. Универсальная форма — это созданная системой форма, удовлетворяющая запросам большинства простых форм. Универсальная форма является простым и быстрым способом создать форму для объектов, не имеющих определенных форм.

По умолчанию универсальная форма отображает все свойства формы в простом макете, который нельзя изменить. Универсальная форма отображает свойства всех родительских объектов в иерархии наследования формы, и вы не можете изменить это поведение. Возможна лишь ограниченная настройка универсальной формы. Например, можно указать свойства, которые нужно отобразить универсальной форме; однако универсальная форма не может использоваться в качестве основы для настройки. Если позже вы определите пользовательскую форму для этого объекта, пользовательская форма перезаписывает универсальную форму объекта.

Сведения о скрытии свойств в универсальной форме и других способах настройки универсальной формы см. в записи блога Overview of the Forms Infrastructure and the Generic Form (Обзор инфраструктуры форм и универсальной формы).

Сочетания классов в формах

Иногда в форме требуется показать информацию, полученную из нескольких классов. Чтобы сделать это, нужно создать комбинированный класс , а затем привязать поле в форме к этому комбинированному классу. Дополнительные сведения о классах сочетаний см. в разделе "Изменения" в схеме System Center Common.

Функциональные аспекты формы

Функциональность формы можно разделить на следующие категории:

  1. Инициализация

  2. Размер и расположение

  3. Refresh

  4. Отправка изменений

Описание этих категорий дается в представленных ниже разделах.

Инициализация

Во время инициализации расширяемый язык разметки приложения формы (XAML) анализируется, а все элементы управления в форме создаются и загружаются. Событие загруженной формы указывает, когда была загружена форма и все содержащиеся элементы. Операции загрузки данных являются асинхронными. Поэтому при появлении события Loaded целевой экземпляр может еще не быть доступен. Для уведомления об готовности целевого экземпляра для формы используйте событие DataContextChanged . Вместо события PropertyChanged можно использовать событие DataContext для свойства DataContextChanged .

Рекомендуется использовать событие Loaded для пользовательской инициализации, вызванной элементами управления, после чего использовать событие DataContextChanged или PropertyChanged на свойстве DataContext для пользовательской инициализации, вызванной целевым экземпляром.

Размер и расположение

Когда форма отображается во всплывающем окне, его начальный размер определяется на основе свойств формы Width, Height, MinWidth и MinHeight. Если эти свойства не заданы для формы, начальный размер формы вычисляется на основе его содержимого.

Рекомендуется устанавливать эти свойства следующим образом:

  • Установите свойства формы Width и Height , чтобы в явном порядке указать наилучший размер. Также имеется возможность задать для этих свойств значение Auto . Данное значение устанавливает высоту и ширину формы в соответствии с размерами ее содержимого.

  • Установите свойства формы MinWidth и MinHeight , чтобы указать наименьший допустимый размер окна формы. Если пользователь меняет размер окна, после чего оно становится меньше указанных значений, появляются полосы прокрутки, позволяющие переходить к скрытому содержимому формы.

Когда форма размещается внутри узла форм Service Manager, последний используемый размер и расположение сохраняется для последующего отображения этой формы тем же пользователем в том же сеансе выполнения.

Refresh

Целевой экземпляр формы может измениться в результате выполнения команды Refresh . Обработчик данной команды загружает новые данные из базы данных. При поступлении данных значение свойства DataContext формы присваивается новому целевому экземпляру, а событие DataContextChanged вызывается.

Чтобы отличить событие DataContextChanged , созданное при первой загрузке формы от события, созданного при обработке команды Refresh , проверьте свойство OldValue в аргументах события, переданных вместе с событием. Если форма только что была инициализирована, данное свойство имеет значение null.

Отправка изменений

Всплывающее окно узла формы в Service Manager предоставляет кнопки для отправки изменений, внесенных в форме, и закрытия всплывающего окна.

Когда пользователь выбирает кнопку "Применить " для формы, целевой экземпляр формы отправляется в хранилище. Эта операция синхронна; Таким образом, пользователь не может изменить форму до завершения операции отправки. Если при отправке формы произойдет сбой, появится сообщение об ошибке. Форма останется открытой для дальнейших изменений. Пользователям рекомендуется часто применять изменения во избежание конфликтов, возможных в случае, если одновременно редактируется другой экземпляр формы.

Если пользователь нажимает кнопку "ОК ", поведение аналогично применению, за исключением того, что, если операция отправки формы выполнена успешно, форма и его окно узла закрываются.

Если пользователь нажимает кнопку "Отмена", появится диалоговое окно, которое просит пользователя подтвердить операцию. Пользователь может выбрать "Да " и потерять изменения или выбрать "Нет " и вернуться в форму.

Общие рекомендации и рекомендации по формам

Вы можете расширить возможности Service Manager, добавив или изменив формы. В этом разделе описаны некоторые рекомендации по созданию и использованию форм Service Manager с помощью различных средств и определений форм сценариев.

Этот раздел предназначен в основном для партнеров и клиентов, опытных в создании собственных пользовательских форм с помощью Windows Presentation Foundation (WPF) и Microsoft Visual Studio Team System или Microsoft Expression Blend.

Общие правила по созданию формы приведены ниже.

  • Используйте стандартные элементы управления.
  • Следуйте общим правилам проектирования формы.
  • Избегайте кода программной части.
  • Добавляйте обработку исключений.
  • Учитывайте возможность обновления и настройки форм.
  • Называйте все настраиваемые элементы управления.
  • Привязывайте форму к источникам данных.
  • Используйте правила проверки инфраструктуры service Manager, преобразовщики значений и шаблоны ошибок.
  • Используйте команды и события инфраструктуры форм.

Сведения по этим правилам см. в разделах ниже.

Использование стандартных элементов управления

Элементы управления, используемые в форме, могут входить в одну из следующих категорий:

  • Стандартные элементы управления. В их число входят элементы управления библиотеки .NET, такие как поле со списком и список.
  • Пользовательские элементы управления. В их число входят дополнительные элементы управления, созданные автором формы или сторонними разработчиками.

Совет

Используя стандартные элементы управления и отказываясь от создания пользовательских элементов управления, вы повышаете согласованность процессов взаимодействия пользователя с формами. Если все же необходимо создать пользовательский элемент управления, разделите его внешний вид и поведение, а также логическое поведение, используя шаблоны элементов управления для определения вида элемента управления. Желательно иметь отдельный шаблон элемента управления для каждой темы Windows.

Следуйте рекомендациям по проектированию общих форм

При проектировании формы используйте общепринятые правила проектирования, чтобы гарантировать то, что форма удобна для пользователя и она следует общей парадигме взаимодействия с пользователем.

Дополнительные сведения на тему проектирования в среде Windows см. в статье Windows User Experience Interaction Guidelines (Руководство по взаимодействию с пользователем в ОС Windows).

Дополнительно:

  • Распределите информацию по нескольким вкладкам, чтобы упростить чтение формы. Включите наиболее часто используемые сведения на первой вкладке и сведения о меньшей важности на последующих вкладках.
  • Используйте панели макета для размещения элементов управления формой. Это гарантирует правильность поведения формы при изменении размера и локализации.
  • Избегайте установки визуальных свойств отдельного элемента управления — используйте стили. Это позволяет изменить внешний вид всех элементов управления в ряде форм, изменив стиль, и он способствует согласованному внешнему виду в связанных формах.

Избегайте программной части

ТерминомКод программной части обозначается код, соединяемый с созданными в разметке объектами при разметочной компиляции XAML-страницы. Старайтесь максимально ограничить использование кода программной части в форме. Рекомендуется внедрить код для формы в сам элемент управления, так как позже проще изменить этот код. Вместо этого используйте декларативные возможности, поддерживаемые инфраструктурой форм Service Manager, чтобы определить преобразования значений и правила проверки в форме.

В качестве общего руководства следует ограничить использование кода позади ситуаций, в которых невозможно предоставить необходимые функциональные возможности с помощью декларативных возможностей XAML с классами, определенными в WPF и библиотеке инфраструктуры форм. И даже в таком случае попробуйте переместить функциональность, реализованную в виде кода программной части, во вспомогательную библиотеку, а затем добавить ссылку на нее в языке XAML.

Включение обработки исключений

Убедитесь, что код в форме содержит обработку исключений, чтобы форма была загружена как на этапе разработки, так и в консоли Service Manager во время выполнения.

Рассмотрите возможность настройки форм и обновлений

При разработке новой формы следует учитывать будущие настройки и обновления этой формы. Чтобы убедиться, что можно настроить и обновить форму при сохранении настроек, следуйте рекомендациям и советам, приведенным ранее в этом разделе, а также следующим рекомендациям:

  • При разработке формы рассмотрите будущие настройки и обновления. Формы, скорее всего, будут развиваться в будущих версиях, и важно учитывать, как пользователи смогут обновляться до новых версий формы, сохраняя их настройки до исходной формы. Например, вы можете предоставить обновленную форму после того, как пользователи уже вложили много усилий в настройку исходной формы. Пользователи ожидают, что их настройки сохранятся и в обновленной версии.

  • Предоставьте уникальное имя каждому элементу управления формой, чтобы позволить привязывать настройки к элементам управления. Настройки формы хранятся в виде набора действий, нацеленных на определенный элемент управления или их группу. Целевой элемент управления ссылается по имени, поэтому важно сохранять имена элементов управления в разных версиях формы. Если элемент управления не имеет имени, редактор настройки формы создает имя, но созданное имя не сохраняется в разных версиях формы.

  • Убедитесь, что имена элементов управления остаются неизменяемыми в разных версиях формы. Это дает возможность применить настройки определенного элемента управления предыдущей версии к тому же элементу управления в новой версии формы.

  • При обновлении формы по возможности избегайте перемещения элемента управления в другое расположение на той же вкладке. Одна из частых настроек формы заключается в том, что пользователь перемещает элемент управления в удобное для себя место. При изменении расположения элемента управления в новой версии формы возникает риск того, что новое расположение элемента управления может перекрываться с элементом управления, перенесенным пользователем.

  • Если это возможно, избегайте перемещения элементов управления между вкладками при разработке обновления в существующей форме. Элементы управления определяются как по имени, так и по вкладке, на которой они расположены. Перемещение элемента управления из одной вкладки на другую в новой версии формы может нарушить настройки, внесенные пользователем, поскольку эти настройки не смогут идентифицировать целевой элемент управления.

  • Когда обновление формы включает новые элементы управления, рассмотрите возможность добавления новых элементов управления на новую вкладку. Это самый безопасный способ, чтобы избежать вмешательства в любые настройки пользователей на существующие вкладки и элементы управления.

  • Учитывайте способы привязки элементов управления. С элементами управления, работающими в режиме "только для чтения", следует использовать только односторонние привязки.

Имя всех настраиваемых элементов управления

Следите за тем, чтобы имена элементов управления описывали функцию элемента управления или то, к каким данным он привязан.

Привязка формы к источникам данных

Основной целью формы является визуализация одного объекта из базы данных Service Manager. Такой объект называется target instance, что всегда указывается свойством формы DataContext (которое наследуется от класса FrameworkElement ).

Внимание

Не изменяйте свойство DataContext формы. Среда внешнего размещения формы использует это свойство для идентификации целевого экземпляра формы.

В модели данных Service Manager целевой экземпляр представлен как объект BindableDataItem . Данный класс выполняет статистическое вычисление подлежащего объекта SDK и предоставляет его свойства с помощью индексатора, принимающего имя свойства в качестве параметра.

Класс BindableDataItem также реализует интерфейс ICustomTypeDescriptor, что позволяет использовать класс BindableDataItem в качестве источника данных для привязки WPF. Ниже приведен пример привязки свойства целевого экземпляра к свойству Text в элементе управления TextBox .


<TextBox Name="textBoxDescription" Text="{Binding Path=Summary}"/>

Не нужно указывать источник привязки, так как целевые экземпляры задаются как DataContext формы, которая служит источником по умолчанию для всех элементов управления в форме.

Элементы управления формы могут быть привязаны к источникам данных, отличным от целевого экземпляра, а библиотека инфраструктуры форм содержит множество элементов управления, которые выполняют привязку неявно. Например, элемент управления для выбора экземпляра привязан к источнику данных, предоставляющему коллекцию экземпляров на выбор. Кроме того, можно определить дополнительные источники данных декларативно с помощью классов ObjectDataProvider и XmlDataProvider.

Инфраструктура форм считает целевой экземпляр единственным источником данных формы, для которого разрешены операции чтения и записи. Поэтому реализация команды Submit сохранит только изменения, сделанные в целевом экземпляре. С другими источниками данных формы работа происходит в режиме "только для чтения".

Использование правил проверки инфраструктуры служб Service Manager, преобразовщиков значений и шаблонов ошибок

Рекомендуется использовать правила проверки инфраструктуры форм в формах для обозначения недопустимых входных данных. Инфраструктура привязок WPF поддерживает проверку свойств элементов управления, привязанных к источнику данных с помощью как односторонних, так и двусторонних привязок. Привязывающий объект обладает коллекцией ValidationRules , которая может содержать любое количество объектов ValidationRule . При каждой отправке данных из элемента управления в источник данных происходит вызов объектов ValidationRule для проверки значения.

Библиотека инфраструктуры форм содержит множество правил проверки, которые обрабатывают наиболее распространенные случаи. Инфраструктура форм использует правила проверки для определения того, можно ли отправить содержимое формы на сохранение. Например, кнопка "Отправить" формы может быть отключена, если в форме есть элемент управления с ошибкой проверки.

Рекомендуется использовать пользовательский шаблон ошибок, идущий в комплекте с библиотекой инфраструктуры форм. Если элемент управления не проходит проверку, по умолчанию он отмечается красной границей. Подсистема WPF позволяет определить пользовательский индикатор ошибки с помощью свойства Validation.ErrorTemplate , которое можно установить любому элементу управления. Библиотека инфраструктуры форм Service Manager содержит пользовательский шаблон ошибки, который отображает значок ошибки вместо красной границы WPF. Кроме того, при наведении указателя мыши на значок ошибки будет отображена подсказка с текстом сообщения об ошибке. Сообщение об ошибке должно содержать причину, по которой данные из элемента управления не прошли проверку.

Метод ссылки на шаблон ошибки на языке XAML показан в следующем примере:


<TextBox Text="{Binding SomeProperty}"
         scwpf:Validation.ValueRequired="True"
         Validation.ErrorTemplate="{DynamicResource {ComponentResourceKey {x:Type scwpf:Validation}, InvalidDataErrorTemplate}}"/>

Если встроенные правила проверки не предоставляют необходимую логику проверки, рекомендуется создать пользовательские правила проверки для представления этой логики. Это позволит стандартной и пользовательской логике проверки сосуществовать в общем механизме управления проверкой.

Если механизм правил проверки не подходит для определенного сценария, следует вместо этого обработать FormEvents.PreviewSubmitEvent и запустить проверку.

В следующем примере кода дается образец процедуры выполнения пользовательской проверки:


void MyForm_Loaded(object sender, RoutedEventArgs e)
{
    // hook to handle form events
    this.AddHandler(
        FormEvents.PreviewSubmitEvent,
        new EventHandler<PreviewFormCommandEventArgs>(this.OnPreviewSubmit));
}
private void OnPreviewSubmit(object sender, PreviewFormCommandEventArgs e)
{
    string errorMessage;
    bool result = this.DoVerify(out errorMessage);
    if (!result)
    {
        // cancel Submit operation
        e.Cancel = true;
        // display error message
        MessageBox.Show(errorMessage);
    }
}
internal bool DoVerify(out string errorMessage)
{
    // Do custom verification and return true to indicate that
    // validation check has passed; otherwise return false and
    // populate errorMessage argument
}

Использование команд и событий инфраструктуры форм

Инфраструктура формы предоставляет множество команд, которые могут выполняться в форме. В число этих команд входят следующие:

  • FormsCommand.Submit, сохраняющая целевой экземпляр формы.

  • FormsCommand.SubmitAndClose, сохраняющая целевой экземпляр формы и закрывающая форму.

  • FormsCommand.Refresh, повторяющая запрос к целевому экземпляру формы.

  • FormCommands.Cancel, который удаляет все изменения и закрывает форму.

Каждая из этих команд отмечается событиями, происходящими до и после запуска команды.

Перед запуском команды происходят следующие события:

  • Событие FormEvents.PreviewSubmit происходит перед выполнением команды FormCommand.Submit , а событие FormEvents.Submitted — после выполнения команды FormCommand.Submit .

  • Событие FormEvents.PreviewRefresh происходит перед выполнением команды FormCommands.Refresh , а команда FormCommand.Refreshed — после выполнения команды FormCommand.Submit .

  • Событие FormEvents.PreviewCancel происходит перед выполнением команды FormCommands.Cancel , а событие FormCommand.Canceled — после выполнения команды FormCommand.Cancel .

С предварительными событиями передается объект PreviewFormCommandEventArgs . Данный объект содержит изменяемое свойство Cancel , с помощью которого можно предотвратить запуск соответствующей команды, если установить свойству значение true.

Следующие за выполнением события содержат объект FormCommandExecutedEventArgs . Данный объект содержит свойство Result , которое сообщает, была ли команда выполнена успешно, была ли она отменена или вызвала ошибку. В случае ошибки свойство Error объекта FormCommandExecutedEventArgs ссылается на исключение, предоставляющее сведения об ошибке.

Можно включить, отключить и запустить команды формы программными средствами и декларативно.

Чтобы активировать команды форм в программном режиме, установите привязку CommandBinding между формой и соответствующей командой.

В примере ниже устанавливается привязка между формой и командой Refresh , а также определяются два обработчика для этой команды. Первый обработчик возвращает сведения о возможности запуска команды Refresh , а второй обработчик содержит фактическую реализацию команды Refresh .


    public class MyForm : UserControl
    {
        public MyForm()
        {
            // do standard initialization
            // establish CommandBinding for Refresh command
            this.CommandBindings.Add(
                new CommandBinding(FormCommands.Refresh, this.ExecuteRefresh, this.CanExecuteRefresh));
        }
        private void CanExecuteRefresh(
              object sender,
              CanExecuteRoutedEventArgs e)
        {
            // put your logic that determines whether Refresh
// can be executed here
            bool canExecute = true;
            BindableDataItem dataItem = this.DataContext as BindableDataItem;
            if (dataItem)
            {
                canExecute = dataItem["Status"] != "New";
            }
            e.CanExecute = canExecute;
        }
        private void ExecuteRefresh(
            object sender,
            ExecutedRoutedEventArgs e)
        {
            // here is placeholder for the code that has do be
// executed upon running Refresh command
        }
    }

Обработчики для команд формы могут быть также определены декларативно. Это можно сделать при помощи объекта Rule , использующего интерфейс RoutedCommandTrigger. В следующем примере кода показана методика декларативного определения обработчиков:


    <scwpf:BusinessLogic.Rules>
        <scwpf:RuleCollection>
            <scwpf:Rule>
                <scwpf:Rule.Triggers>
                    <scwpf:RoutedCommandTrigger
RoutedCommand="{x:Static scwpf:FormCommands.Refresh}"/>
                </scwpf:Rule.Triggers>
                <scwpf:Rule.Conditions>
                    <scwpf:PropertyMatchCondition
                        Binding="{Binding Status}"
                        Value="New"
                        Operation="NotEquals" />
                </scwpf:Rule.Conditions>
                <!-- Use RuleAction objects to define the logic that executed
                upon running Refresh command; this can be left empty -->
            </scwpf:Rule>
        </scwpf:RuleCollection>
    </scwpf:BusinessLogic.Rules>

Следующие шаги