Работа с XML-файлами пакета управления Service Manager

Важно!

Поддержка этой версии Service Manager завершена. Мы рекомендуем выполнить обновление до Service Manager 2022.

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

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

Изменения в общей схеме System Center

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

Свойства и ограничения свойств

Общая схема расширяет классы за счет ряда новых типов свойств. К этим типам свойств относятся двоичные, перечислитель и типы с автоматическим приращением.

Кроме того, можно определить ограничения для определенных значений свойств. Например, можно определить ограничение в виде регулярного выражения для значения свойства строкового типа. В следующем примере свойство BuildingName имеет ограничение регулярного выражения, которое определяется таким образом, что допустимым считается только значение, содержащее слово Building , за которым следует пробел и число.


<ClassType ID="Lobby" Accessibility="Public" Base="System!System.Entity">  
   <Property ID="Id" Type="int" Key="true" />  
   <Property ID="BuildingName" Type="string" RegEx="Building [0-9]+" />  
</ClassType>  

изображения;

Образы не хранятся в пакете управления. В связи с этим раздел <PresentationTypes> пакета управления больше не содержит тегов <Images>, <Image> и <ImageData>. Вместо этого используется ресурс изображения.

<Resources>  
   <Image ID="TestLibrary.Resources.Image1" Accessibility="Public" FileName="image.png"/>  
</Resources>  

Перечисления

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

Каждое перечисление имеет обязательный уникальный атрибут ID и необязательный атрибут Parent .

В следующем примере перечисление XBoxState определено с помощью трех возможных значений: Running, Stopped и Error.


<EnumerationTypes>  
   <EnumerationValue ID="XBoxState" Accessibility="Public"/>  
   <EnumerationValue ID="XBoxState.Running" Parent="XBoxState" Accessibility="Public"/>  
  <EnumerationValue ID="XBoxState.Stopped" Parent="XBoxState" Accessibility="Public"/>  
   <EnumerationValue ID="XBoxState.Error" Parent="XBoxState" Accessibility="Public" />  
   <EnumerationValue ID="XBoxState.Error.RROD" Parent="XBoxState.Error" Accessibility="Public" />  
</EnumerationTypes>  

В следующем примере класс Xbox определяет свойство enum типа XBoxState.


<ClassType ID="XBox" Accessibility="Public" Base="System!System.ConfigItem" Hosted="true">  
   <Property ID="Id" Type="int" Key="true" />  
   <Property ID="Name" Type="string" />  
   <Property ID="State" Type="enum" EnumType="XBoxState" />  
</ClassType>  

Отношения

В общей схеме расширена функциональность определений отношений. Тип RelationshipType теперь содержит дочерние элементы Source и Target со свойствами ID , которые могут использоваться в качестве отображаемых имен. Кроме того, можно определить минимальную и максимальную кратность как для источника, так и для целевого объекта; например, связи "1 к 1" или "0 ко многим".

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

Важно!

Любое значение свойства MaxCardinality , которое больше 1, обрабатывается как бесконечное.

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

В следующем примере определяется связь размещения HasXboxes между типом Lobby и типом Xbox . В этом определении отношения каждый тип Lobby может иметь несколько типов Xbox .


<RelationshipType ID="HasXBboxes" Accessibility="Public" Base="System!System.Hosting">  
   <Source ID="Source" Type="Lobby" />  
   <Target ID="Target" Type="Xbox" MinCardinality="0" MaxCardinality="9999" />  
</RelationshipType>  

Комбинированные классы

Комбинированные классы представляют агрегаты нескольких связанных типов в пакете управления, подобно представлениям, определенным в базе данных Microsoft SQL Server, которые могут возвращать данные из нескольких таблиц. Комбинированные классы сохраняют и извлекают все агрегированные данные за одну операцию с базой данных и могут упростить определение пользовательских интерфейсов для пакета управления.

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


<TypeProjections>  
   <TypeProjection ID="System.WorkItem.Incident.View.ProjectionType"  
      Accessibility="Public" Type="Incident!System.WorkItem.Incident">  
      <Component Alias="AffectedUser"  
