Compartir a través de


Información general sobre las propiedades de dependencia

Actualización: noviembre 2007

Windows Presentation Foundation (WPF) proporciona un conjunto de servicios que se pueden utilizar para extender la funcionalidad de una propiedad de common language runtime (CLR). Colectivamente, estos servicios se conocen como el sistema de propiedades de WPF. Una propiedad que está respaldada por el sistema de propiedades de WPF se conoce como una propiedad de dependencia. Esta información general describe el sistema de propiedades de WPF y las funciones de una propiedad de dependencia. Esto incluye cómo utilizar propiedades de dependencia existentes en Lenguaje de marcado de aplicaciones extensible (XAML) y en código. Esta información general también presenta aspectos especializados de las propiedades de dependencia, tales como los metadatos de propiedades de dependencia y cómo crear una propiedad de dependencia propia en una clase personalizada.

Este tema contiene las secciones siguientes.

  • Requisitos previos
  • Propiedades de dependencia y propiedades de CLR
  • Propiedades CLR de respaldo de propiedades de dependencia
  • Establecer valores de propiedad
  • Funcionalidad de propiedad proporcionada por una propiedad de dependencia
  • Prioridad de los valores de propiedades de dependencia
  • Más información sobre propiedades de dependencia
  • Temas relacionados

Requisitos previos

En este tema se asume que tiene conocimientos básicos sobre CLR y sobre programación orientada a objetos. Para seguir los ejemplos de este tema, también debe entender XAML y debe saber escribir aplicaciones de WPF. Para obtener más información, consulte Información general sobre Windows Presentation Foundation.

Propiedades de dependencia y propiedades de CLR

En WPF, las propiedades se exponen normalmente como propiedades common language runtime (CLR). En un nivel básico, podría interactuar directamente con estas propiedades y nunca sabría que se implementan como una propiedad de dependencia. Sin embargo, es recomendable conocer algunas o todas las características del sistema de propiedades de WPF, para poder aprovecha estas características.

El propósito de las propiedades de dependencia es proporcionar una manera de calcular el valor de una propiedad en función del valor de otras entradas. Estas otras entradas pueden incluir propiedades del sistema tales como temas y preferencias del usuario, mecanismos de determinación de propiedad Just-In-Time tales como el enlace de datos y las animaciones o guiones gráficos, plantillas del uso múltiple tales como recursos y estilos, o valores conocidos a través de relaciones de elementos primarios-secundarios con otros elementos del árbol de elementos. Además, una propiedad de dependencia se puede implementar para que proporcione validación autónoma, valores predeterminados, devoluciones de llamada que supervisen los cambios de otras propiedades y un sistema que pueda forzar valores de la propiedad en función de información que puede estar disponible en tiempo de ejecución. Las clases derivadas también pueden cambiar algunas características concretas de una propiedad existente invalidando metadatos de propiedades de dependencia, en lugar de reemplazar la implementación real de propiedades existentes o crear propiedades nuevas.

En la referencia de SDK, puede identificar qué propiedad es una propiedad de dependencia por la presencia de la sección de Información de propiedad de dependencia en la página de referencia administrada para esa propiedad. La sección de Información de propiedad de dependencia incluye un vínculo al campo identificador de DependencyProperty para esa propiedad de dependencia y también incluye una lista de las opciones de metadatos establecidas para esa propiedad, información de invalidación por clases y otros detalles.

Propiedades CLR de respaldo de propiedades de dependencia

Las propiedades de dependencia y el sistema de propiedades de WPF extienden la funcionalidad de propiedad proporcionando un tipo que respalda una propiedad, como implementación alternativa al modelo estándar de respaldar la propiedad con un campo privado. El nombre de este tipo es DependencyProperty. El otro tipo importante que define el sistema de propiedades de WPF es DependencyObject.DependencyObject define la clase base que puede registrar y poseer una propiedad de dependencia.

A continuación se ofrece un resumen de la terminología que se utiliza en esta documentación de kit de desarrollo de software (SDK) cuando se tratan las propiedades de dependencia:

  • Propiedad de dependencia: una propiedad respaldada por un objeto DependencyProperty.

  • Identificador de propiedad de dependencia: una instancia de DependencyProperty, que se obtiene como valor de retorno al registrar una propiedad de dependencia y, a continuación, se almacena como miembro de una clase. Este identificador se utiliza como parámetro en muchas de las API que interactúan con el sistema de propiedades de WPF.

  • ""Contenedor" CLR: implementaciones reales de lectura y escritura de la propiedad. Estas implementaciones incorporan el identificador de propiedad de dependencia utilizándolo en las llamadas a GetValue y SetValue, proporcionando así el respaldo para la propiedad utilizando el sistema de propiedades de WPF.

En el ejemplo siguiente se muestra la propiedad propiedad de dependencia IsSpinning y se muestra la relación del identificador DependencyProperty con la propiedad a la que respalda.

public static readonly DependencyProperty IsSpinningProperty = 
    DependencyProperty.Register(


...


    );
public bool IsSpinning
{
    get { return (bool)GetValue(IsSpinningProperty); }
    set { SetValue(IsSpinningProperty, value); }
}

La convención de nomenclatura de la propiedad y su campo de respaldo DependencyProperty es importante. El nombre del campo siempre es el nombre de la propiedad, con el sufijo Property. Para obtener más información sobre esta convención y sus razones, vea Propiedades de dependencia personalizadas.

Establecer valores de propiedad

Puede establecer propiedades en código o en XAML.

Establecer valores de propiedad en XAML

En el siguiente ejemplo de XAML se especifica como valor de fondo para un botón el rojo. En este ejemplo se muestra un caso donde el valor de cadena simple para un atributo XAML convierte su tipo, mediante el cargador XAML, en un tipo WPF (un Color, mediante un SolidColorBrush) en el código generado .

<Button Background="Red" Content="Button!"/>

XAML admite diversas formas de sintaxis para establecer propiedades. La sintaxis a utilizar para una propiedad determinada dependerá del tipo de valor que utilice una propiedad, así como de otros factores tales como la presencia de un convertidor de tipos. Para obtener más información sobre la sintaxis XAML para establecer propiedades, vea Información general sobre XAML y Terminología de la sintaxis de XAML.

Como ejemplo de sintaxis sin atributos, en el siguiente ejemplo de XAML se muestra otro fondo de botón. Esta vez, en lugar de establecer un color sólido simple, el fondo se establece en una imagen, con un elemento que representa esa imagen y el origen de la imagen especificado como un atributo del elemento anidado. Éste es un ejemplo de sintaxis de elemento de propiedad.

<Button Content="Button!">
  <Button.Background>
    <ImageBrush ImageSource="wavy.jpg"/>
  </Button.Background>
</Button>

Establecer propiedades en código

Establecer valores de propiedad de dependencia en código suele consistir en una simple llamada a la implementación de escritura expuesta por el "contenedor" de CLR.

Button myButton = new Button();
myButton.Width = 200.0;

Obtener un valor de propiedad consiste también esencialmente en una llamada a la implementación de lectura del "contenedor":

double whatWidth;
whatWidth = myButton.Width;

También puede llamar directamente a APIGetValue y SetValue del sistema de propiedades. Habitualmente, no es necesario si se está utilizando propiedades existentes (los contenedores son más cómodos y ofrecen una mejor exposición de la propiedad para las herramientas de desarrollo), pero llamar directamente a API es lo adecuado para ciertos escenarios.

También se puede establecer propiedades en XAML y, a continuación, obtener acceso más tarde en el código mediante código subyacente. Para obtener información más detallada, vea Código subyacente y XAML.

Funcionalidad de propiedad proporcionada por una propiedad de dependencia

Una propiedad de dependencia proporciona funcionalidad que extiende la funcionalidad de una propiedad, a diferencia de una propiedad respaldada por un campo. A menudo, cada una de estas funcionalidades representa o admite una característica concreta del conjunto total de propiedades de WPF:

  • Resources

  • Enlace de datos

  • Estilos

  • Animations

  • Invalidaciones de metadatos

  • Herencia del valor de la propiedad

  • Integración de WPF Designer

