Vinculación a propiedad estática

Resuelto Anthony Brien asked hace 15 años • 12 respuestas

Me resulta difícil vincular una propiedad de cadena estática simple a un cuadro de texto.

Aquí está la clase con la propiedad estática:

public class VersionManager
{
    private static string filterString;

    public static string FilterString
    {
        get { return filterString; }
        set { filterString = value; }
    }
}

En mi xaml, sólo quiero vincular esta propiedad estática a un cuadro de texto:

<TextBox>
    <TextBox.Text>
        <Binding Source="{x:Static local:VersionManager.FilterString}"/>
    </TextBox.Text>
</TextBox>

Todo se compila, pero en tiempo de ejecución aparece la siguiente excepción:

No se puede convertir el valor del atributo 'Fuente' en un objeto de tipo 'System.Windows.Markup.StaticExtension'. Error en el objeto 'System.Windows.Data.Binding' en el archivo de marcado 'BurnDisk;component/selectversionpagefunction.xaml' Línea 57 Posición 29.

¿Alguna idea de lo que estoy haciendo mal?

Anthony Brien avatar Jun 02 '09 02:06 Anthony Brien
Aceptado

Si el enlace debe ser bidireccional, debe proporcionar una ruta.

Hay un truco para realizar un enlace bidireccional en una propiedad estática, siempre que la clase no sea estática: declare una instancia ficticia de la clase en los recursos y utilícela como fuente del enlace.

<Window.Resources>
    <local:VersionManager x:Key="versionManager"/>
</Window.Resources>
...

<TextBox Text="{Binding Source={StaticResource versionManager}, Path=FilterString}"/>
Thomas Levesque avatar Jun 02 '2009 09:06 Thomas Levesque

No puedes vincularte a una estática como esa. No hay forma de que la infraestructura vinculante reciba notificaciones de las actualizaciones ya que no hay ninguna instancia involucrada DependencyObject(ni una instancia de objeto que implemente INotifyPropertyChanged).

Si ese valor no cambia, simplemente deshazte del enlace y úsalo x:Staticdirectamente dentro de la Textpropiedad. Defina appa continuación como la ubicación del espacio de nombres (y del ensamblado) de la clase VersionManager.

<TextBox Text="{x:Static app:VersionManager.FilterString}" />

Si el valor cambia, sugeriría crear un singleton para contener el valor y vincularlo.

Un ejemplo del singleton:

public class VersionManager : DependencyObject {
    public static readonly DependencyProperty FilterStringProperty =
        DependencyProperty.Register( "FilterString", typeof( string ),
        typeof( VersionManager ), new UIPropertyMetadata( "no version!" ) );
    public string FilterString {
        get { return (string) GetValue( FilterStringProperty ); }
        set { SetValue( FilterStringProperty, value ); }
    }

    public static VersionManager Instance { get; private set; }

    static VersionManager() {
        Instance = new VersionManager();
    }
}
<TextBox Text="{Binding Source={x:Static local:VersionManager.Instance},
                        Path=FilterString}"/>
Adam Sills avatar Jun 01 '2009 19:06 Adam Sills

En .NET 4.5 es posible vincularse a propiedades estáticas, leer más

Puede utilizar propiedades estáticas como origen de un enlace de datos. El motor de enlace de datos reconoce cuándo cambia el valor de la propiedad si se genera un evento estático. Por ejemplo, si la clase SomeClass define una propiedad estática llamada MyProperty, SomeClass puede definir un evento estático que se genera cuando cambia el valor de MyProperty. El evento estático puede utilizar cualquiera de las siguientes firmas:

public static event EventHandler MyPropertyChanged; 
public static event EventHandler<PropertyChangedEventArgs> StaticPropertyChanged; 

Tenga en cuenta que en el primer caso, la clase expone un evento estático denominado PropertyNameChanged que pasa EventArgs al controlador de eventos. En el segundo caso, la clase expone un evento estático denominado StaticPropertyChanged que pasa PropertyChangedEventArgs al controlador de eventos. Una clase que implementa la propiedad estática puede optar por generar notificaciones de cambio de propiedad utilizando cualquiera de los métodos.

Jowen avatar Sep 22 '2011 13:09 Jowen

A partir de WPF 4.5, puede vincularse directamente a propiedades estáticas y hacer que el enlace se actualice automáticamente cuando se cambia su propiedad. Es necesario conectar manualmente un evento de cambio para activar las actualizaciones vinculantes.

public class VersionManager
{
    private static String _filterString;        

    /// <summary>
    /// A static property which you'd like to bind to
    /// </summary>
    public static String FilterString
    {
        get
        {
            return _filterString;
        }

        set
        {
            _filterString = value;

            // Raise a change event
            OnFilterStringChanged(EventArgs.Empty);
        }
    }

    // Declare a static event representing changes to your static property
    public static event EventHandler FilterStringChanged;

    // Raise the change event through this static method
    protected static void OnFilterStringChanged(EventArgs e)
    {
        EventHandler handler = FilterStringChanged;

        if (handler != null)
        {
            handler(null, e);
        }
    }

    static VersionManager()
    {
        // Set up an empty event handler
        FilterStringChanged += (sender, e) => { return; };
    }

}

Ahora puedes vincular tu propiedad estática como cualquier otra:

<TextBox Text="{Binding Path=(local:VersionManager.FilterString)}"/>
Matt avatar Nov 22 '2017 06:11 Matt

Podría haber dos formas/sintaxis para vincular una staticpropiedad. Si p es una staticpropiedad de la clase MainWindow, entonces bindingfor textboxserá:

1.

<TextBox Text="{x:Static local:MainWindow.p}" />

2.

<TextBox Text="{Binding Source={x:Static local:MainWindow.p},Mode=OneTime}" />
Kylo Ren avatar Jan 22 '2016 18:01 Kylo Ren

Puedes usar ObjectDataProviderla clase y su MethodNamepropiedad. Puede verse así:

<Window.Resources>
   <ObjectDataProvider x:Key="versionManager" ObjectType="{x:Type VersionManager}" MethodName="get_FilterString"></ObjectDataProvider>
</Window.Resources>

El proveedor de datos del objeto declarado se puede utilizar así:

<TextBox Text="{Binding Source={StaticResource versionManager}}" />
GPAshka avatar Jan 23 '2013 09:01 GPAshka