Path="$Target/Path[Relationship='SMCore!System.WorkItemCreatedForUser']$"/>  
      <Component Alias="AssignedUser" Path="$Target/Path[Relationship='SMCore!System.WorkItemAssignedToUser']$"/>  
   </TypeProjection>  
   <TypeProjection ID="System.WorkItem.Incident.View.DCMProjectionType" Accessibility="Public" Type="Incident!System.WorkItem.Incident.DCMIncident">  
      <Component Alias="AffectedUser" Path="$Target/Path[Relationship='SMCore!System.WorkItemCreatedForUser']$"/>  
      <Component Alias="AssignedUser" Path="$Target/Path[Relationship='SMCore!System.WorkItemAssignedToUser']$"/>  
      <!--Baseline and Configuration Item Information-->  
      <Component Alias="AffectedComputer" Path="$Target/Path[Relationship='Incident!System.WorkItem.Incident.DCMIncident.Refers.NonComplianceComputer']$"/>  
   </TypeProjection>  
   <TypeProjection ID="System.WorkItem.ChangeRequestViewProjection" Accessibility="Public" Type="System.WorkItem.ChangeRequest">  
      <Component Alias="AssignedTo" Path="$Target/Path[Relationship='SMCore!System.WorkItemAssignedToUser']$"/>  
   </TypeProjection>  
   <TypeProjection ID="System.WorkItem.ChangeRequestProjection" Accessibility="Public" Type="System.WorkItem.ChangeRequest">  
      <Component Alias="Activity" Path="$Target/Path[Relationship='SMActivity!System.WorkItemContainsActivity']$">  
         <Component Alias="ActivityAssignedTo" Path="$Target/Path[Relationship='SMCore!System.WorkItemAssignedToUser']$"/>  
         <Component Alias="ActivityRelatedWorkItem" Path="$Target/Path[Relationship='SMCore!System.WorkItemRelatesToWorkItem']$">  
            <Component Alias="ActivityRelatedWorkItemAssignedTo" Path="$Target/Path[Relationship='SMCore!System.WorkItemAssignedToUser']$"/>  
         </Component>  
         <Component Alias="ActivityRelatedConfigItem" Path="$Target/Path[Relationship='SMCore!System.WorkItemRelatesToConfigItem']$"/>  
         <Component Alias="ActivityAboutConfigItem" Path="$Target/Path[Relationship='System!System.WorkItemAboutConfigItem']$"/>  
         <Component Alias="ActivityFileAttachment" Path="$Target/Path[Relationship='System!System.WorkItemHasFileAttachment']$">  
            <Component Alias="ActivityFileAttachmentAddedBy" Path="$Target/Path[Relationship='System!System.FileAttachmentAddedByUser']$"/>  
         </Component>  
         <Component Alias="Reviewer" Path="$Target/Path[Relationship='SMActivity!System.ReviewActivityHasReviewer']$">  
            <Component Alias="User" Path="$Target/Path[Relationship='SMActivity!System.ReviewerIsUser']$"/>  
            <Component Alias="VotedBy" Path="$Target/Path[Relationship='SMActivity!System.ReviewerVotedByUser']$"/>  
         </Component>  
      </Component>  
      <Component Alias="CreatedBy" Path="$Target/Path[Relationship='SMCore!System.WorkItemCreatedByUser']$"/>  
      <Component Alias="AssignedTo" Path="$Target/Path[Relationship='SMCore!System.WorkItemAssignedToUser']$"/>  
      <Component Alias="CreatedFor" Path="$Target/Path[Relationship='SMCore!System.WorkItemCreatedForUser']$"/>  
      <Component Alias="RelatedWorkItem" Path="$Target/Path[Relationship='SMCore!System.WorkItemRelatesToWorkItem']$">  
         <Component Alias="RelatedWorkItemAssignedTo" Path="$Target/Path[Relationship='SMCore!System.WorkItemAssignedToUser']$"/>  
      </Component>  
      <Component Alias="RelatedConfigItem" Path="$Target/Path[Relationship='SMCore!System.WorkItemRelatesToConfigItem']$"/>  
      <Component Alias="AboutConfigItem" Path="$Target/Path[Relationship='System!System.WorkItemAboutConfigItem']$"/>  
      <Component Alias="FileAttachment" Path="$Target/Path[Relationship='System!System.WorkItemHasFileAttachment']$">  
         <Component Alias="FileAttachmentAddedBy" Path="$Target/Path[Relationship='System!System.FileAttachmentAddedByUser']$"/>  
      </Component>  
   </TypeProjection>  
   <TypeProjection ID="System.FileAttachmentProjection" Accessibility="Public" Type="System!System.FileAttachment">  
      <Component Alias="FileAttachmentAddedBy" Path="$Target/Path[Relationship='System!System.FileAttachmentAddedByUser']$"/>  
   </TypeProjection>  
</TypeProjections>  

Задачи консоли

В общей схеме расширены задачи консоли. Раньше задачи консоли были простыми указателями на каталог приложения и имя исполняемого файла. Теперь задачи консоли реализованы в виде кода обработчика в сборке Microsoft .NET Framework. Код обработчика ссылается на сборку, которая содержит код, имя обработчика и список именованных значений, которые могут быть переданы в обработчик в качестве аргументов.

В следующем примере обработчик Some.Handler.Name определен в сборке MyLibrary.Resources.Assembly . Также определен список параметров обработчика и их значений.

<ConsoleTask ID="MyLibrary.ConsoleTasks.T1"  
    Accessibility="Public"  
     Target="System!System.Entity"  
     Enabled="true"  
     RequireOutput="true">  
   <Assembly>MyLibrary.Resources.Assembly1</Assembly>  
   <Handler>Some.Handler.Name</Handler>  
   <Parameters>  
      <Argument Name="Application">cmd.exe</Argument>  
      <Argument Name="WorkingDirectory">%TEMP%</Argument>  
      <Argument>test1</Argument>  
      <Argument>test2</Argument>  
   </Parameters>  
</ConsoleTask>  

Ресурсы

Двоичные данные не хранятся непосредственно в пакете управления. Вместо этого в пакете управления хранятся метаданные о двоичном ресурсе, а сами двоичные данные хранятся во внешнем файле ресурсов. Метаданные включают уникальный идентификатор, имя файла, дату создания, дату изменения и сведения о доступности.

Двоичные данные могут включать универсальные ресурсы, изображения, сборки, определения отчетов и формы. В следующем примере показан универсальный XML-ресурс, ресурс сборки и ресурс отчета.


<Resources>  
   <Resource ID="TestLibrary.Resources.Test1" Accessibility="Public" FileName="res1.xml"/>  
   <Resource ID="TestLibrary.Resources.Test2" Accessibility="Public" FileName="res2.xml"/>  
   <Assembly ID="TestLibrary.Resources.Assembly1" Accessibility="Public" QualifiedName="Baz, Version=1.0.0.0" FileName="baz.dll"/>  
   <Assembly ID="TestLibrary.Resources.Assembly2" Accessibility="Public" QualifiedName="Yoyo, Version=1.0.0.0" FileName="yoyo.dll">  
      <Dependency ID="TestLibrary.Resources.Assembly1"/>  
   </Assembly>  
   <ReportResource ID="TestLibrary.Resources.Report1" Accessibility="Public" MIMEType="text/xml" FileName="res1.xml"/>  
   <Image ID="TestLibrary.Resources.Image1" Accessibility="Public" FileName="image.png"/>  
</Resources>  

Формы

Формы определяются в пакете управления. Формы можно использовать для просмотра и изменения одного экземпляра типа или комбинированного класса.

Формы основаны на Windows Presentation Framework (WPF) и определяются в сборках. Сборка и класс, которые содержат реализации формы для пакета управления, включаются в раздел ресурсов пакета управления. Как и в случае с любым двоичным ресурсом в пакете управления, использующим новую общую схему, сам пакет управления не содержит двоичных данных для формы. В пакете управления указывается только манифест ресурса.

В пакете управления можно указать собственные данные конфигурации для формы. В следующем примере раздел Configuration содержит свойство ShowXboxes . Эти сведения о конфигурации не оцениваются процессом проверки пакета управления; он интерпретируется только реализацией формы.


    <Forms>  
   <Form ID="LobbyForm" Target="Projection" Assembly="FormAssembly" TypeName="MyFormClass">  
   <Configuration>  
      <ShowXboxes>yes</ShowXboxes>  
   </Configuration>  
   </Form>  
</Forms>  

Создание файла пакета управления для управления проекторами

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

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

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

  • Manifest

  • TypeDefinitions (определения типов) для создания перечислений классов и отношений между классами

  • Формы

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

  • Категории

  • Уровень представления

  • Расширения классов

