2009-06-01 28 views
143

Tengo dificultades para vincular una propiedad de cadena estática simple a un cuadro de texto.Enlace a la propiedad estática

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 enlazar esta propiedad estática a un cuadro de texto:

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

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

No se puede convertir el valor en el atributo 'Fuente' t o objeto del tipo 'System.Windows.Markup.StaticExtension'. error al objeto 'System.Windows.Data.Binding' en archivo de anotación 'BurnDisk; componente/selectversionpagefunction.xaml' Línea 57 Posición 29.

Alguna idea de lo que estoy haciendo mal?

Respuesta

144

Si las necesidades de encuadernación que se bidireccional, debe proporcionar un camino. Hay un truco para hacer 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}"/> 
+0

Esta respuesta es más apropiada para mi caso porque no quiero presentar DependencyObject a mi clase de origen. ¡Gracias por el consejo! –

+4

Tenga en cuenta que habilitará su cuadro de texto para volver a insertar el valor en la propiedad estática, pero no actualizará el cuadro de texto cuando cambie el valor de origen. –

+0

Eso está bien, solo necesitaba el enlace del cuadro de texto a la Fuente en este caso. Si deseo que el enlace funcione de otra manera, soy consciente de la necesidad de uno de estos métodos: INotifyPropertyChanged, Evento modificado o propiedad de dependencia. –

88

No se puede vincular a un modo estático como ese. No hay forma de que la infraestructura de enlace reciba notificaciones de actualizaciones ya que no hay DependencyObject (o instancia de objeto que implemente INotifyPropertyChanged) involucrado.

Si ese valor no cambia, solo elimine el enlace y use x:Static directamente dentro de la propiedad Text. Defina app a continuación para ser la ubicación del espacio de nombres (y el ensamblaje) de la clase VersionManager.

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

Si el valor cambia, sugiero crear un singleton para contener el valor y vincularlo.

Un ejemplo de la 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}"/> 
+2

serio? Pude enlazar con el Int32.MaxValue estático que es muy similar a mi ejemplo: ¿Funciona porque es de una manera? –

+2

Sí, cualquier enlace bidireccional requiere un valor de propiedad de ruta en el enlace. El origen debe ser un objeto que contenga la propiedad especificada por Ruta Al especificar OneWay se elimina esa restricción. –

+0

Además, disculpe por la actualización tardía, pero actualicé la respuesta anterior con una muestra. –

34

En .NET 4.5 es posible enlazar a las propiedades estáticas, read more

Puede utilizar las propiedades estáticas como la fuente de un enlace de datos. El motor de enlace de datos reconoce cuándo cambia el valor de la propiedad si se produce 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ática 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 EventArgs que pasa 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 elegir para levantar notificaciones de cambio de propiedad con cualquiera de los métodos.

+0

Aquí está el enlace en caso de que alguien quiera leer más. Microsoft lo tomó, pero está en el archivo web aquí. https://web.archive.org/web/20131129053934/http://msdn.microsoft.com/en-US/library/bb613588 – matrixugly

+0

algunos ejemplos pleaseeee ... – user1034912

+0

Esta respuesta me indicó la dirección correcta, pero todavía tomó un tiempo para resolver los detalles sin un ejemplo. He escrito un [ejemplo] (https://stackoverflow.com/a/47428015/5024) basado en el código original. – Matt

7

Puede usar la clase ObjectDataProvider y es la propiedad MethodName. Puede tener este aspecto:

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

Declarado proveedor de datos de objeto se puede utilizar como esto:

<TextBox Text="{Binding Source={StaticResource versionManager}}" /> 
5

Si está utilizando los recursos locales se puede hacer referencia a ellos como a continuación:

<TextBlock Text="{Binding Source={x:Static prop:Resources.PerUnitOfMeasure}}" TextWrapping="Wrap" TextAlignment="Center"/> 
3

Podría haber dos formas/sintaxis para enlazar una propiedad static. Si p es un static Propiedad de la clase MainWindow, entonces binding para textbox será:

1.

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

2.

<TextBox Text="{Binding Source={x:Static local:MainWindow.p},Mode=OneTime}" /> 
2

Look at my proyecto CalcBinding, que le proporciona escribir expresiones complejas en el valor de la propiedad Ruta, incluidas propiedades estáticas, propiedades de origen, Matemáticas y otras. Por lo tanto, puede escribir esto:

<TextBox Text="{c:Binding local:VersionManager.FilterString}"/> 

Goodluck!

2

A partir de WPF 4.5 puede enlazar directamente a propiedades estáticas y hacer que el enlace se actualice automáticamente cuando se cambie su propiedad. Necesitas conectar manualmente un evento de cambio para activar las actualizaciones de enlace.

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 puede vincular a su propiedad estática al igual que cualquier otra:

<TextBox Text="{Binding Path=(local:VersionManager.FilterString)}"/> 
Cuestiones relacionadas