Compartir a través de


Trabajar con archivos XML del módulo de administración de Service Manager

Para realizar personalizaciones elaboradas de módulos de administración, es posible que la consola de Service Manager y la herramienta de creación de Service Manager no sean suficientes y es posible que tenga que crear o modificar archivos del módulo de administración directamente. Trabajar directamente con archivos de módulo de administración requiere conocimientos detallados en varias áreas, como el esquema común de System Center y la estructura de los módulos de administración.

En esta sección se proporciona información general e instrucciones que pueden ayudarle a crear y modificar módulos de administración para personalizar Service Manager.

Cambios en el esquema común de System Center

Service Manager incluye una versión actualizada del esquema del módulo de administración de System Center. Este esquema ahora se denomina Esquema común de System Center e incluye una serie de mejoras y adiciones que están pensadas para mejorar la funcionalidad existente y habilitar las características de Service Manager. En este artículo se describen los cambios en el esquema común de System Center.

Propiedades y restricciones de propiedades

El esquema común amplía las clases a través de varios tipos de propiedades nuevos. Estos tipos de propiedad incluyen los tipos binarios, enumeradores y incremento automático.

Además, puede definir restricciones en determinados valores de propiedad. Por ejemplo, puede definir una restricción de expresión regular en un valor de propiedad de cadena. En el ejemplo siguiente, la propiedad BuildingName tiene una restricción de expresión regular definida para que solo un valor que contenga la palabra Building seguido de un espacio y un número se considera válido.


<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>  

Imágenes

Las imágenes no se almacenan dentro de un módulo de administración. Por lo tanto, la <PresentationTypes> sección del módulo de administración ya no contiene las <Images>etiquetas , <Image>o <ImageData> . En su lugar, use un recurso de imagen.

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

Enumeraciones

El esquema común admite enumeraciones. Las enumeraciones son un árbol de valores que puede usar para restringir el valor de una propiedad o atributo.

Cada enumeración tiene un atributo id. único necesario y un atributo Primario opcional.

En el ejemplo siguiente, la enumeración XBoxState se define con tres valores posibles: Running, Stopped y 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>  

En el ejemplo siguiente, la clase Xbox define una propiedad de enumeración de tipo 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>  

Relaciones

La funcionalidad de las definiciones de relación se ha mejorado en el esquema común. El tipo RelationshipType ahora tiene subelementos Source y Target con propiedades id . que se pueden usar como nombres para mostrar. Además, puede definir la cardinalidad mínima y máxima para el origen y el destino; por ejemplo, relaciones de 1 a 1 o 0 a varios.

El proceso de validación del módulo de administración no aplica la cardinalidad, pero está pensado para ayudar a definir interfaces de usuario para el módulo de administración. Por ejemplo, se puede comprobar la cardinalidad para determinar si un campo se puede representar en un formulario mediante un cuadro de texto o por una lista.

Importante

Cualquier valor maxCardinality definido como mayor que 1 se procesa como ilimitado.

Si agrega un nuevo tipo de relación desde su propio módulo de administración, los usuarios deben tener privilegios suficientes para actualizar todas las propiedades de las instancias de clase de origen y de destino del tipo de relación para crear una instancia del nuevo tipo de relación.

En el ejemplo siguiente, se define una relación de hospedaje denominada HasXboxes entre el tipo lobby y el tipo xbox. En esta definición de relación, cada tipo de lobby puede tener varios tipos de 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>  

Clases combinadas

Las clases combinadas representan una agregación de varios tipos relacionados en el módulo de administración, similares a las vistas definidas en una base de datos de Microsoft SQL Server que puede devolver datos de varias tablas. Las clases combinadas almacenan y recuperan todos los datos agregados de una operación en la base de datos y pueden facilitar la definición de interfaces de usuario para un módulo de administración.

En el ejemplo siguiente, se define una proyección para una vista de administración de incidentes. Esta proyección combina varios componentes diferentes relacionados con un incidente en una unidad que se puede usar más fácilmente para formularios y para operaciones de base de datos.


<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>  

Tareas de consola

Las tareas de consola se extienden en el esquema común. Anteriormente, las tareas de consola eran punteros simples a un directorio de aplicación y un nombre de archivo ejecutable. Las tareas de consola ahora se implementan como código de controlador en un ensamblado de Microsoft .NET Framework. El código del controlador hace referencia al ensamblado que aloja el código, el nombre del controlador y una lista de valores con nombre que se pueden pasar como argumentos al controlador.