Раздел манифеста

Первый раздел пакета управления содержит манифест. Манифест идентифицирует пакет управления и объявляет все ссылки на другие пакеты управления.

В примере ниже показан раздел Manifest из пакета управления, созданного для слежения за корпоративными проекторами.


<Manifest>  
  <Identity>  
    <ID>ServiceManager.Projector_Authoring</ID>  
    <Version>7.0.3707.0</Version>  
  </Identity>  
  <Name>Projector Library</Name>  
  <References>  
    <Reference Alias="System">  
      <ID>System.Library</ID>  
      <Version>7.0.3707.0</Version>  
      <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>  
    </Reference>  
    <Reference Alias="SMConsole">  
      <ID>Microsoft.EnterpriseManagement.ServiceManager.UI.Console</ID>  
      <Version>7.0.3707.0</Version>  
      <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>  
    </Reference>  
    <Reference Alias="Authoring">  
      <ID>Microsoft.EnterpriseManagement.ServiceManager.UI.Authoring</ID>  
      <Version>7.0.3707.0</Version>  
      <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>  
    </Reference>  
    <Reference Alias="SMConfig">  
      <ID>ServiceManager.ConfigurationManagement.Library</ID>  
      <Version>7.0.3707.0</Version>  
      <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>  
    </Reference>  
  </References>  
</Manifest>  

Важно!

В разделе Ссылки не используйте неальфакнумерные значения, такие как ".", в псевдониме для ссылки.

Создание классов в разделе TypeDefinitions

В этом разделе пакета управления содержатся определения типов. Раздел TypeDefinitions содержит определения классов, перечислений и отношений, используемых пакетом управления.

В следующем примере представлен класс, содержащий сведения о проекторах:


<TypeDefinitions>  
    <EntityTypes>  
      <ClassTypes>  
        <ClassType ID="System.ConfigItem.Projector" Base="System!System.ConfigItem" Hosted="false" Accessibility="Public" Abstract="false">  
          <Property ID="SerialNumber" Type="int" Key="true" />  
          <Property ID="Make" Type="string" />  
          <Property ID="Model" Type="string"  />  
          <Property ID="Location" Type="string" />  
          <Property ID="Condition" Type="enum" EnumType="ProjectorCondition"  />  
        </ClassType>  
      </ClassTypes>  
      <RelationshipTypes>  
      </RelationshipTypes>  
      <EnumerationTypes>  
        <EnumerationValue ID="ProjectorCondition" Accessibility="Public"/>  
        <EnumerationValue ID="ProjectorCondition.Working" Parent="ProjectorCondition" Accessibility="Public"/>  
        <EnumerationValue ID="ProjectorCondition.BeingRepaired" Parent="ProjectorCondition" Accessibility="Public"/>  
        <EnumerationValue ID="ProjectorCondition.New" Parent="ProjectorCondition" Accessibility="Public"/>  
        <EnumerationValue ID="ProjectorCondition.Broken" Parent="ProjectorCondition" Accessibility="Public"/>  
        <EnumerationValue ID="ProjectorViewTasksEnumeration" Accessibility="Public"/>  
      </EnumerationTypes>  
    </EntityTypes>  
  </TypeDefinitions>  

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

Раздел ClassTypes

Элемент ClassType определяет класс проектора:

<ClassType ID="System.ConfigItem.Projector" Base="System!System.ConfigItem" Hosted="false" Accessibility="Public" Abstract="false">

Атрибут ID является уникальным идентификатором данного класса. Для него задано значение:

ID="System.ConfigItem.Projector"

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

Base="System!System.ConfigItem"

Нотация System! указывает, что этот класс System.ConfigItem находится в пакете управления, на который ссылается псевдоним System.

Атрибут Hosted определяет, размещен ли данный класс в другом классе. Если это так, экземпляр данного класса может существовать только при условии, что существует родительский экземпляр. В этом примере проекторы не размещаются; поэтому для атрибута Hosted задано значение false:

Hosted="false"

Если атрибут Hosted имеет значение true , это означает, что класс размещен в другом классе. Отношение размещения должно быть объявлено в разделе RelationshipTypes .

Атрибут Accessibility определяет, могут ли другие классы использовать данный класс в качестве базового. Чтобы позволить другим создавать специализированные версии класса, установите этому атрибуту значение public, например, следующим образом:

Accessibility="Public"

Установка атрибуту Accessibility значения Internal предотвращает создание классов на основе данного класса.

Атрибут Abstract определяет, можно ли создавать экземпляры данного класса, или же класс используется лишь в качестве родительского класса для других классов. В данном примере этот атрибут имеет значение false. Установка для атрибута значения true приводит к невозможности непосредственного создания экземпляров этого класса, позволяя использовать его лишь в качестве родительского класса.

В следующем разделе определения класса находятся свойства класса. XML-код, определяющий свойства класса в данном примере, приведен ниже.


<Property ID="SerialNumber" Type="int" Key="true" />  
<Property ID="Make" Type="string" />  
<Property ID="Model" Type="string"  />  
<Property ID="Location" Type="string" />  
<Property ID="Condition" Type="enum" EnumType="ProjectorCondition"  />  

Каждый элемент Property имеет следующие атрибуты:

  • Атрибут ID представляет собой уникальный идентификатор свойства.

  • Атрибут Type , обозначает тип данных свойства.

  • Атрибут Key . Установка данному атрибуту значения true обозначает, что это свойство будет использоваться в качестве уникального идентификатора данного класса.

Создание типов перечисления

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

Перечисления создаются в разделе пакета решения EnumertionTypes . Определение перечисления содержит корневое перечисление, за которым следуют фактические значения перечисления.

Каждый EnumerationValue принимает несколько атрибутов:

В данном примере перечисление определяется для отслеживания технического состояния проекторов. Ниже представлено определение данного перечисления.

  • ID является идентификатором перечисления или значения перечисления.

  • Accessibility указывает, может ли данный перечислитель содержать другие перечислители.

  • ParentName — это атрибут, указывающий значение ID для родительского элемента значения перечислителя.


<EnumerationTypes>  
   <EnumerationValue ID="ProjectorCondition" Accessibility="Public"/>  
   <EnumerationValue ID="ProjectorCondition.Working" Parent="ProjectorCondition" Accessibility="Public"/>  
   <EnumerationValue ID="ProjectorCondition.BeingRepaired" Parent="ProjectorCondition" Accessibility="Public"/>  
   <EnumerationValue ID="ProjectorCondition.New" Parent="ProjectorCondition" Accessibility="Public"/>  
   <EnumerationValue ID="ProjectorCondition.Broken" Parent="ProjectorCondition" Accessibility="Public"/>  
   <EnumerationValue ID="ProjectorViewTasksEnumeration" Accessibility="Public"/>  
</EnumerationTypes>  

Создайте форму

Service Manager формы основаны на формах Windows Presentation Framework (WPF). Service Manager расширяет WPF простыми атрибутами, которые добавляются в определение XML и позволяют Service Manager привязывать данные из пакета управления к форме.

Service Manager формы можно создавать с помощью нескольких различных средств, включая Microsoft Visual Studio или Microsoft Expression Blend. Поскольку формы основаны на XML, их также можно создавать с помощью любого редактора XML.

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


<UserControl xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="clr-namespace:SMFormsDemo" x:Class="SMFormsDemo.TestControl" x:Name="Control" Width="574" Height="390" Opacity="1" xmlns:d="https://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">  
   <UserControl.Resources>  
      <ObjectDataProvider ObjectType="{x:Type local:helper}" MethodName="GetStatusValues" x:Key="getStatusValues"/>  
   </UserControl.Resources>  
   <Grid x:Name="LayoutRoot">  
      <Label Margin="70,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" Content="Serial Number:"/>  
      <TextBox Margin="180,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" d:IsStaticText="True" Text="{Binding Path=SerialNumber, Mode=TwoWay}"/>  
      <Label Margin="70,60,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" Content="Make:"/>  
      <TextBox Margin="180,60,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" d:IsStaticText="True" Text="{Binding Path=Make, Mode=TwoWay}"/>  
      <Label Margin="70,100,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" Content="Model:"/>  
      <TextBox Margin="180,100,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" d:IsStaticText="True" Text="{Binding Path=Model, Mode=TwoWay}"/>  
      <Label Margin="70,140,80,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" Content="Location:"/>  
      <TextBox Margin="180,140,80,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" d:IsStaticText="True" Text="{Binding Path=Location, Mode=TwoWay}"/>  
      <Label Margin="70,180,80,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" Content="Condition:"/>  
      <ComboBox Margin="180,180,80,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" ItemsSource="{Binding Source={StaticResource getStatusValues}, Mode=OneWay }" IsSynchronizedWithCurrentItem="True">  
         <ComboBox.SelectedItem>  
            <Binding Path="Condition" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"/>  
         </ComboBox.SelectedItem>  
         <ComboBox.ItemTemplate>  
            <DataTemplate>  
               <StackPanel>  
                  <TextBlock Text="{Binding Path=DisplayName}"/>  
               </StackPanel>  
            </DataTemplate>  
         </ComboBox.ItemTemplate>  
      </ComboBox>  
   </Grid>  
</UserControl>  

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

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

Чтобы привязать текстовые поля к свойствам класса в пакете управления, добавьте тег Binding Path в свойство Text элемента управления текстового поля, например:

{Binding Path=SerialNumber, Mode=TwoWay}  

Данный тег привязывает элемент управления "Текстовое поле" к свойству SerialNumber класса Projector , определенного в пакете управления, и указывает, что привязка должна быть двусторонней. Значение свойства извлекается из базы данных и отображается в текстовом поле при загрузке формы, а значение свойства сохраняется обратно в базу данных, если оно было изменено пользователем.

Привязка полей со списком

Чтобы форма могла извлечь данные перечисления из соответствующего пакета управления и привязать их к элементу управления формой, в разделе code-behind формы должен быть определен класс поддержки. Класс поддержки должен иметь метод, который возвращает перечисление, определенное в пакете управления. Для возврата перечисления используйте метод GetEnumerations , принадлежащий текущему пакету управления. Доступ к этому экземпляру осуществляется с помощью класса ConsoleContextHelper из пакета sdk Service Manager. В приведенном ниже примере класс поддержки определяет метод GetStatusValues , извлекающий значения перечисления ProjectorCondition , которое было определено в пакете управления.


public class helper  
{  
   public static ICollection<IDataItem> GetStatusValues()  
   {  
      return ConsoleContextHelper.Instance.GetEnumerations("ProjectorCondition",true);  
   }  
}  

Чтобы получить доступ к данному методу, в находящемся в пакете управления определении формы следует определить ряд элементов.

Прежде всего в определение формы добавляется пространство имен, указывающее на пространство имен code behind для формы. В данном примере используется пространство имен SMFormsDemo.

xmlns:local="clr-namespace:SMFormsDemo"  

Далее следует определить объект ObjectDataProvider для передачи значений полю со списком, отображающему состояние проектора. ObjectDataProvider определяется в виде ресурса:


<UserControl.Resources>  
   <ObjectDataProvider   
      ObjectType="{x:Type local:helper}"    
      MethodName="GetStatusValues"   
      x:Key="getStatusValues" />  
</UserControl.Resources>  

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

И, наконец, чтобы привязать поле со списком к значениям перечисления, указанным в пакете управления, в определение поля со списком добавляется атрибут ItemsSource . Данный атрибут указывает, куда извлечь значения перечисления, например:

ItemsSource="{Binding Source={StaticResource getStatusValues}, Mode=OneWay }"  

Далее, в XAML-определение элемента управления "поле со списком" добавляются элементы SelectedItem и ItemTemplate . В следующем примере показывается определение поля со списком с дополнительным XAML-кодом привязки.


<ComboBox Margin="180,180,80,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" ItemsSource="{Binding Source={StaticResource getStatusValues}, Mode=OneWay }" IsSynchronizedWithCurrentItem="True">  
   <ComboBox.SelectedItem>  
      <Binding Path="Condition" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"/>  
   </ComboBox.SelectedItem>  
   <ComboBox.ItemTemplate>  
      <DataTemplate>  
         <StackPanel>  
            <TextBlock Text="{Binding Path=DisplayName}"/>  
         </StackPanel>  
      </DataTemplate>  
   </ComboBox.ItemTemplate>  
</ComboBox>  

Раздел "Категория"

Раздел Category группирует элементы пакета управления для упрощения навигации.

Первые два <Category> элемента в примере используются для управления отображением задач "Создать" и "Изменить " в представлении "Проекторы ".

