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 Service Manager Authoring Tool no sean suficientes y que tengas 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 proporcionan información general e instrucciones que pueden ayudarte 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 binario, enumerador e incremento automático.
Además, puedes definir restricciones en determinados valores de propiedad. Por ejemplo, puedes 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 sección <PresentationTypes>
del módulo de administración ya no contiene las etiquetas <Images>
, <Image>
o <ImageData>
. En su lugar, usa 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 puedes 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 enum 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, puedes 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 mediante una lista.
Importante
Cualquier valor maxCardinality definido como mayor que 1 se procesa como ilimitado.
Si agregas un nuevo tipo de relación desde tu 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 Lobby puede tener varios tipos 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 de combinación
Las clases de combinación 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 de combinación 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 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. Puedes 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.
Puedes especificar tu 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 del 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 uses valores no alfanuméricos, como '.', en el 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 por sección de lo que contiene la definición de tipo.
La 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 cual se 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 falso:
Hosted="false"
Si se establece el atributo Hosted en verdadero, quiere decir 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 quieras permitir que otros usuarios creen una versión más específica de la clase, establece este atributo en public, 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 solo como clase primaria para otras clases de las que derivar. En este ejemplo, este atributo 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 siguientes atributos:
El atributo Id., que designa el identificador único de la propiedad.
El atributo Type, que indica el tipo de datos de la propiedad.
El 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 enum 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.
Accessibility especifica si este enumerador puede contener otros enumeradores.
ParentName es un atributo que especifica el Id. 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 Projector 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, agrega una etiqueta Binding Path a la propiedad Text del control 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 Projector 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, usa el método GetEnumerations del módulo de administración actual. A esta instancia se accede 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 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>
La sección de 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 primeros elementos <Category>
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 Categoría 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 a la que se apunta en el atributo Target:
<Category ID="Projector.ProjectorConditionCategory" Target="ProjectorCondition" Value="Authoring!Microsoft.EnterpriseManagement.ServiceManager.UI.Authoring.EnumerationViewTasks"/>
La sección de 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.
La sección de formularios
La sección Formularios declara los formularios que usa tu 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>
En el siguiente ejemplo, se usan los siguientes atributos.
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.
Definir una vista
La sección Vistas de un módulo de administración contiene definiciones de vistas de la 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 del tipo de vista que se está usando. En este caso, se define el tipo de vista SMConsole!GridViewType.
AdvancedListSupportClass define una serie de parámetros, el más importante de los cuales es el parámetro TargetClass. Establece este parámetro en el ID de ClassType que aparecerá en esta vista. Para mostrar las columnas que son propiedades de ClassType, usa el elemento Column y enlázalo 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.
Definir 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 del espacio 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 espacio 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 la 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 Administración de configuración:
<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, EnumerationValueProjectorCondition.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>
Puedes crear elementos LanguagePack adicionales, según sea necesario, para cada idioma adicional que necesites. 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. La propiedad se hereda de la clase A, la primaria o la 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 después el nombre de la clase base. Para más información, consulta el siguiente ejemplo.
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>
Importar un paquete de datos mediante un cmdlet
Puedes 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, consulta 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);
}
}
}