En el ejemplo siguiente, el controlador de Some.Handler.Name se define en el ensamblado MyLibrary.Resources.Assembly . También se define una lista de parámetros de controlador y sus valores.

<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>  

Recursos

Los datos binarios no se almacenan directamente en un módulo de administración. En su lugar, los metadatos sobre el recurso binario se almacenan en el módulo de administración y los datos binarios reales se almacenan externamente en un archivo de recursos. Los metadatos incluyen un identificador único, el nombre de archivo, los datos de creación, la fecha de modificación y la información de accesibilidad.

Los datos binarios pueden incluir recursos genéricos, imágenes, ensamblados, definiciones de informe y formularios. En el ejemplo siguiente se muestra un recurso XML genérico, un recurso de ensamblado y un recurso de informe.


<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>  

Formularios

Los formularios se definen en un módulo de administración. Puede usar formularios para ver y modificar una sola instancia de una clase de tipo o combinación.

Los formularios se basan en Windows Presentation Framework (WPF) y se definen en ensamblados. El ensamblado y la clase que contienen las implementaciones de formulario para un módulo de administración se incluyen en la sección de recursos del módulo de administración. Al igual que con cualquier recurso binario de un módulo de administración que usa el nuevo esquema común, el propio módulo de administración no contiene los datos binarios del formulario. Solo se especifica el manifiesto de recursos en el módulo de administración.

Puede especificar su propia información de configuración para el formulario en el módulo de administración. En el ejemplo siguiente, la sección Configuración contiene una propiedad ShowXboxes . El proceso de comprobación del módulo de administración no evalúa esta información de configuración; solo se interpreta mediante la implementación del formulario.


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

Creación de un archivo de módulo de administración para administrar proyectores

Los módulos de administración se usan para dirigir y ampliar la funcionalidad de Service Manager. En este artículo se usan proyectores como ejemplo para describir las distintas secciones de un módulo de administración y para definir los distintos objetos necesarios para administrar proyectores en una organización.

En este artículo se incluye un ejemplo completo del módulo de administración con las extensiones necesarias para administrar proyectores en una organización. Además, describe cómo importar un módulo de administración mediante un cmdlet de Windows PowerShell.

En este artículo se describen las secciones siguientes de un módulo de administración:

  • El manifiesto

  • TypeDefinitions para crear enumeraciones de clases y relaciones

  • Formularios

En este artículo también se describen las secciones siguientes de un módulo de administración que contiene declaraciones y definiciones para la interfaz de usuario (UI) y los elementos de localización:

  • Categorías

  • Presentación

  • Extensiones de clase

Sección manifiesto

La primera sección de un módulo de administración contiene el manifiesto. El manifiesto identifica el módulo de administración y declara las referencias a otros módulos de administración.

En el ejemplo siguiente se muestra la sección Manifiesto de un módulo de administración diseñado para realizar un seguimiento de los proyectores de una organización.


<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>  

Importante

En la sección Referencias , no use valores nonalphanumeric, como ".", en alias para una referencia.

Creación de clases en la sección TypeDefinitions

La siguiente sección de un módulo de administración contiene definiciones de tipo. La sección TypeDefinitions de un módulo de administración contiene definiciones para clases, enumeraciones y relaciones que usa el módulo de administración.

En el ejemplo siguiente se muestra una clase que contiene información sobre los proyectores:


<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>  

A continuación se muestra una explicación de sección por sección de lo que contiene la definición de tipo.

Sección ClassTypes

El elemento ClassType define la clase del proyector:

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

El atributo ID es el identificador único de esta clase. Se establece en:

ID="System.ConfigItem.Projector"

El atributo Base es el identificador de la clase a partir de la que deriva esta clase. Dado que un proyector es un tipo de elemento de configuración, se establece en:

Base="System!System.ConfigItem"

La notación de System! indica que esta clase, System.ConfigItem, está en el módulo de administración al que hace referencia el alias System.

El atributo Hosted define si esta clase está hospedada por otra clase. En este caso, una instancia de esta clase solo puede existir cuando existe una instancia de host que la contiene. En este ejemplo, los proyectores no se hospedan en nada; Por lo tanto, el atributo Hosted se establece en false:

