Definir, invalidar y usar propiedades de control de LightSwitch

Los controles de LightSwitch tienen propiedades cuyos valores se pueden establecer en tiempo de diseño o en tiempo de ejecución a través del proxy devuelto por una llamada al método de extensión FindControl. Algunas propiedades se definen en RootControl, el control integrado que cada control hereda implícitamente como control base de nivel superior y, por tanto, todos los controles las heredan e integran. Los controles pueden definir sus propiedades, pueden invalidar determinados atributos de las propiedades integradas y también pueden establecer propiedades en valores concretos para sí mismos o para sus elementos secundarios.

LightSwitch contiene un sistema de resolución de propiedades que funciona en tiempo de diseño y también en tiempo de ejecución. Este sistema permite que la hoja de propiedades del Diseñador de pantallas tenga en cuenta el valor predeterminado de una propiedad en distintos puntos del árbol de contenido y que muestre dichos valores tal y como aparecerán en tiempo de ejecución.

Los controles pueden manipular el valor predeterminado de una propiedad para proporcionar una mejor experiencia predeterminada. Por ejemplo, la pantalla establece la posición de etiqueta predeterminada, AttachedLabelPosition, en Left-aligned. AttachedLabelPosition es una propiedad heredable. Por consiguiente, su valor se propagará automáticamente a todos sus elementos secundarios y a los elementos secundarios de estos hasta que un control invalide el valor predeterminado de esa propiedad o el desarrollador haya cambiado el valor de una propiedad en un elemento de contenido.

Por ejemplo, es habitual que los valores incluidos en una lista no muestren etiquetas. Por consiguiente, el control List cambia la posición de etiqueta predeterminada a None para todos sus descendientes. También cambia la posición de etiqueta predeterminada a Collapsed para sí mismo. El desarrollador puede cambiar uno o más de estos valores predeterminados en el Diseñador de pantallas o en tiempo de ejecución; el valor cambiado se heredará a través del árbol de contenido hasta que otro control especifique otro valor predeterminado o el desarrollador cambie su valor.

Las propiedades de los controles se almacenan en la colección Properties del nodo del elemento de contenido, IContentItem.Properties. Si la propiedad fuera válida en la instancia determinada del elemento de contenido, esta tendrá una entrada en la colección de propiedades. De lo contrario, no la tendrá. Así, si una propiedad puede establecerse en un elemento de contenido al estar definida en el control o en uno de sus antecesores, o si la propiedad se define en RootControl, o la propiedad se puede asociar, IContentItem.Properties contendrá una entrada para la propiedad en cuestión. De lo contrario, Properties.TryGetValue devolverá False. Si el valor no se ha establecido realmente, la acción Properties.TryGetValue se realizará correctamente, pero la colección devolverá Null para su valor.

Definir una nueva propiedad de control

Un control de LightSwitch define una nueva propiedad de control en el archivo de metadatos .lsml de la solución mediante el elemento ControlProperty. En el ejemplo siguiente se define una propiedad denominada ShowButton en un control denominado MyControl.

<Control Name="MyControl" ... >
    ...
    <Control.Properties>
      <ControlProperty 
Name="ShowButton"
PropertyType=":Boolean"
CategoryName="Appearance"
              EditorVisibility="PropertySheet">
        <ControlProperty.Attributes>
          <DisplayName Value="Show Button" />
          <Description Value="Determines whether the button is shown." />
        </ControlProperty.Attributes>
        <ControlProperty.DefaultValueSource>
          <ScreenExpressionTree>
            <ConstantExpression ResultType=":Boolean" Value="True"/>
          </ScreenExpressionTree>
        </ControlProperty.DefaultValueSource>
      </ControlProperty>
    </Control.Properties>
  </Control>

