Buscar..


Sintaxis

  • {Binding PropertyName} es equivalente a {Binding Path = PropertyName}
  • {Ruta de enlace = SomeProperty.SomeOtherProperty.YetAnotherProperty}
  • {Ruta de enlace = SomeListProperty [1]}

Parámetros

Parámetro Detalles
Camino Especifica la ruta a enlazar. Si no se especifica, se enlaza con el propio DataContext.
UpdateSourceTrigger Especifica cuándo la fuente de enlace tiene su valor actualizado. El valor predeterminado es LostFocus . El valor más utilizado es PropertyChanged .
Modo Típicamente OneWay o TwoWay . Si el enlace no lo especifica, el valor predeterminado es OneWay menos que el destino del enlace solicite que sea TwoWay . Se produce un error cuando TwoWay se utiliza para enlazar a una propiedad de sólo lectura, por ejemplo OneWay se debe configurar de forma explícita cuando se une una propiedad de cadena de sólo lectura a TextBox.Text .
Fuente Permite utilizar un StaticResource como fuente de enlace en lugar del DataContext actual.
Fuente relativa Permite utilizar otro elemento XAML como fuente de enlace en lugar del DataContext actual.
ElementName Permite usar un elemento XAML nombrado como fuente de enlace en lugar del DataContext actual.
FallbackValue Si el enlace falla, este valor se proporciona al objetivo de enlace.
TargetNullValue Si el valor de origen de enlace es null , este valor se proporciona al destino de enlace.
Convertidor Especifica el convertidor StaticResource que se utiliza para convertir el valor del enlace, por ejemplo, convertir un booleano en un elemento de enumeración de Visibility .
Convertidor Parámetro Especifica un parámetro opcional que se proporcionará al convertidor. Este valor debe ser estático y no se puede enlazar.
StringFormat Especifica una cadena de formato que se utilizará al mostrar el valor enlazado.
Retrasar (WPF 4.5+) Especifica un retraso en milliseconds para que el enlace actualice el BindingSource en el ViewModel . Esto debe usarse con Mode=TwoWay UpdateSourceTrigger=PropertyChanged y UpdateSourceTrigger=PropertyChanged para que tenga efecto.

Observaciones

UpdateSourceTrigger

De forma predeterminada, WPF actualiza el origen de enlace cuando el control pierde el foco. Sin embargo, si solo hay un control que puede enfocarse, algo que es común en los ejemplos, deberá especificar UpdateSourceTrigger=PropertyChanged para que las actualizaciones funcionen.

Querrá utilizar PropertyChanged como desencadenante en muchos enlaces de dos vías, a menos que la actualización de la fuente de enlace en cada pulsación de tecla sea costosa o la validación de datos en vivo no sea deseable.

El uso de LostFocus tiene un efecto secundario desafortunado: presionar intro para enviar un formulario usando un botón marcado como IsDefault no actualiza la propiedad que respalda su enlace, deshaciendo efectivamente sus cambios. Afortunadamente, existen algunas soluciones .

Tenga en cuenta también que, a diferencia de UWP, WPF (4.5+) también tiene la propiedad Delay en los enlaces, lo que podría ser suficiente para algunos Bindings con configuraciones de inteligencia secundaria solo o local, como algunas validaciones de TextBox .

Convertir un valor booleano a visibilidad

Este ejemplo oculta la casilla roja (borde) si la casilla de verificación no está marcada haciendo uso de un IValueConverter .

Nota: El BooleanToVisibilityConverter usa en el siguiente ejemplo es un convertidor de valores integrado, ubicado en el espacio de nombres System.Windows.Controls.

XAML:

<Window x:Class="StackOverflowDataBindingExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <BooleanToVisibilityConverter x:Key="VisibleIfTrueConverter" />
    </Window.Resources>
    <StackPanel>
        <CheckBox x:Name="MyCheckBox"
                  IsChecked="True" />
        <Border Background="Red" Width="20" Height="20"
                Visibility="{Binding Path=IsChecked,ElementName=MyCheckBox, Converter={StaticResource VisibleIfTrueConverter}}" />
    </StackPanel>
</Window>

Definiendo el DataContext

Para trabajar con enlaces en WPF, debe definir un DataContext . El DataContext le dice a los enlaces de dónde obtener sus datos de forma predeterminada.

<Window x:Class="StackOverflowDataBindingExample.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:StackOverflowDataBindingExample"
        xmlns:vm="clr-namespace:StackOverflowDataBindingExample.ViewModels"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <vm:HelloWorldViewModel />
    </Window.DataContext>
    ...
</Window>