Resources

Puede establecerse un valor de propiedad de dependencia haciendo referencia a un recurso. Los recursos se especifican normalmente como elementos secundarios de un elemento raíz de la página o de la aplicación (estas ubicaciones permiten el acceso más cómodo al recurso). En el ejemplo siguiente se muestra cómo definir un recurso SolidColorBrush.

<DockPanel.Resources>
  <SolidColorBrush x:Key="MyBrush" Color="Gold"/>
</DockPanel.Resources>

Una vez definido el recurso, puede hacer referencia al recurso y utilizarlo para proporcionar un valor de propiedad:

<Button Background="{DynamicResource MyBrush}" Content="I am gold" />

Este recurso en particular se conoce como Extensión de marcado DynamicResource (en XAML, se puede utilizar una referencia de recurso estática o dinámica). Para utilizar una referencia de recurso dinámica debe estar estableciendo una propiedad de dependencia, por lo que es específicamente el uso de la referencia de recurso dinámica lo que habilita el sistema de propiedades de WPF. Para obtener más información, consulte Información general sobre recursos.

Nota

Los recursos se tratan como un valor local, lo que significa que si se establece otro valor local, se eliminará la referencia de recurso. Para obtener información más detallada, vea Prioridad de los valores de propiedades de dependencia.

Enlace de datos

Una propiedad de dependencia puede hacer referencia a un valor mediante enlace de datos. El enlace de datos funciona mediante una sintaxis de extensión de marcado concreta en XAML o mediante el objeto Binding en código. Con el enlace de datos, la determinación final del valor de la propiedad se aplaza hasta el tiempo de ejecución, momento en el que se obtiene el valor desde un origen de datos.

En el ejemplo siguiente se establece la propiedad Content de un control Button, utilizando un enlace en XAML. El enlace usa un contexto de datos heredado y un origen de datos XmlDataProvider (que no se muestra). El propio enlace especifica la propiedad de origen deseada por XPath dentro del origen de datos.

<Button Content="{Binding XPath=Team/@TeamName}"/>

Nota

Los enlaces se tratan como un valor local, lo que significa que, si establece otro valor local, eliminará el enlace. Para obtener información más detallada, vea Prioridad de los valores de propiedades de dependencia.

Las propiedades de dependencia o la clase DependencyObject no admiten de forma nativa INotifyPropertyChanged para generar notificaciones de cambios de valor de la propiedad de origen DependencyObject en operaciones de enlace de datos. Para obtener más información sobre cómo crear propiedades para su uso en enlace de datos que puedan informar de los cambios de un destino de enlace de datos, vea Información general sobre el enlace de datos.

Estilos

Los estilos y las plantillas son dos de los principales escenarios que invitan a usar propiedades de dependencia. Los estilos son particularmente útiles para establecer propiedades que definen la interfaz de usuario (UI) de la aplicación. Los estilos se definen habitualmente como recursos en XAML. Los estilos interactúan con el sistema de propiedades porque contienen normalmente "establecedores" para determinadas propiedades, así como "desencadenadores" que modifican el valor de la propiedad en función del valor en tiempo real de otra propiedad.

En el ejemplo siguiente se crea un estilo muy simple (que se definiría dentro de un diccionario Resources, que no se muestra) y, a continuación, se aplica directamente a la propiedad Style de un control Button. El establecedor que hay dentro del estilo establece la propiedad Background de un control Button con estilo en el color verde.

<Style x:Key="GreenButtonStyle">
  <Setter Property="Control.Background" Value="Green"/>
</Style>
<Button Style="{StaticResource GreenButtonStyle}">I am green!</Button>

Para obtener más información, consulte Aplicar estilos y plantillas.

Animations

Las propiedades de dependencia se pueden animar. Cuando se aplica una animación y se está ejecutando, el valor animado funciona en una prioridad más alta que cualquier valor (tal como un valor local) que pueda tener la propiedad.

En el ejemplo siguiente se anima la propiedad Background de una propiedad Button (técnicamente, la propiedad Background se anima utilizando la sintaxis de elemento de propiedad para especificar un objeto SolidColorBrush en blanco como Background; entonces, la propiedad Color de ese objeto SolidColorBrush es la propiedad que se anima directamente).

<Button>I am animated
  <Button.Background>
    <SolidColorBrush x:Name="AnimBrush"/>
  </Button.Background>
  <Button.Triggers>
    <EventTrigger RoutedEvent="Button.Loaded">
      <BeginStoryboard>
        <Storyboard>
          <ColorAnimation
            Storyboard.TargetName="AnimBrush" 
            Storyboard.TargetProperty="(SolidColorBrush.Color)"
            From="Red" To="Green" Duration="0:0:5" 
            AutoReverse="True" RepeatBehavior="Forever" />
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Button.Triggers>
</Button>

Para obtener más información sobre la animación de propiedades, vea Información general sobre animaciones y Información general sobre objetos Storyboard.

Invalidaciones de metadatos

Puede cambiar ciertos comportamientos de una propiedad de dependencia invalidando los metadatos para esa propiedad al derivar de la clase que registra originalmente la propiedad de dependencia. La invalidación de metadatos se apoya en el identificador DependencyProperty. La invalidación de metadatos, no requiere implementar de nuevo la propiedad. El sistema de propiedades administra nativamente el cambio de metadatos; cada clase puede contener metadatos individuales para todas las propiedades heredadas de las clases base, tipo por tipo.

En el ejemplo siguiente se invalidan los metadatos de una propiedad de dependencia DefaultStyleKey. Invalidar los metadatos de esta propiedad de dependencia concreta forma parte de un modelo de implementación que crea controles que pueden utilizar estilos predeterminados de temas.

public class SpinnerControl : ItemsControl
{
    static SpinnerControl()
    {
        DefaultStyleKeyProperty.OverrideMetadata(
            typeof(SpinnerControl), 
            new FrameworkPropertyMetadata(typeof(SpinnerControl))
        );
    }
}

Para obtener más información sobre cómo invalidar u obtener metadatos de propiedades, vea Metadatos de las propiedades de dependencia.

Herencia de valores de propiedad

Un elemento puede heredar el valor de una propiedad de dependencia de su elemento primario en el árbol.

Nota

El comportamiento de herencia del valor de la propiedad no está habilitado globalmente para todas las propiedades de dependencia, porque el tiempo de cálculo para la herencia tiene cierto impacto sobre el rendimiento. La herencia del valor de la propiedad solamente está habilitada, normalmente, para las propiedades donde un escenario determinado sugiera que resulta adecuada la herencia del valor de la propiedad. Puede determinar si una propiedad de dependencia se hereda examinando la sección Información de propiedad de dependencia de esa propiedad de dependencia en la referencia del SDK.

En el ejemplo siguiente se muestra un enlace y se establece la propiedad DataContext que especifica el origen del enlace, lo que no se mostraba en el ejemplo de enlace anterior. El valor de la propiedad DataContext se hereda, por consiguiente los enlaces subsiguientes de los elementos secundarios no tendrán que respetar el origen que se especifica como DataContext en el elemento StackPanel primario.

<StackPanel Canvas.Top="50" DataContext="{Binding Source={StaticResource XmlTeamsSource}}">
  <Button Content="{Binding XPath=Team/@TeamName}"/>
</StackPanel>

Para obtener más información, consulte Herencia de valores de propiedad.

Integración de WPF Designer

Un control personalizado con propiedades implementadas como propiedades de dependencia recibirá la compatibilidad con Windows Presentation Foundation (WPF) Designer for Visual Studio adecuada. Un ejemplo es la capacidad de modificar propiedades de dependencia directas y asociadas con la ventana Propiedades. Para obtener más información, consulte Información general sobre la creación de controles.

Prioridad de los valores de propiedades de dependencia