<Category ID="ProjectorViewHasTasks.View" Target="AllProjectorsView" Value="ProjectorViewTasksEnumeration" />  
<Category ID="ProjectorViewHasTasks.CreateTask" Target="CreateProjector" Value="ProjectorViewTasksEnumeration" />  

Вторые два элемента Category в примере пакета управления используются для отображения перечисления условий проектора в представлении Списки на панели Разработка в консоли Service Manager. Это позволяет пользователю выполнять настройку значений:

<Category ID="Project.ProjectorConditionEnumVisibleCategory" Target="ProjectorCondition" Value="System!VisibleToUser"/>  

Добавление данной категории в представленный ниже пример приводит к появлению задачи Правка в представлении Списки для значения EnumerationValue , на которое указывает атрибут Target .

<Category ID="Projector.ProjectorConditionCategory" Target="ProjectorCondition" Value="Authoring!Microsoft.EnterpriseManagement.ServiceManager.UI.Authoring.EnumerationViewTasks"/>  

Раздел "Презентация"

Раздел Presentation используется для объявления и определения элементов, связанных с пользовательским интерфейсом. К этому разряду относятся объявления форм, категории и задачи консоли.

Раздел Forms

В разделе Forms объявляются формы, используемые пакетом управления. В примере ниже указывается расположение формы, определенной для отображения и изменения экземпляров класса Projector . Данный код привязывает форму к классу Projector , определенному в пакете управления.


<Forms>  
   <Form TypeName="SMFormsDemo.TestControl"  
      ID="TestForm"  
      Target="System.ConfigItem.Projector"  
      Assembly="ProjectorFormsAssembly"  
      Accessibility="Public">  
   <Category>Form</Category>  
   </Form>  
</Forms>  

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

  • Атрибут TypeName содержит пространство имен и имя класса для формы.

  • Атрибут ID содержит уникальный идентификатор данного экземпляра формы.

  • Атрибут Target содержит имя класса, к которому привязана данная форма.

  • Атрибут Assembly указывает на внешний ресурс, в котором размещена форма.

  • Атрибут Accessibility определяет возможность настройки данной формы.

Определение представления

Раздел пакета управления Views содержит определения представлений пользовательского интерфейса. Эти представления можно использовать для фильтрации и отображения объектов пакета управления.

<View Target="System.ConfigItem.Projector"   
Enabled="true"  
TypeID="SMConsole!GridViewType"  
ID="AllProjectorsView"  
Accessibility="Public">  
<Category>NotUsed</Category>  
<Data>  
<Adapters>  
      <Adapter AdapterName="dataportal:EnterpriseManagementObjectAdaptor">  
                <AdapterAssembly>Microsoft.EnterpriseManagement.UI.SdkDataAccess</AdapterAssembly>  
   <AdapterType>  
Microsoft.EnterpriseManagement.UI.SdkDataAccess.DataAdapters.EnterpriseManagementObjectAdapter  
   </AdapterType>  
      </Adapter>  
            <Adapter AdapterName="viewframework://adapters/ListDefault">  
              <AdapterAssembly>Microsoft.EnterpriseManagement.UI.ViewFramework</AdapterAssembly>  
              <AdapterType>Microsoft.EnterpriseManagement.UI.ViewFramework.ListSupportAdapter</AdapterType>  
            </Adapter>  
</Adapters>  
<ItemsSource>  
  <AdvancedListSupportClass DataTypeName="" AdapterName="viewframework://adapters/AdvancedList" FullUpdateAdapter="dataportal:EnterpriseManagementObjectAdapter" FullUpdateFrequency='1' DataSource="mom:ManagementGroup" IsRecurring="true" RecurrenceFrequency="5000"  treaming='true' xmlns="clr-namespace:Microsoft.EnterpriseManagement.UI.ViewFramework;assembly=Microsoft.EnterpriseManagement.UI.ViewFramework" xmlns:av="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" >  
    <AdvancedListSupportClass.Parameters>  
                <QueryParameter Parameter="TargetClass" Value="System.ConfigItem.Projector"/>  
    </AdvancedListSupportClass.Parameters>  
    </AdvancedListSupportClass>  
    </ItemsSource>  
    <Criteria />  
</Data>  
<Presentation>  
<Columns>  
            <mux:ColumnCollection xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:mux="https://schemas.microsoft.com/SystemCenter/Common/UI/Views/GridView" xmlns:s="clr-namespace:System;assembly=mscorlib">  
              <mux:Column Name="SerialNumber" DisplayMemberBinding="{Binding Path=SerialNumber}" Width="100" DisplayName="SerialNumber" Property="SerialNumber" DataType="s:Int32" />  
              <mux:Column Name="Location" DisplayMemberBinding="{Binding Path=Location}" Width="100" DisplayName="Location" Property="Location" DataType="s:String" />  
              <mux:Column Name="Condition" DisplayMemberBinding="{Binding Path=Condition.DisplayName}" Width="100" DisplayName="Condition" Property="Condition.DisplayName" DataType="s:String" />  
              <mux:Column Name="DisplayName" DisplayMemberBinding="{Binding Path=DisplayName}" Width="100" DisplayName="Display Name" Property="DisplayName" DataType="s:String" />  
              <mux:Column Name="OwnerUser" DisplayMemberBinding="{Binding Path=OwnerUser.DisplayName}" Width="100" DisplayName="SupportOwner" Property="OwnerUser.DisplayName" DataType="s:String" />  
            </mux:ColumnCollection>      
</Columns>  
</Presentation>  
</View>  

Атрибут View Target указывает на класс, который будет отображаться в представлении.

Пример выше содержит ссылку на пакет управления консоли Service Manager. Данный пакет управления содержит определение используемого типа представления. В этом экземпляре определен тип представления SMConsole!GridViewType .

Элемент AdvancedListSupportClass определяет ряд параметров, самым важным из которых является параметр TargetClass . Установите этому параметру значение ID из элемента ClassType , который будет показан в данном представлении. Для отображения столбцов, являющихся свойствами элемента ClassType, используйте элемент Column и привяжите его к атрибуту PropertyID .

Атрибут IsRecurring элемента ListSupportClass определяет, выполняется ли автоматическое обновление представления. Атрибут RecurrenceFrequency определяет интервал обновления в миллисекундах. В этом примере для интервала обновления задано значение 1 секунда, но это не рекомендуется для рабочих установок.

Определение папок

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