También puede establecer el DataContext a través del código subyacente, pero vale la pena señalar que XAML IntelliSense es algo delicado: se debe establecer un DataContext fuertemente tipado en XAML para que IntelliSense sugiera las propiedades disponibles para el enlace.

/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        DataContext = new HelloWorldViewModel();
    }
}

Si bien existen marcos para ayudarlo a definir su DataContext de una manera más flexible (por ejemplo, MVVM Light tiene un localizador de modelos de vista que usa inversión de control ), usamos el método rápido y sucio para los propósitos de este tutorial.

Puede definir un DataContext para casi cualquier elemento visual en WPF. El DataContext generalmente se hereda de los antepasados ​​en el árbol visual a menos que se haya anulado explícitamente, por ejemplo, dentro de un ContentPresenter.

Implementando INotifyPropertyChanged

INotifyPropertyChanged es una interfaz utilizada por las fuentes de enlace (es decir, el DataContext) para que la interfaz de usuario u otros componentes sepan que una propiedad ha sido cambiada. WPF actualiza automáticamente la interfaz de usuario cuando ve el evento PropertyChanged generado. Es deseable tener esta interfaz implementada en una clase base de la que puedan heredar todos sus modelos de vista.

En C # 6, esto es todo lo que necesitas:

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged([CallerMemberName] string name = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
    }
}

Esto le permite invocar NotifyPropertyChanged de dos maneras diferentes:

  1. NotifyPropertyChanged() , que NotifyPropertyChanged() el evento para el establecedor que lo invoca, gracias al atributo CallerMemberName .
  2. NotifyPropertyChanged(nameof(SomeOtherProperty)) , que generará el evento para SomeOtherProperty.

Para .NET 4.5 y superior utilizando C # 5.0, esto puede usarse en su lugar:

public abstract class ViewModelBase : INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged([CallerMemberName] string name = null)
    {
        var handler = PropertyChanged;
        if (handler != null)
        {
            handler(this, new PropertyChangedEventArgs(name));
        }
    }
}

En versiones de .NET anteriores a 4.5, debe conformarse con los nombres de propiedades como constantes de cadena o una solución utilizando expresiones .


Nota: es posible enlazar a una propiedad de un "objeto C # antiguo" (POCO) que no implementa INotifyPropertyChanged y observar que los enlaces funcionan mejor de lo esperado. Esta es una característica oculta en .NET y probablemente debería evitarse. Especialmente porque causará pérdidas de memoria cuando el Mode de enlace no sea OneTime (ver aquí ).

¿Por qué se actualiza el enlace sin implementar INotifyPropertyChanged?

Vincular a propiedad de otro elemento nombrado

Puede enlazar a una propiedad en un elemento con nombre, pero el elemento con nombre debe estar dentro del alcance.

<StackPanel>
    <CheckBox x:Name="MyCheckBox" IsChecked="True" />
    <TextBlock Text="{Binding IsChecked, ElementName=MyCheckBox}" />
</StackPanel>

Vincular a la propiedad de un antepasado

Puede enlazar a una propiedad de un antepasado en el árbol visual utilizando un enlace RelativeSource . El control más cercano más alto en el árbol visual que tiene el mismo tipo o se deriva del tipo que especifique se usará como fuente del enlace:

<Grid Background="Blue">
    <Grid Background="Gray" Margin="10">
        <Border Background="Red" Margin="20">
            <StackPanel Background="White" Margin="20">
                <Button Margin="10" Content="Button1" Background="{Binding Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}}" />
                <Button Margin="10" Content="Button2" Background="{Binding Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type FrameworkElement}}}" />
            </StackPanel>
        </Border>
    </Grid>
</Grid>

En este ejemplo, Button1 tiene un fondo gris porque el antepasado Grid más cercano tiene un fondo gris. Button2 tiene un fondo blanco porque el antepasado más cercano derivado de FrameworkElement es el StackPanel blanco.

Ejemplo de enlace de RelativeSource

Vinculando múltiples valores con un MultiBinding

El MultiBinding permite vincular múltiples valores a la misma propiedad. En el siguiente ejemplo, varios valores están vinculados a la propiedad Texto de un cuadro de texto y se formatean utilizando la propiedad StringFormat.

<TextBlock>
    <TextBlock.Text>
        <MultiBinding StringFormat="{}{0} {1}">
            <Binding Path="User.Forename"/>
            <Binding Path="User.Surname"/>
        </MultiBinding>
    </TextBlock.Text>
</TextBlock>

Además de StringFormat , también se puede usar un IMultiValueConverter para convertir los valores de los enlaces en un valor para el objetivo de MultiBinding.

Sin embargo, MultiBindings no puede ser anidado.



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow