193 votes

Liaison à une propriété statique

J'ai du mal à lier une simple propriété statique de type chaîne à un TextBox.

Voici la classe avec la propriété statique :

public class VersionManager
{
    private static string filterString;

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

Dans mon xaml, je veux juste lier cette propriété statique à un TextBox :

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

Tout se compile, mais au moment de l'exécution, j'obtiens l'exception suivante :

Impossible de convertir la valeur de l'attribut 'Source' en objet de type System.Windows.Markup.StaticExtension'. Erreur au niveau de l'objet 'System.Windows.Data.Binding' dans le fichier de balisage BurnDisk;component/selectversionpagefunction.xaml'. Ligne 57 Position 29.

Une idée de ce que je fais mal ?

197voto

Thomas Levesque Points 141081

Si la liaison doit être bidirectionnelle, vous devez fournir un chemin.

Il existe une astuce pour réaliser une liaison bidirectionnelle sur une propriété statique, à condition que la classe ne soit pas statique : déclarez une instance fictive de la classe dans les ressources, et utilisez-la comme source de la liaison.

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

<TextBox Text="{Binding Source={StaticResource versionManager}, Path=FilterString}"/>

0 votes

Cette réponse est plus appropriée à mon cas car je ne veux pas introduire DependencyObject dans ma classe source. Merci pour l'astuce !

11 votes

Notez que cela permettra à votre zone de texte de repousser la valeur dans la propriété statique, mais ne mettra pas à jour la zone de texte lorsque la valeur source change.

1 votes

C'est très bien, j'avais juste besoin de lier la zone de texte à la source dans ce cas. Si je veux que la liaison fonctionne dans l'autre sens, je suis conscient de la nécessité de l'une de ces méthodes : INotifyPropertyChanged, <PropertyName>Événement modifié ou propriété de dépendance.

128voto

Adam Sills Points 8749

Vous ne pouvez pas vous lier à un statique comme ça. Il n'y a aucun moyen pour l'infrastructure de liaison d'être informée des mises à jour, puisqu'il n'y a pas de fichier DependencyObject (ou une instance d'objet qui implémente INotifyPropertyChanged ) concernés.

Si cette valeur ne change pas, il suffit de laisser tomber la liaison et d'utiliser x:Static directement à l'intérieur du Text propriété. Définir app ci-dessous pour être l'emplacement de l'espace de nom (et de l'assemblage) de la classe VersionManager.

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

Si la valeur change, je suggère de créer un singleton contenant la valeur et de l'associer à celui-ci.

Un exemple de 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}"/>

5 votes

Vraiment ? J'ai pu faire le bind à la static Int32.MaxValue qui est très similaire à mon échantillon : <TextBox Text={Binding Source={x:Static sys:Int32.MaxValue}, Mode=OneWay}" /> Est-ce que cela fonctionne parce que c'est à sens unique ?

2 votes

Oui, toute liaison bidirectionnelle nécessite une valeur de propriété Path sur la liaison. La source doit être un objet qui contient la propriété spécifiée par Path. Le fait de spécifier OneWay supprime cette restriction.

0 votes

Aussi, désolé pour la mise à jour tardive, mais j'ai mis à jour la réponse ci-dessus avec un échantillon.

41voto

Jowen Points 1307

Dans .NET 4.5, il est possible de se lier à des propriétés statiques, en savoir plus

Vous pouvez utiliser des propriétés statiques comme source d'une liaison de données. Le moteur de liaison de données de moteur de liaison de données reconnaît quand la valeur de la propriété change si un événement statique est déclenché. Par exemple, si la classe SomeClass définit une propriété statique appelée MyProperty, SomeClass peut définir un événement statique. propriété statique appelée MyProperty, SomeClass peut définir un événement statique qui est déclenché lorsque la valeur de MyProperty change. L'événement statique peut utiliser l'une des signatures suivantes :

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

Notez que dans le premier cas, la classe expose un événement statique nommé PropertyNameChanged qui transmet des EventArgs au gestionnaire d'événements. Dans le second cas, la classe expose un événement statique nommé StaticPropertyChanged qui transmet PropertyChangedEventArgs au gestionnaire de l'événement. gestionnaire d'événements. Une classe qui implémente la propriété statique peut choisir de d'envoyer des notifications de changement de propriété en utilisant l'une ou l'autre méthode.

0 votes

Voici le lien au cas où quelqu'un voudrait en savoir plus. Microsoft l'a retiré, mais il est archivé sur le web ici. web.archive.org/web/20131129053934/http://msdn.microsoft.com/

2 votes

Cette réponse m'a mis sur la bonne voie, mais il m'a fallu un certain temps pour trouver les détails sans exemple. J'ai rédigé un exemple basé sur le code original.

9voto

GPAshka Points 33

Vous pouvez utiliser ObjectDataProvider et c'est MethodName propriété. Cela peut ressembler à ceci :

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

Le fournisseur de données d'objet déclaré peut être utilisé comme suit :

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

8voto

Edmund Covington Points 155

Si vous utilisez des ressources locales, vous pouvez vous y référer comme ci-dessous :

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

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X