Hosted="false"

Si se establece el atributo Hosted en true , se indica que la clase está hospedada por otra clase. Una relación de hospedaje debe declararse en la sección RelationshipTypes .

El atributo Accessibility define si otras clases pueden derivar de esta clase. En los casos en los que quiera permitir que otros usuarios creen una versión más específica de la clase, establezca este atributo en público, por ejemplo:

Accessibility="Public"

Establecer el atributo Accessibility en Internal impide que otras clases deriven de esta clase.

El atributo Abstract define si se pueden crear instancias de esta clase o si la clase debe usarse como clase primaria a otras clases de las que derivar. En este ejemplo, este atributo se establece en false. Establecer este atributo en true significa que no se puede crear ninguna instancia de esta clase directamente y que esta clase solo se puede usar como clase primaria.

La siguiente sección de la definición de clase contiene las propiedades de clase. El XML que define las propiedades de clase de este ejemplo se definen en el ejemplo de código siguiente:


<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"  />  

Cada elemento Property tiene los atributos siguientes:

  • Atributo ID , que designa el identificador único de la propiedad.

  • Atributo Type , que indica el tipo de datos de la propiedad.

  • Atributo Key . Si se establece este atributo en true , se indica que esta propiedad se usará para identificar de forma única esta clase.

Crear tipos de enumeración

Las enumeraciones del tipo de datos de enumeración son tipos de datos especiales. Las enumeraciones se usan para restringir los datos permitidos para una propiedad a un conjunto específico de valores. Las enumeraciones pueden ser jerárquicas; una enumeración puede basarse en otra enumeración.

Las enumeraciones se definen en la sección EnumertionTypes de un paquete de soluciones. Una definición de enumeración contiene la enumeración raíz, seguida de los valores de enumeración reales.

Cada EnumerationValue acepta algunos atributos:

En este ejemplo, se define una enumeración para realizar un seguimiento de la condición de los proyectores. A continuación se define esta enumeración:

  • Id. es el identificador del valor de enumeración o enumeración.

  • Accesibilidad especifica si este enumerador puede contener otros enumeradores.

  • ParentName es un atributo que especifica el identificador del elemento primario del valor del enumerador.


<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>  

Crear un formulario

Los formularios de Service Manager se basan en formularios de Windows Presentation Framework (WPF). Service Manager amplía WPF con atributos simples que se agregan a la definición XML y permiten que Service Manager enlace datos desde el módulo de administración al formulario.

Los formularios de Service Manager se pueden crear mediante varias herramientas diferentes, como Microsoft Visual Studio o Microsoft Expression Blend. Dado que los formularios están basados en XML, también se pueden definir mediante cualquier editor XML.

En el ejemplo siguiente se muestra una definición de formulario que se creó mediante Microsoft Expression Blend. Este formulario contiene cuatro controles, tres cuadros de texto y un cuadro combinado, que están enlazados a las propiedades de la clase Proyector que se definieron anteriormente:


<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>  

Para habilitar el enlace de controles en el formulario a las propiedades de clase definidas en un módulo de administración, se debe especificar un número de elementos.

Enlazar controles de texto

Para enlazar cuadros de texto a propiedades de clase en un módulo de administración, agregue una etiqueta Ruta de acceso de enlace a la propiedad Text del control text del cuadro de texto, por ejemplo:

{Binding Path=SerialNumber, Mode=TwoWay}  

Esta etiqueta enlaza el control de cuadro de texto a la propiedad SerialNumber de la clase Proyector definida en el módulo de administración y especifica que debe ser un enlace bidireccional. El valor de la propiedad se recupera de la base de datos y se muestra en el cuadro de texto cuando se carga el formulario y el valor de la propiedad se almacena de nuevo en la base de datos si el usuario lo cambia.

Enlazar cuadros combinados

Para permitir que el formulario recupere los datos de enumeración del módulo de administración subyacente y enlazarlos a un control del formulario, se debe definir una clase auxiliar en el código subyacente del formulario. Esta clase auxiliar debe contener un método que devuelva una enumeración definida en el módulo de administración. Para devolver una enumeración, use el método GetEnumerations del módulo de administración actual. Se accede a esta instancia con la clase ConsoleContextHelper desde el kit de desarrollo de software (SDK) de Service Manager. En el ejemplo siguiente, una clase auxiliar define un método GetStatusValues que recupera los valores de la enumeración ProjectorCondition que se definió en el módulo de administración:


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