A continuación se indican los atributos disponibles para ControlProperty:

  • PropertyType (Obligatorio): el tipo de la propiedad. Solo se admiten IDataTypes simples como, por ejemplo, “:Int32”, ”:String”, etc. Los datos de propiedad complejos pueden almacenarse como cadena y mostrarse mediante un editor de propiedades personalizado.

  • IsAttachable: si es True, la propiedad se puede establecer en un elemento de contenido cuyo control no la define.

  • IsInheritable: si es True, los descendientes que aparecen en el árbol de contenido heredan automáticamente el valor de la propiedad hasta que se invalide.

    Nota

    Una propiedad heredable también se debe poder asociar; de lo contrario, no será válida en los posibles elementos secundarios que la hereden.

  • CategoryName: especifica el nombre de la categoría en la que se va a agrupar la propiedad cuando se muestra en la ventana Propiedades del Diseñador de pantallas. Las opciones disponibles actualmente es un valor vacío o Default, Validation, Appearance y Sizing.

  • UIEditorId: especifica el editor de la hoja de propiedades que se va a usar: integrado o personalizado. Si no se especifica, se usará un editor predeterminado según el tipo de propiedad.

  • EditorVisibility: indica cómo se trata la propiedad en tiempo de diseño.

    • NotDisplayed (predeterminado): esta propiedad no se muestra en la hoja de propiedades.

    • PropertySheet: se muestra en la hoja de propiedades mediante el editor de hoja de propiedades especificado (o predeterminado).

  • AttachedPropertyAvailability: indica la disponibilidad de una propiedad asociada. Se omite si la propiedad no se puede asociar.

    • Default: la propiedad asociada está disponible para todos los elementos de contenido del árbol.

    • ImmediateChildren: la propiedad asociada está disponible solo para los elementos de contenido secundarios inmediatos de un control en el árbol de contenido.

  • DefaultValueSource: una expresión que debe ser constante que proporciona el valor predeterminado de esta propiedad.

  • IsReadOnly: si es True, especifica que el desarrollador no puede cambiar el valor.

Hh304431.collapse_all(es-es,VS.140).gifAdministrar las propiedades de los pares de controles de editor y visor

Un patrón habitual consiste en tener dos versiones de un control: una que permita la edición de datos (“editor”) y otra que solo muestre datos (“visor”). Algunos ejemplos son AddressEditor/AddressViewer y TextBox/Label. La implementación de pares de controles se cubre en la sección sobre cómo proporcionar un control de editor y de visor, en el tema Conceptos adicionales sobre el control LightSwitch.

Reemplazar propiedades

Todos los controles descendientes heredan las definiciones de propiedad de un control. Un control puede invalidar ciertos atributos de las propiedades heredadas mediante el elemento PropertyOverride.

Por ejemplo, todos los controles heredan la propiedad VerticalAlignment de RootControl. En el ejemplo siguiente se muestra cómo un control puede también invalidar el valor predeterminado de VerticalAlignment cuando se usa en dicho control o en un control derivado de este.

<Control Name="MyControl" ... >
    ...
    <Control.PropertyOverrides>
      <ControlPropertyOverride
          Property=":RootControl/Properties[VerticalAlignment]">
        <ControlPropertyOverride.DefaultValueSource>
          <ScreenExpressionTree>
            <ConstantExpression ResultType=":String" Value="Top"/>
          </ScreenExpressionTree>
        </ControlPropertyOverride.DefaultValueSource>
      </ControlPropertyOverride>
    </Control.PropertyOverrides>
  </Control>

A continuación se indican los atributos disponibles en ControlPropertyOverride:

  • Property (obligatorio): especifica el identificador completo de la propiedad que se va a invalidar.

  • DefaultValueSource: un valor predeterminado invalidado.

  • UIEditorId: un identificador de editor invalidado.

  • IsReadOnly: un valor invalidado para la propiedad IsReadOnly.

Compatibilidad con las propiedades comunes integradas en un control de extensión

LightSwitch define un conjunto de propiedades que suelen ser útiles en RootControl. LightSwitch admite automáticamente algunas propiedades, que aparecen de forma automática en la hoja de propiedades de los nuevos controles. LightSwitch también controla generalmente la funcionalidad de estas propiedades de forma automática. Por consiguiente, el control no tiene que hacer nada para admitir las propiedades, aunque es posible que este pueda establecer determinadas opciones. Para ocultar las propiedades de la hoja de propiedades de un control, establezca EditorVisibility en NotDisplayed.

