Пример расширения страницы свойств Windows-клиента

В данном примере создаётся расширение Windows-клиента, добавляющее собственную вкладку на форму свойств карточки Задание. Новая вкладка должна предоставлять возможность получать основную информацию о задании без открытия карточки.

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

Архив с исходным кодом решения доступен по ссылке.

  1. Создаем (в Visual Studio) новый проект типа Class Library.

    Первоначально реализуем компонент страницы свойств карточки.

  2. Добавляем в проект компонент типа User Control (WPF), в котором будет реализован графический интерфейс страницы. Базовым классом страницы (для WPF) является тип DocsVision.Platform.Wpf.NavPropertyPageControl (сборка DocsVision.Platform.Wpf.dll) — переопределяем UserControl на него. Класс должен быть помечен атрибутами COM-видимости.

    [ComVisible(true)]
    [Guid("95821EC8-34C2-4914-A4C2-125D1BF6FFDE")]
    [ClassInterface(ClassInterfaceType.None)]
    public partial class PropertyPageControl : NavPropertyPageControl

    Если для реализации пользовательского интерфейса используются компоненты WinForms (или DevExpress), а не WPF, то нужно наследовать свой класс от типа DocsVision.Platform.WinForms, реализованного в сборке DocsVision.Platform.WinForms.dll.
    Название типов в WPF и WinForms-версиях сборок совпадают.

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

    Чтобы получить информацию о карточке, можно использовать данные, переданные с параметрами активации страницы, для чего достаточно получить элемент с названием CardData из массива параметров this.ActivateParams. Также можно самостоятельно получить данные из пользовательской сессии — this.Session. В данном примере, реализован иной способ, в котором запрашивается объектная модель карточки. Это позволяет, в случае необходимости, задействовать сервисы объектной модели для выполнения бизнес-функций.

    Пример получения контекста объектов приведён в разделе Инициализация контекста объектов, а также в исходных кодах данного проекта.

    В данном проекте на страницу свойств задания выводится лишь часть информации о нем, но в собственном решении можно вывести больше информации, а также реализовать дополнительные методы. Можно, например, делегировать или завершать по кнопке, или открывать вложенные файлы. В качестве примера, отображаем название, приоритет, состояние, автора, дату исполнения и содержимое задания:

    private void PostInit()
    {
     TaskName.Content = BaseObject.MainInfo.Name;
    
     switch (BaseObject.MainInfo.Priority)
     {
      case DocsVision.BackOffice.ObjectModel.TaskPriority.High:
       TaskPriority.Content = "Высокий";
       break;
      case DocsVision.BackOffice.ObjectModel.TaskPriority.Low:
       TaskPriority.Content = "Низкий";
       break;
      default:
       TaskPriority.Content = "Нормальный";
       break;
     }
    
     TaskState.Content = BaseObject.SystemInfo.State.LocalizedName;
     TaskAuthor.Content = BaseObject.MainInfo.Author.DisplayName;
     TaskEndDateActual.Content = BaseObject.MainInfo.EndDate.HasValue ? BaseObject.MainInfo.EndDate.Value.ToString("dd.MM.yyyy") : string.Empty;
     TaskContent.Content = BaseObject.MainInfo.Content;
    }

    Собственно графический интерфейс реализуется обычным образом, но т.к. базовый класс компонента был изменён, аналогичное изменение должно быть сделано в XAML:

    <dv:NavPropertyPageControl
     ...
     xmlns:dv="http://schemas.docsvision.com/winfx/2007/xaml/presentation"
     ...
  4. Добавляем в проект компонент типа User Control (WPF) для реализации основного класса расширения. Базовый класс необходимо изменить на тип DocsVision.Platform.Wpf.NavExtension, а также пометить его атрибутами доступности для COM:

    [ComVisible(true)]
    [Guid("4A8331EC-9E4E-4E26-91A4-8E621D39870D")]
    [ClassInterface(ClassInterfaceType.None)]
    public partial class Extension : NavExtension

    При реализации на компонентах WinForms нужно наследовать (см. комментарий выше) от класса DocsVision.Platform.WinForms.NavExtension, реализованного в сборке DocsVision.Platform.WinForms.dll)

  5. Реализуем в классе Extension функциональность расширения, добавляющего страницы в свойства карточки.

    Прежде всего необходимо определить функциональное назначение расширения — его тип. Расширение может быть нескольких типов (см. раздел Расширение Windows-клиента), причем возможна реализация нескольких типов в одном компоненте расширения.

    Как было сказано в описании данного расширения, оно добавляет страницу в свойства карточки, т.е. является типом NavExtensionTypes.PropertyPages.

    Чтобы указать тип расширения, нужно переопределить свойство SupportedTypes:
    protected override NavExtensionTypes SupportedTypes
    {
     get
     {
      return NavExtensionTypes.PropertyPages; (1)
     }
    }
    1 Если расширение реализует несколько типов, они перечисляются через |.
  6. Реализуем специфическую функциональность типа расширения. Каждый тип расширения добавляет в базовый класс собственную функциональность (методы или свойства), список элементов которой приведён в разделе Расширение Windows-клиента. Для расширения типа NavExtensionTypes.PropertyPages нужно переопределить метод CreatePropertyPages, чтобы он возвращал описание страниц, добавляемых расширением:

    protected override IEnumerable<NavPropertyPage> CreatePropertyPages()
    {
     return new NavPropertyPage[] {  (1)
      new NavPropertyPage() {
       PageType = NavPropertyPageTypes.All,
       Name = "Информация о задании",
       Clsid = typeof(PropertyPageControl).GUID
      }
     };
    }
    1 Для каждой страницы определяется тип объекта, в свойствах которого она будет отображаться, заголовок страницы, а также идентификатор класса.

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

    В данном примере это ограничение обходится за счет формирования исключения при инициализации страницы OnPageInitialized в её компоненте (класс PropertyPageControl). Если в процессе исключения происходит ошибка, то страница в свойствах не отображается.

  7. Собираем проект и распространяем сборку на клиентские компьютеры. Сборка должна быть зарегистрирована как COM-компонент утилитой regasm.

  8. Реализуем библиотеку карточек с карточкой, компонентом который является сборка, содержащая разработанный ранее код (сборка может быть подписанной и размещена в GAC, либо в каталоге приложения).

    Добавление кода сборки
    Рисунок 1. Добавление кода сборки

    Условия разработки библиотеки карточек для расширения см. в разделе Расширение Windows-клиента.

  9. Загружаем схему карточки в базу данных целевого севера Docsvision. После перезапуска Docsvision в свойствах карточки Задание появится реализованная вкладка:

    Вкладка "Информация о задании"
    Рисунок 2. Вкладка "Информация о задании"