<Folders>  
  <Folder ID="Folder.Projectors" Accessibility="Public" ParentFolder="SMConfig!ServiceManager.Console.ConfigurationManagement.ConfigItem.Root" />  
</Folders>  
<FolderItems>  
   <FolderItem   
      ElementID="AllProjectorsView"   
      Folder="Folder.Projectors" />  
   </FolderItems>  

В примере выше атрибут ElementID содержит ссылку на созданное представление. Атрибут Folder указывает на папку Folders.Projectors, которая, в свою очередь, имеет корневой каталог, как определено в рабочей области Управление конфигурацией консоли Service Manager. Данная корневая папка определена в пакете управления "Управление конфигурацией".

Элемент ImageReference сопоставляет созданное представление со значком, определенным в пространстве имен Configuration Management .

<ImageReferences>  
  <ImageReference ElementID="Folder.Projectors" ImageID="SMConfig!ConfigItemImage16x16" />  
  <ImageReference ElementID="AllProjectorsView" ImageID="SMConfig!ConfigItemImage16x16" />  
</ImageReferences>  

Локализация с помощью раздела LanguagePacks

Раздел LanaguagePacks определяет строковые ресурсы и сопоставления для элементов пакета управления.

В этом примере элемент EnumerationValueProjectorCondition.Working должен иметь вид Working. Для этого следует определить отображаемые имена всех следующих элементов:

  • Представление: Все проекторы

  • Перечисления: работает, неисправен, в ремонте, новый

  <LanguagePacks>  
    <LanguagePack ID="ENU" IsDefault="true">  
      <DisplayStrings>  
        <DisplayString ElementID="AllProjectorsView">  
          <Name>All Projectors</Name>  
          <Description>This displays all projectors</Description>  
        </DisplayString>  
        <DisplayString ElementID="ProjectorCondition.Working">  
          <Name>Working</Name>  
        </DisplayString>  
        <DisplayString ElementID="ProjectorCondition.Broken">  
          <Name>Broken</Name>  
        </DisplayString>  
        <DisplayString ElementID="ProjectorCondition.BeingRepaired">  
          <Name>In Repair</Name>  
        </DisplayString>  
        <DisplayString ElementID="ProjectorCondition.New">  
          <Name>New</Name>  
        </DisplayString>  
      </DisplayStrings>  
    </LanguagePack>  
</LanguagePacks>  

При необходимости вы можете создать дополнительные элементы LanguagePack на каждом нужном языке. Для пользователя отображается правильная отображаемая строка в зависимости от языкового стандарта пользователя.

Ресурсы

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

<Assembly ID="ProjectorFormsAssembly"    
         Accessibility="Public"   
         QualifiedName="SMFormsDemo, Version=1.0.0.0" FileName="SMFormsDemo.dll" CreationDate="1900-10-12T13:13:13" ModifiedDate="2008-12-12T12:12:12" />  

Расширения класса

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

Расширение класса наследует свойства всех родительских классов, например:

  • Класс А имеет свойство с именем Свойство1.

  • Класс B является производным от класса А или расширяет его, следовательно, он имеет свойство с именем Свойство1. Это свойство унаследовано от класса А (родительского или базового класса).

  • Определение класса B добавляет свойство с именем Свойство2.

  • Любое расширение класса, производное от класса B, унаследует Свойство1 и Свойство2.

    В следующем примере показано определение расширения класса.


<TypeDefinitions>  
     <EntityTypes>  
       <ClassTypes>  
         <ClassType ID="IncidentManagmentPack.Extension" Accessibility="Public" Base="Incident!System.WorkItem.Incident" Hosted="false" IsExtensionType="true">  
          <Property ID="TimeOnIncident" Type="int" Key="false" />  
        </ClassType>  
      </ClassTypes>  
    </EntityTypes>  
  </TypeDefinitions>  

Это расширение класса расширяет класс System.WorkItem.Incident и добавляет новое свойство с именем TimeOnIncident.

Определение расширения класса похоже на определение класса. Для определения класса используются два атрибута элемента ClassType : атрибут Base и атрибут IsExtensionType .

Атрибут Base определяет ID родительского класса, от которого является производным расширение класса. В данном случае атрибут имеет значение Incident!System.WorkItem.Incident. Это значение содержит Alias полного имени пакета управления и состоит из имени расширяемого класса, восклицательного знака и имени базового класса. Дополнительные сведения см. в следующем примере.

Атрибут IsExtensionType определяет, является ли данный класс расширением базового класса. Поскольку TimeOnIncident является расширением класса Incident , это свойство имеет значение true:

IsExtensionType="true"  

Другой параметр — false, который указывает, что это не расширение другого класса, а новый класс, наследующий от базового. Значение по умолчанию — false; Поэтому этот атрибут не обязательно использовать, если класс не является расширением.

Полный пример

В следующем примере кода показан полный пакет управления, содержащий расширение класса.

ManagementPack xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" ContentReadable="true" SchemaVersion="1.1">  
   <Manifest>  
     <Identity>  
      <ID>ServiceManager.Extension</ID>  
      <Version>1.0.0.0</Version>  
     </Identity>  
    <Name>ServiceManagerExtension</Name>  
     <References>  
       <Reference Alias="System">  
        <ID>System.Library</ID>  
        <Version>1.0.2780.0</Version>  
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>  
      </Reference>  
      <Reference Alias="Incident">  
        <ID>System.WorkItem.Incident.Library</ID>  
        <Version>1.0.2780.0</Version>  
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>  
      </Reference>  
    </References>  
  </Manifest>  
   <TypeDefinitions>  
     <EntityTypes>  
       <ClassTypes>  
         <ClassType ID="IncidentManagmentPack.Extension" Accessibility="Public" Base="Incident!System.WorkItem.Incident" Hosted="false" Extension="true">  
          <Property ID="TimeOnIncident" Type="int" Key="false" />  
        </ClassType>  
      </ClassTypes>  
    </EntityTypes>  
  </TypeDefinitions>  
</ManagementPack>  

Импорт пакета управления с помощью командлета

Для импорта пакета управления Service Manager можно использовать командлет Windows PowerShell Import-SCSMManagementPack, например:

Import-SCSMManagementPack MyServiceManager.ManagementPack.xml  

В этом документе не описывается, как импортировать и использовать пакеты управления в консоли Service Manager. Сведения об использовании пакетов управления в консоли Service Manager см. в статье Использование пакетов управления в Service Manager.