Las propiedades que requieren que el control realice alguna acción (un enlace en XAML, por ejemplo) se ocultan de forma predeterminada de la hoja de propiedades. Para admitirlas, un control de extensión debe implementar el comportamiento necesario y también invalidar EditorVisibility para PropertySheet. En las secciones siguientes se abordan las propiedades comunes y cómo admitir cada una de ellas desde el control.

Hh304431.collapse_all(es-es,VS.140).gifPropiedades de los controles de cancelación (mostradas de forma predeterminada)

Las propiedades de cancelación están habilitadas en la hoja de propiedades de forma predeterminada y también tienen el comportamiento automático proporcionado por LightSwitch para el control.

  • AttachedLabelPosition (heredable): LightSwitch mostrará automáticamente una etiqueta para un control de extensión con la configuración predeterminada. Puede ser preferible que algunos controles, por ejemplo, los controles Button, muestren sus propias etiquetas adjuntas. En ese caso, establezca el atributo AttachedLabelSupport del control en DisplayedByControl, como se indica a continuación.

    <Control Name="MyCheckBox"
               AttachedLabelSupport="DisplayedByControl"
        ... />
    

    Puede que también desee ocultar la propiedad AttachedLabelPositioninvalidando EditorVisibility. Sin embargo, invalidar simplemente EditorVisibility como NotDisplayed no es suficiente, porque incluso aunque la propiedad no se muestre en la hoja de propiedades, su valor se sigue heredando del elemento primario y LightSwitch mostrará una etiqueta adecuada automáticamente si AttachedLabelSupport se deja como DisplayedByContainer de forma predeterminada.

  • Propiedades de tamaño comunes:

    • HeightSizingMode

    • WidthSizingMode

    • MinHeight

    • MaxHeight

    • MinWidth

    • MaxWidth

    • Height

    • Width

    Todas estas propiedades se muestran en un único editor asociado a la propiedad HeightSizingMode. Para la mayoría de los casos, recomendamos que se dejen habilitadas en la hoja de propiedades por motivos de coherencia, ya que LightSwitch controla automáticamente el tamaño de los controles de forma general.

    Si, por algún motivo, un control debe ocultar estas propiedades, debe invalidar el atributo EditorVisibility para HeightSizingMode como NotDisplayed, como se indica a continuación.

    <!--Hide all of the common sizing properties by hiding HeightSizingMode-->  
          <ControlPropertyOverride Property=":RootControl/Properties[HeightSizingMode]"
                                   EditorVisibility="NotDisplayed">
    
  • Rows y Characters

    Estas no son en realidad propiedades comunes. Sin embargo, si el control define aquellas de sus propiedades que usan estos nombres, el editor de propiedades de tamaño comunes también las mostrará. El atributo EditorVisibility debe establecerse en NotDisplayed para que LightSwitch no muestre un editor adicional para ellas. Por ejemplo:

    <Control Name="MyTextBox" ... >
        ...
        <Control.Properties>
          <ControlProperty Name="Lines"
                           PropertyType=":Int32"
                           CategoryName="Sizing"
                           EditorVisibility="NotDisplayed">
            <ControlProperty.Attributes>
              <DisplayName Value="$(MyTextBox_Lines_DisplayName)" />
              <Description Value="$(MyTextBox_Lines_Description)" />
            </ControlProperty.Attributes>
            <ControlProperty.DefaultValueSource>
              <ScreenExpressionTree>
                <ConstantExpression ResultType=":Int32" Value="1"/>
              </ScreenExpressionTree>
            </ControlProperty.DefaultValueSource>
          </ControlProperty>
    
          <ControlProperty Name="Characters"
                           PropertyType=":Int32"
                           CategoryName="Sizing"
                           EditorVisibility="NotDisplayed">
            <ControlProperty.Attributes>
              <DisplayName Value="$(TextBox_Characters_DisplayName)" />
            </ControlProperty.Attributes>
            <ControlProperty.DefaultValueSource>
              <ScreenExpressionTree>
                <ConstantExpression ResultType=":Int32" Value="1"/>
              </ScreenExpressionTree>
            </ControlProperty.DefaultValueSource>
          </ControlProperty>      
    
        </Control.Properties>
    
  • Propiedades de alineación comunes:

    • HorizontalAlignment

    • VerticalAlignment

    Ambas propiedades se muestran a través de un único editor asociado a la propiedad VerticalAlignment. Para ocultarlas, si bien no suele ser recomendable, invalide el atributo EditorVisibility de VerticalAlignment como NotDisplayed.

    De forma similar a Rows y Characters, si un control de extensión define aquellas de sus propiedades que usan los nombres WeightedRowHeight y WeightedRowWidth, estas también se mostrarán a través del mismo editor.