Para acceder a este método, se deben definir algunas cosas en la definición de formulario en el módulo de administración.

En primer lugar, se agrega un espacio de nombres que apunta al espacio de nombres para el código subyacente del formulario a la definición del formulario. En este ejemplo, el espacio de nombres es SMFormsDemo:

xmlns:local="clr-namespace:SMFormsDemo"  

A continuación, se debe definir un objectDataProvider para proporcionar los valores del cuadro combinado que muestra el estado del proyector. Este objectDataProvider se define como un recurso:


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

Este proveedor de datos especifica el objeto y el nombre del método que recupera los valores de enumeración del módulo de administración.

Por último, para enlazar el cuadro combinado a los valores de enumeración definidos en el módulo de administración, se agrega un atributo ItemsSource a la definición del cuadro combinado. Este atributo especifica dónde recuperar los valores de enumeración, por ejemplo:

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

A continuación, los elementos SelectedItem y ItemTemplate se agregan a la definición del lenguaje de marcado de aplicación extensible (XAML) del control de cuadro combinado. En el ejemplo siguiente se muestra la definición del cuadro combinado con el XAML de enlace incluido:


<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>  

Sección Categoría

La sección Categoría de un módulo de administración agrupa los elementos del módulo de administración para facilitar la navegación.

Los dos <Category> primeros elementos del ejemplo se usan para controlar la visualización de las tareas Nuevo y Editar en la vista Proyectores .

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

Los dos segundos elementos Category del módulo de administración de ejemplo se usan para hacer que la enumeración de condición del proyector aparezca en la vista Listas del panel Creación de la consola de Service Manager. Esto permite al usuario personalizar los valores:

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

Al agregar esta categoría en el ejemplo siguiente, la tarea Editar aparece en la vista Listas para enumerationValue que apunta en el atributo Target:

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

Sección Presentación

La sección Presentación de un módulo de administración declara y define elementos relacionados con la interfaz de usuario. Entre ellas se incluyen declaraciones de formularios, categorías y tareas de consola.

Sección Formularios

La sección Formularios declara los formularios que usa el módulo de administración. En el ejemplo siguiente se especifica dónde buscar el formulario definido para mostrar y editar instancias de la clase Proyector . Esto enlaza el formulario a la clase Proyector definida en el módulo de administración:


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

Los atributos siguientes se usan en el ejemplo anterior:

  • El atributo TypeName contiene el espacio de nombres y el nombre de clase del formulario.

  • El atributo ID contiene el identificador único de esta instancia de formulario.

  • El atributo Target contiene el nombre de la clase a la que está enlazado este formulario.

  • El atributo Assembly apunta al recurso externo que contiene el formulario.

  • El atributo Accessibility define si este formulario se puede personalizar.

Definición de una vista

La sección Vistas de un módulo de administración contiene definiciones de vistas de interfaz de usuario (UI). Estas vistas se pueden usar para filtrar y mostrar objetos en un módulo de administración.

<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>  

El atributo View Target apunta a la clase que se usará para mostrar la vista.

En el ejemplo anterior, se hace referencia al módulo de administración de la consola de Service Manager. Este módulo de administración contiene una definición de un tipo de vista que se está usando. En este caso, el SMConsole! Se define el tipo de vista GridViewType .

AdvancedListSupportClass define una serie de parámetros, el más importante de los cuales es el parámetro TargetClass. Establezca este parámetro en el identificador de ClassType que aparecerá en esta vista. Para mostrar las columnas que son propiedades de ClassType, use el elemento Column y conéctelo al atributo PropertyID .

El atributo IsRecurring del elemento ListSupportClass determina si la vista se actualiza automáticamente. El atributo RecurrenceFrequency define el intervalo de actualización en milisegundos. En este ejemplo, el intervalo de actualización se establece en 1 segundo, pero no se recomienda para las instalaciones de producción.

Definición de carpetas

Definir una carpeta determina la ubicación en el árbol de navegación en el que se muestra la vista. En este ejemplo, se define un elemento de configuración para que solo sea adecuado colocar la vista en la carpeta existente para los elementos de configuración en el área de trabajo Elementos de configuración:

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