Пример полного пакета управления

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

Пакет управления

<ManagementPack ContentReadable="true" SchemaVersion="1.1" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">  
  <Manifest>  
    <Identity>  
      <ID>ServiceManager.Projector</ID>  
      <Version>7.0.3707.0</Version>  
    </Identity>  
    <Name>Projector Library</Name>  
    <References>  
      <Reference Alias="SMConsole">  
        <ID>Microsoft.EnterpriseManagement.ServiceManager.UI.Console</ID>  
        <Version>7.0.3707.0</Version>  
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>  
      </Reference>  
      <Reference Alias="Authoring">  
        <ID>Microsoft.EnterpriseManagement.ServiceManager.UI.Authoring</ID>  
        <Version>7.0.3707.0</Version>  
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>  
      </Reference>  
      <Reference Alias="System">  
        <ID>System.Library</ID>  
        <Version>7.0.3707.0</Version>  
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>  
      </Reference>  
      <Reference Alias="SMConfig">  
        <ID>ServiceManager.ConfigurationManagement.Library</ID>  
        <Version>7.0.3707.0</Version>  
        <PublicKeyToken>31bf3856ad364e35</PublicKeyToken>  
      </Reference>  
    </References>  
  </Manifest>  
  <TypeDefinitions>  
    <EntityTypes>  
      <ClassTypes>  
        <ClassType ID="System.ConfigItem.Projector" Accessibility="Public" Abstract="false" Base="System!System.ConfigItem" Hosted="false" Singleton="false" Extension="false">  
          <Property ID="SerialNumber" Type="int" Key="true" />  
          <Property ID="Make" Type="string" />  
          <Property ID="Model" Type="string" />  
          <Property ID="Location" Type="string" />  
          <Property ID="Condition" Type="enum" EnumType="ProjectorCondition" />  
        </ClassType>  
      </ClassTypes>  
      <EnumerationTypes>  
        <EnumerationValue ID="ProjectorCondition" Accessibility="Public" />  
        <EnumerationValue ID="ProjectorCondition.Working" Accessibility="Public" Parent="ProjectorCondition" />  
        <EnumerationValue ID="ProjectorCondition.BeingRepaired" Accessibility="Public" Parent="ProjectorCondition" />  
        <EnumerationValue ID="ProjectorCondition.New" Accessibility="Public" Parent="ProjectorCondition" />  
        <EnumerationValue ID="ProjectorCondition.Broken" Accessibility="Public" Parent="ProjectorCondition" />  
        <EnumerationValue ID="ProjectorViewTasksEnumeration" Accessibility="Public" />  
      </EnumerationTypes>  
    </EntityTypes>  
  </TypeDefinitions>  
  <Categories>  
    <Category ID="AllProjectorsView.Category" Target="AllProjectorsView" Value="SMConsole!Microsoft.EnterpriseManagement.ServiceManager.UI.Console.ViewTasks" />  
    <Category ID="ProjectorViewHasTasks.CreateTask" Target="AllProjectorsView" Value="Authoring!Microsoft.EnterpriseManagement.ServiceManager.UI.Authoring.CreateTypeCategory" />  
    <Category ID="Projector.ProjectorConditionCategory" Target="ProjectorCondition" Value="Authoring!Microsoft.EnterpriseManagement.ServiceManager.UI.Authoring.EnumerationViewTasks" />  
    <Category ID="Project.ProjectorConditionEnumVisibleCategory" Target="ProjectorCondition" Value="System!VisibleToUser" />  
  </Categories>  
  <Presentation>  
    <Forms>  
      <Form ID="TestForm" Accessibility="Public" Target="System.ConfigItem.Projector" Assembly="ProjectorFormsAssembly" TypeName="New_CI_lab.TestControl">  
        <Category>Form</Category>  
      </Form>  
    </Forms>  
    <Views>  
      <View ID="AllProjectorsView" Accessibility="Public" Enabled="true" Target="System.ConfigItem.Projector" TypeID="SMConsole!GridViewType" Visible="true">  
    <Category>NotUsed</Category>  
    <Data>  
    <Adapters>  
    <Adapter AdapterName="dataportal:EnterpriseManagementObjectAdapter">  
    <AdapterAssembly>Microsoft.EnterpriseManagement.UI.SdkDataAccess</AdapterAssembly>  
    <AdapterType>Microsoft.EnterpriseManagement.UI.SdkDataAccess.DataAdapters.EnterpriseManagementObjectAdapter</AdapterType>  
    </Adapter>  
    <Adapter AdapterName="viewframework://adapters/AdvancedList">  
    <AdapterAssembly>Microsoft.EnterpriseManagement.UI.ViewFramework</AdapterAssembly>  
    <AdapterType>Microsoft.EnterpriseManagement.UI.ViewFramework.AdvancedListSupportAdapter</AdapterType>  
    </Adapter>  
    <Adapter AdapterName="omsdk://Adapters/Criteria">  
    <AdapterAssembly>Microsoft.EnterpriseManagement.UI.SdkDataAccess</AdapterAssembly>  
    <AdapterType>Microsoft.EnterpriseManagement.UI.SdkDataAccess.DataAdapters.SdkCriteriaAdapter</AdapterType>  
    </Adapter>  
    </Adapters>  
    <ItemsSource>  
    <AdvancedListSupportClass DataTypeName="" AdapterName="viewframework://adapters/AdvancedList" FullUpdateAdapter="dataportal:EnterpriseManagementObjectAdapter" FullUpdateFrequency='1' DataSource="mom:ManagementGroup"   
  IsRecurring="true" RecurrenceFrequency="5000"  Streaming='true' xmlns="clr-namespace:Microsoft.EnterpriseManagement.UI.ViewFramework;assembly=Microsoft.EnterpriseManagement.UI.ViewFramework" xmlns:av="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" >  
    <AdvancedListSupportClass.Parameters>  
                <QueryParameter Parameter="TargetClass" Value="System.ConfigItem.Projector"/>  
    </AdvancedListSupportClass.Parameters>  
    </AdvancedListSupportClass>  
    </ItemsSource>  
    <Criteria />  
    </Data>  
    <Presentation>  
    <Columns>  