Hh304431.collapse_all(es-es,VS.140).gifPropiedades de los controles de opción

Las propiedades de opción se ocultan en la hoja de propiedades de forma predeterminada, ya sea porque LightSwitch no puede proporcionar su comportamiento para un control automáticamente o porque no todos los controles desean usar esta funcionalidad. Las propiedades de opción se pueden invalidar para mostrarse en la hoja de propiedades, pero puede que se requiera trabajo adicional por parte del control para que la propiedad tenga el efecto deseado.

  • ShowAsLink

    Para admitir esta propiedad, primero invalide EditorVisibility="PropertySheet" en los metadatos del control:

    <Control.PropertyOverrides>
          <!-- Support Show As Link property -->
          <ControlPropertyOverride
            Property=":RootControl/Properties[ShowAsLink]"
            EditorVisibility="PropertySheet"/>
    </Control.PropertyOverrides>
    

    Use el control de marco de presentación integrado LinkableLabel (Microsoft.LightSwitch.Presentation.Framework.LinkableLabel) en el árbol visual del control para tener el comportamiento automático de una etiqueta o hipervínculo como con Label. O bien, use su propia interfaz de usuario y utilice las funciones de la clase auxiliar ShowAsLinkPropertyHelper (Microsoft.LightSwitch.Presentation.Framework.Helpers.ShowAsLinkPropertyHelper) para implementar esta funcionalidad.

  • FontStyle (heredable)

    Para admitir FontStyle, recomendado únicamente para controles de solo lectura como Label, solo tiene que invalidar su EditorVisibility para PropertySheet y LightSwitch controlará automáticamente su funcionalidad.

  • TextAlignment

    Para admitir TextAlignment, un control debe invalidar EditorVisibility y también proporcionar su propia implementación, como se indica a continuación.

    <TextBox
           Text="{Binding StringValue, Mode=TwoWay}"
           TextAlignment="{Binding Properties[MyControlExtension:MyControl/TextAlignment]}"
           IsReadOnly="{Binding IsReadOnly}"
           AutomationProperties.AutomationId="{Binding Name, StringFormat=Control: \{0\}}"
           AutomationProperties.Name="{Binding DisplayName}"
           AutomationProperties.HelpText="{Binding Description}"
           ToolTipService.ToolTip="{Binding Description}"
       />
    
  • BrowseOnly (heredable)

    Esta propiedad corresponde a la propiedad Usar controles de solo lectura de la hoja de propiedades. Para admitirla, recomendado únicamente para controles de grupo y de diseño inteligente, invalide EditorVisibility para PropertySheet y LightSwitch la controlará automáticamente.

  • IsReadOnly (heredable) y IsEnabled (heredable)

    Estas dos propiedades son solo para uso interno y no se deben mostrar en la hoja de propiedades.

  • ContainerState (heredable)

    ContainerState es una propiedad interna que nunca debe mostrarse en la hoja de propiedades. Se usa para permitir que los controles cambien su interfaz de usuario o su comportamiento según el contexto en el árbol. Los únicos valores estándar definidos actualmente son None y Cell. Cell indica que el control se usa dentro de otro control que muestra los elementos como celdas (por ejemplo, DataGrid). Como ejemplo, el control TextBox integrado cambia su apariencia cuando ContainerState es Cell.

    Si crea un control de colección o de grupo y desea que los controles cambien su apariencia de la misma forma que en DataGrid, establezca el valor de esta propiedad en Cell en los elementos secundarios del control, como se indica a continuación.

    <Control.ChildItemPropertySources>
          <!-- Set ContainerState for descendants to "Cell", so they can draw 
               themselves differently inside a DataGrid or similar control -->
          <ControlPropertySource Property=":RootControl/Properties[ContainerState]">
            <ControlPropertySource.Source>
              <ScreenExpressionTree>
                <ConstantExpression ResultType=":String" Value="Cell" />
              </ScreenExpressionTree>
            </ControlPropertySource.Source>
          </ControlPropertySource>
        </Control.ChildItemPropertySources>
    

    Si crea un control que cambia su comportamiento en respuesta a su ContainerState, puede comprobar IContentItem.ContainerState o buscarlo en IContentItem.Properties y responder en el código o en XAML mediante un estado visual.

  • Image

    Para admitir la propiedad Image, un control debe invalidar EditorVisibility para PropertySheet y, a continuación, enlazar su interfaz de usuario a Image. No enlace directamente al valor de la propiedad Image. En su lugar, debe usar la clase auxiliar ImagePropertyHelper en Microsoft.LightSwitch.Presentation.Framework.Helpers para interpretar la configuración de propiedades en IContentItem y recuperar la imagen correcta que se va a mostrar. La clase auxiliar sabe cómo recuperar la imagen y obtener las imágenes predeterminadas correctas para determinados datos enlazados, como métodos de botón.