En el ejemplo anterior, el atributo ElementID contiene una referencia a la vista que se creó. El atributo Folder apunta a una carpeta Folders.Projectors , que a su vez tiene su raíz tal como se define en el área de trabajo Administración de configuración de la consola de Service Manager. Esta carpeta raíz se define en el módulo de administración de administración de configuración.

El elemento ImageReference asigna la vista que se creó anteriormente a un icono definido en el espacio de nombres de Configuration Management :

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

Localización mediante la sección LanguagePacks

La sección LanaguagePacks de un módulo de administración define los recursos de cadena y las asignaciones para los elementos del módulo de administración.

En el ejemplo, la enumeraciónValueProjectorCondition.Working debe aparecer como Working. Para ello, se deben definir los nombres para mostrar de cada uno de los siguientes elementos:

  • Vista: Todos los proyectores

  • Enumeraciones: working, broken, in repair, new

  <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>  

Puede crear elementos LanguagePack adicionales, según sea necesario, para cada idioma adicional que necesite. La cadena de visualización correcta aparece al usuario en función de la configuración regional del usuario.

Recursos

La sección Recursos de un módulo de administración contiene referencias a recursos binarios, que se encuentran en ensamblados independientes del módulo de administración. En el ejemplo siguiente, se define un recurso que apunta al ensamblado que contiene el formulario que usa la clase Proyector :

<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" />  

Extensiones de clase

Una extensión de clase es una clase que agrega propiedades a una clase existente. En la mayoría de los casos, esta clase existente se encuentra en un módulo de administración sellado. En los casos en los que la clase existente no se encuentra en un módulo de administración sellado, la extensión de clase debe estar incluida en el mismo módulo de administración que la clase que se va a extender.

Una extensión de clase hereda las propiedades de cualquier clase primaria, por ejemplo:

  • La clase A tiene una propiedad denominada Property1

  • La clase B deriva de, o extiende, la clase A y, por tanto, tiene una propiedad denominada Property1. Esta propiedad se hereda de la clase A, la clase primaria o base)

  • La definición de la clase B agrega una propiedad denominada Property2.

  • Cualquier extensión de clase que derive de la clase B heredará Property1 y Property2.

    En el ejemplo siguiente se muestra una definición de extensión de clase:


<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>  

Esta extensión de clase extiende la clase System.WorkItem.Incident y agrega una nueva propiedad denominada TimeOnIncident.

La definición de una extensión de clase es similar a la de una definición de clase. Se usan dos atributos del elemento ClassType para definir una definición de clase: el atributo Base y el atributo IsExtensionType .

El atributo Base especifica el identificador de la clase primaria de la que deriva la extensión de clase. En este caso, el valor del atributo se establece en Incident! System.WorkItem.Incident. Este valor contiene el alias del nombre completo del módulo de administración, que contiene la clase que se extiende, un signo de exclamación y, a continuación, el nombre de la clase base. Para obtener más información, vea el ejemplo siguiente.

El atributo IsExtensionType define si esta clase es una extensión de la clase base. Dado que TimeOnIncident es una extensión de la clase Incident , esta propiedad se establece en true:

IsExtensionType="true"  

La otra opción es false, lo que indica que no es una extensión de otra clase, sino una nueva clase que hereda de la base. El valor predeterminado es false; por lo tanto, este atributo no tiene que usarse si la clase no es una extensión.

Ejemplo completo

En el ejemplo de código siguiente se muestra el módulo de administración completo que contiene la extensión de clase .

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>  

Importación de un módulo de administración mediante un cmdlet

Puede usar el cmdlet Import-SCSMManagementPack de Windows PowerShell para importar un módulo de administración de Service Manager, por ejemplo:

Import-SCSMManagementPack MyServiceManager.ManagementPack.xml  

En este documento no se describe cómo importar y usar módulos de administración en la consola de Service Manager. Para obtener información sobre el uso de módulos de administración en la consola de Service Manager, consulte Uso de módulos de administración en Service Manager.

Ejemplo de módulo de administración completo

Los ejemplos de código siguientes representan el módulo de administración de ejemplo completo que se usa para ejemplos de este artículo, además de la definición del formulario y el código subyacente de C# para el formulario.

Módulo de administración

<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>  

Definición de formulario


<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>  

Código subyacente del formulario


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);  
      }  
   }  
}  

Pasos siguientes