<mux:ColumnCollection xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:mux="https://schemas.microsoft.com/SystemCenter/Common/UI/Views/GridView" xmlns:s="clr-namespace:System;assembly=mscorlib">  
              <mux:Column Name="SerialNumber" DisplayMemberBinding="{Binding Path=SerialNumber}" Width="100" DisplayName="SerialNumber" Property="SerialNumber" DataType="s:Int32" />  
              <mux:Column Name="Location" DisplayMemberBinding="{Binding Path=Location}" Width="100" DisplayName="Location" Property="Location" DataType="s:String" />  
              <mux:Column Name="Condition" DisplayMemberBinding="{Binding Path=Condition.DisplayName}" Width="100" DisplayName="Condition" Property="Condition.DisplayName" DataType="s:String" />  
              <mux:Column Name="DisplayName" DisplayMemberBinding="{Binding Path=DisplayName}" Width="100" DisplayName="Display Name" Property="DisplayName" DataType="s:String" />  
              <mux:Column Name="OwnerUser" DisplayMemberBinding="{Binding Path=OwnerUser.DisplayName}" Width="100" DisplayName="SupportOwner" Property="OwnerUser.DisplayName" DataType="s:String" />  
            </mux:ColumnCollection>      
    </Columns>  
    </Presentation>  
    </View>  
    </Views>  
    <Folders>  
      <Folder ID="Folder.Projectors" Accessibility="Public" ParentFolder="SMConfig!ServiceManager.Console.ConfigurationManagement.ConfigItem.Root" />  
    </Folders>  
    <FolderItems>  
      <FolderItem ElementID="AllProjectorsView" ID="FolderItem.AllProjectors" Folder="Folder.Projectors" />  
    </FolderItems>  
    <ImageReferences>  
      <ImageReference ElementID="Folder.Projectors" ImageID="SMConfig!ConfigItemImage16x16" />  
      <ImageReference ElementID="AllProjectorsView" ImageID="SMConfig!ConfigItemImage16x16" />  
    </ImageReferences>  
  </Presentation>  
  <LanguagePacks>  
    <LanguagePack ID="ENU" IsDefault="true">  
      <DisplayStrings>  
    <DisplayString ElementID="System.ConfigItem.Projector">  
    <Name>Projector</Name>  
    </DisplayString>  
        <DisplayString ElementID="Folder.Projectors">  
          <Name>Projectors</Name>  
          <Description>This is the Projector Folder</Description>  
        </DisplayString>  
        <DisplayString ElementID="AllProjectorsView">  
          <Name>All Projectors</Name>  
          <Description>This displays all projectors</Description>  
        </DisplayString>  
        <DisplayString ElementID="ProjectorCondition.Working">  
          <Name>Working</Name>  
        </DisplayString>  
        <DisplayString ElementID="ProjectorCondition.Broken">  
          <Name>Broken</Name>  
        </DisplayString>  
        <DisplayString ElementID="ProjectorCondition.BeingRepaired">  
          <Name>In Repair</Name>  
        </DisplayString>  
        <DisplayString ElementID="ProjectorCondition.New">  
          <Name>New</Name>  
        </DisplayString>  
      </DisplayStrings>  
    </LanguagePack>  
  </LanguagePacks>  
  <Resources>  
    <Assembly ID="ProjectorFormsAssembly" Accessibility="Public" FileName="New_CI_lab.dll" QualifiedName="New_CI_lab, Version=0.0.0.0" />  
  </Resources>  
</ManagementPack>  

Определение формы


<UserControl  
    xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"  
    xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"  
    xmlns:local="clr-namespace:SMFormsDemo"  
    x:Class="SMFormsDemo.TestControl"  
    x:Name="Control"  
    Width="574" Height="390" Opacity="1" xmlns:d="https://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" Background="{DynamicResource {x:Static SystemColors.WindowBrushKey}}">  
  <UserControl.Resources>  
    <ObjectDataProvider ObjectType="{x:Type local:helper}"  MethodName="GetStatusValues" x:Key="getStatusValues" />  
  </UserControl.Resources>  
  <Grid x:Name="LayoutRoot">  
    <Label Margin="70,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" Content="Serial Number:"/>  
    <TextBox Margin="180,20,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" d:IsStaticText="True" Text="{Binding Path=SerialNumber, Mode=TwoWay}"/>  
    <Label Margin="70,60,0,0" HorizontalAlignment="Left"  VerticalAlignment="Top" Width="160" Height="25" Content="Make:"/>  
    <TextBox Margin="180,60,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" d:IsStaticText="True" Text="{Binding Path=Make, Mode=TwoWay}" />  
    <Label Margin="70,100,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" Content="Model:"/>  
    <TextBox Margin="180,100,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" d:IsStaticText="True" Text="{Binding Path=Model, Mode=TwoWay}"/>  
    <Label Margin="70,140,80,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" Content="Location:"/>  
    <TextBox Margin="180,140,80,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" d:IsStaticText="True" Text="{Binding Path=Location, Mode=TwoWay}" />  
    <Label Margin="70,180,80,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" Content="Condition:"/>  
    <ComboBox Margin="180,180,80,0" HorizontalAlignment="Left" VerticalAlignment="Top" Width="160" Height="25" ItemsSource="{Binding Source={StaticResource getStatusValues}, Mode=OneWay }" IsSynchronizedWithCurrentItem="True">  
      <ComboBox.SelectedItem>  
        <Binding Path="Condition" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged"/>  
      </ComboBox.SelectedItem>  
      <ComboBox.ItemTemplate>  
        <DataTemplate>  
          <StackPanel>  
            <TextBlock Text="{Binding Path=DisplayName}"/>  
          </StackPanel>  
        </DataTemplate>  
      </ComboBox.ItemTemplate>  
    </ComboBox>  
  </Grid>  
</UserControl>  

Код программной части формы


using System;  
using System.Collections.Generic;  
using System.Collections.ObjectModel;  
using System.Threading;  
using System.Windows.Controls;  
using Microsoft.EnterpriseManagement.ServiceManager.Application.Common;  
using Microsoft.EnterpriseManagement.UI.DataModel;  
namespace SMFormsDemo  
{  
   /// <summary>  
   /// Interaction logic for ProjectorForm.xaml  
   /// </summary>  
   public partial class TestControl : UserControl  
   {  
        public TestControl()  
      {  
         InitializeComponent();  
      }        
   }  
   public class helper  
   {  

      public static ICollection<IDataItem> GetStatusValues()  
      {  
            return ConsoleContextHelper.Instance.GetEnumerations("ProjectorCondition",true);  
      }  
   }  
}  

Дальнейшие действия