Hh304431.collapse_all(es-es,VS.140).gifPropiedades con valores enum

Puesto que los tipos de propiedad deben ser tipos IDataType y LightSwitch no admite actualmente el tipo enum, una propiedad cuyo valor se reciba de un valor de propiedad enum conocido debe almacenarse como cadena. El control debe realizar las conversiones necesarias al inspeccionar el valor de la propiedad.

El editor de propiedades predeterminado para las cadenas puede controlar propiedades con valores enum y mostrará un ComboBox con valores si se especifican los atributos SupportedValue y SupportedValuesExclusive. Por ejemplo:

<ControlProperty Name="TextAlignment"
                       PropertyType=":String"
                       CategoryName="Appearance"
                       EditorVisibility="PropertySheet">
        <ControlProperty.Attributes>
          <DisplayName Value="$(MyControl_TextAlignment_DisplayName)" />
          <Description Value="$(MyControl_TextAlignment_Description)" />
          <SupportedValuesExclusive />
          <SupportedValue DisplayName="$(TextAlignment_StandardValues_Left)" 
                          Value="Left" />
          <SupportedValue DisplayName="$(TextAlignment_StandardValues_Right)" 
                          Value="Right" />
          <SupportedValue DisplayName="$(TextAlignment_StandardValues_Center)" 
                          Value="Center" />
        </ControlProperty.Attributes>
        <ControlProperty.DefaultValueSource>
          <ScreenExpressionTree>
            <ConstantExpression ResultType=":String" Value="Left"/>
          </ScreenExpressionTree>
        </ControlProperty.DefaultValueSource>
      </ControlProperty>

Establecer valores de propiedades automáticamente

Los controles pueden establecer valores de propiedades automáticamente tanto para ellos como para sus elementos secundarios directamente a partir de los metadatos. Los controles pueden establecer propiedades en las siguientes ubicaciones:

  • Control.PropertySources: establece valores de propiedades directamente en un control.

  • Control.ChildItemPropertySources: establece valores de propiedades en todos los elementos de contenido secundarios del control.

  • Placeholder.PropertySources: establece valores de propiedades en un elemento de contenido secundario dentro de un marcador de posición de control específico.

En el ejemplo siguiente se muestran estos tres orígenes de propiedades en funcionamiento.