Al obtener el valor de una propiedad de dependencia, se está obteniendo potencialmente un valor que se estableció en esa propiedad mediante cualquiera de las demás entradas basadas en propiedad que participan en el sistema de propiedades de WPF. La prioridad de valor de propiedad de dependencia existe para que diversos escenarios de obtención de valores para propiedades puedan interactuar de una manera predecible.

Considere el ejemplo siguiente. El ejemplo incluye un estilo que se aplica a todos los botones y sus propiedades Background, pero también especifica un botón con un valor Background establecido localmente.

Nota

La documentación de SDK utiliza ocasionalmente los términos "valor local" o valor "localmente establecido" para explicar las propiedades de dependencia. Un valor localmente establecido es un valor de propiedad que se establece directamente en una instancia de objeto en código o como un atributo de un elemento en XAML.

De hecho, para el primer botón, la propiedad se establece dos veces, pero solamente se aplica un valor: el que tiene la prioridad superior. Un valor localmente establecido tiene la prioridad superior (excepto para una animación en ejecución, pero no hay ninguna animación en este ejemplo) y, así, se utiliza el valor establecido localmente en lugar del valor del establecedor del estilo para el segundo plano del primer botón. El segundo botón no tiene ningún valor local (y ningún otro valor con prioridad más alta que un establecedor de estilo) y, así, el fondo de ese botón procede del establecedor del estilo.

<StackPanel>
  <StackPanel.Resources>
    <Style x:Key="{x:Type Button}" TargetType="{x:Type Button}">
     <Setter Property="Background" Value="Red"/>
    </Style>
  </StackPanel.Resources>
  <Button Background="Green">I am NOT red!</Button>
  <Button>I am styled red</Button>
</StackPanel>

¿Por qué existe la prioridad de propiedad de dependencia?

Normalmente, no se desea que los estilos se apliquen siempre y oculten incluso un valor localmente establecido de un elemento individual (de lo contrario, sería muy difícil utilizar estilos o elementos en general). Por consiguiente, los valores que proceden de estilos funcionan con una prioridad más baja que un valor establecido localmente. Para ver una lista más completa de propiedades de dependencia y de dónde puede proceder el valor efectivo de una propiedad de dependencia, vea Prioridad de los valores de propiedades de dependencia.

Nota

Hay varias propiedades definidas en elementos de WPF que no son propiedades de dependencia. Habitualmente, las propiedades se implementan como propiedades de dependencia solamente cuando es necesario admitir por lo menos uno de los escenarios habilitados por el sistema de propiedades: enlace de datos, estilos, animación, compatibilidad con valor predeterminado, herencia, propiedades asociadas o invalidación.

Más información sobre propiedades de dependencia

  • Una propiedad asociada es un tipo de propiedad que admite una sintaxis especializada en XAML. Una propiedad asociada no suele tener una correspondencia 1:1 con una propiedad de common language runtime (CLR) y no es necesariamente una propiedad de dependencia. El propósito típico de una propiedad asociada es permitir que los elementos secundarios informen de los valores de la propiedad a un elemento primario, aunque el elemento primario y los elementos secundarios no posean esa propiedad como parte de las listas de miembros de la clase. Un escenario primario consiste en permitir que los elementos secundarios informen el elemento primario de cómo se deben presentar en interfaz de usuario; para ver un ejemplo, vea Dock o Left. Para obtener información más detallada, vea Información general sobre propiedades asociadas.

  • Los programadores de componentes y los desarrolladores de aplicaciones pueden desear crear propiedades de dependencia propias para habilitar funciones tales como el enlace de datos o la compatibilidad con estilos, o para la invalidación y la coerción de valor. Para obtener información más detallada, vea Propiedades de dependencia personalizadas.

  • Generalmente las propiedades de dependencia deben considerarse propiedades públicas, accesibles o, por lo menos, reconocibles por cualquier llamador que tenga acceso a una instancia. Para obtener información más detallada, vea Seguridad de las propiedades de dependencia.

Vea también

Conceptos

Propiedades de dependencia personalizadas

Propiedades de dependencia de sólo lectura

Información general sobre XAML

Arquitectura de WPF