<Control Name="MySmartLayout"
           SupportedContentItemKind="Group">

    <!-- Set property values on the control itself -->
    <Control.PropertySources>
      <!-- Override AttachedLabelPosition on the control itself to Collapsed – 
            this is the label that is shown for the smart layout itself. 
            Note that this value will also be propagated to all children 
            by default because this property is inheritable, except that you are 
            setting a different value for the children below. -->
      <ControlPropertySource Property=":RootControl/Properties[AttachedLabelPosition]">
        <ControlPropertySource.Source>
          <ScreenExpressionTree>
            <ConstantExpression ResultType=":String" Value="Collapsed" />
          </ScreenExpressionTree>
        </ControlPropertySource.Source>
      </ControlPropertySource>

    </Control.PropertySources>

    <!-- Set property values on all direct children in the content tree -->
    <Control.ChildItemPropertySources>
      
      <!-- Set default AttachedLabelPosition to None for all of the children. -->
      <ControlPropertySource Property=":RootControl/Properties[AttachedLabelPosition]">
        <ControlPropertySource.Source>
          <ScreenExpressionTree>
            <ConstantExpression ResultType=":String" Value="None" />
          </ScreenExpressionTree>
        </ControlPropertySource.Source>
      </ControlPropertySource>
      
    </Control.ChildItemPropertySources>

    <!-- Define two placeholders (or “buckets”).  You will set a value for the
         property FontSize in only one of the placeholders. This value will be
         applied to whatever content item is in that placeholder in the content
         tree. -->
    <Control.Placeholders>
      <Placeholder DisplayName="$(MySmartLayout_Title_DisplayName)" 
                   Name="Title">
        <Placeholder.PropertySources>
          <ControlPropertySource Property=":RootControl/Properties[FontStyle]">
            <ControlPropertySource.Source>
              <ScreenExpressionTree>
                <ConstantExpression ResultType=":String" Value="Heading1" />
              </ScreenExpressionTree>
            </ControlPropertySource.Source>
          </ControlPropertySource>
        </Placeholder.PropertySources>
      </Placeholder>
      <Placeholder DisplayName="$(MySmartLayout_Description_DisplayName)" 
                   Name="Description" />
    </Control.Placeholders>

    ...
  </Control>

Como regla general, no hay ninguna diferencia real entre la invalidación del valor predeterminado de una propiedad de control y el establecimiento de un valor de propiedad en el propio control mediante Control.PropertySources. Sin embargo, no puede decirse lo mismo para Placerholder.PropertySources y Control.ChildItemPropertySources, ya que los valores no se propagan.

Evaluación de propiedades

El valor de una propiedad para un elemento de contenido concreto puede proceder de varios orígenes. A continuación se muestra el orden de evaluación de estos orígenes, desde la propiedad más baja a la más alta:

  1. Valor predeterminado especificado en una propiedad ControlProperty definida en el control del elemento de contenido o heredada por este.

  2. Valor heredado del valor vigente del elemento primario de esta propiedad, si es heredable.

  3. Valor predeterminado invalidado mediante ControlPropertyOverride.

  4. Valor especificado en PropertySources del control.

  5. Valor especificado en ChildItemPropertySources del control primario.

  6. Valor especificado en PropertySources del marcador de posición del control primario, si el valor se especifica en un marcador de posición.

  7. Valor establecido por el desarrollador en tiempo de diseño, ContentItem.PropertySources.

  8. Valor establecido por el desarrollador en tiempo de ejecución con FindControl().

  9. Estado determinado por el elemento de contenido en tiempo de ejecución y que puede cambiar; para propiedades como IsReadOnly e IsEnabled, invalidar un método IsReadOnly de la propiedad del elemento de tabla, y así sucesivamente.

  10. Estado del esquema de los datos enlazados, como tablas de solo lectura, campos calculados, etc.

Los seis primeros elementos son valores predeterminados o valores establecidos en metadatos, los elementos siete y ocho son valores establecidos por el desarrollador de LightSwitch y los elementos nueve y diez son valores determinados por el estado de enlace de datos.

Acceso a los valores de las propiedades

Enlazar a los valores de propiedades desde XAML

Para tener acceso a los valores de las propiedades desde la colección Properties de un elemento de contenido, use el nombre completo de la propiedad. Para evitar la ambigüedad, se puede usar el diccionario de propiedades para ver los nombres completos de estas. Debido a las limitaciones de la notación de enlaces XAML, no se pueden usar identificadores de propiedad estándar como “:RootControl/Properties[AttachedLabelPosition]”. Por consiguiente, se usa una notación alternativa para claves en la colección Properties: Microsoft.LightSwitch:RootControl/AttachedLabelPosition. Asimismo, observe que el acceso directo “:” para “Microsoft.LightSwitch” no se puede usar aquí. En el ejemplo siguiente se muestra la sintaxis.

TextAlignment="{Binding Properties[Microsoft.LightSwitch:RootControl/TextAlignment]}"

Acceso a los valores de las propiedades desde el código

También se puede tener acceso a los valores de las propiedades desde el código. En este caso, sigue siendo necesario el nombre completo de la propiedad. En el siguiente ejemplo se muestra cómo tener acceso al valor de una propiedad.

Friend NotInheritable Class MyContentItemExtensions
    Private Sub New()
    End Sub

    <System.Runtime.CompilerServices.Extension> _
    Public Shared Function TryGetPropertyValue(Of T)(contentItem As IContentItem, qualifiedPropertyName As String, ByRef value As T) As Boolean
        Dim objValue As Object
        If contentItem.Properties.TryGetValue(qualifiedPropertyName, objValue) AndAlso objValue IsNot Nothing Then
            If GetType(T).IsEnum Then
                Try
                    Dim objectEnumValue As Object = [Enum].Parse(GetType(T), DirectCast(objValue, String))
                    value = DirectCast(objectEnumValue, T)
                    Return True
                Catch generatedExceptionName As ArgumentException
                End Try
            Else
                value = DirectCast(objValue, T)
                Return True
            End If
        End If

        value = Nothing
        Return False
    End Function

    <System.Runtime.CompilerServices.Extension> _
    Public Shared Function GetPropertyValueOrDefault(Of T)(contentItem As IContentItem, qualifiedPropertyName As String, Optional defaultValue As T = Nothing) As T
        Dim result As T
        If contentItem.TryGetPropertyValue(Of T)(qualifiedPropertyName, result) Then
            Return result
        Else
            Return defaultValue
        End If
    End Function
End Class
internal static class MyContentItemExtensions
{
        public static bool TryGetPropertyValue<T>(this IContentItem contentItem, string qualifiedPropertyName, out T value)
        {
            object objValue;
            if (contentItem.Properties.TryGetValue(qualifiedPropertyName, out objValue) && objValue != null)
            {
                if (typeof(T).IsEnum)
                {
                    try
                    {
                        object objectEnumValue = Enum.Parse(typeof(T), (string)objValue), false;
                        value = (T)objectEnumValue;
                        return true;
                    }
                    catch (ArgumentException)
                    {
                    }
                }
                else
                {
                    value = (T)objValue;
                    return true;
                }
            }

            value = default(T);
            return false;
        }

        public static T GetPropertyValueOrDefault<T>(this IContentItem contentItem, string qualifiedPropertyName, T defaultValue = default(T))
        {
            T result;
            if (contentItem.TryGetPropertyValue<T>(qualifiedPropertyName, out result))
                return result;
            else
                return defaultValue;
        }
}

Controlar los cambios de las propiedades

Al tener acceso a los valores de las propiedades desde el código, debe controlar correctamente los cambios de las propiedades mediante el evento IContentItem.PropertyChanged; este desencadena un evento para “Propiedades” y también para el nombre completo de la propiedad de forma específica. Esto es importante para todas las propiedades, ya que el desarrollador puede cambiar los valores de las propiedades en tiempo de ejecución con FindControl() o a través de la opción de personalización de pantalla del Diseñador de pantallas en tiempo de ejecución. En general, si un control administra correctamente los cambios de las propiedades en el Diseñador de pantallas en tiempo de ejecución, administrará correctamente el caso FindControl().

Vea también

Tareas

Cómo: Crear un control LightSwitch

Tutorial: Crear una extensión de control de valor

Tutorial: Crear una extensión de control de detalle

Tutorial: Crear una extensión de control de diseño inteligente

Tutorial: Crear una extensión de control de panel de apilamiento

Conceptos

LightSwitch Extensibility Toolkit para Visual Studio 2013