2010-11-15 25 views
1

Je suis en train d'effectuer une nouvelle mise à l'échelle des données dans un convertisseur de valeurs chaque fois qu'un panneau est redessiné. Je veux déplacer une partie de ce traitement vers le viewmodel car la plus grande partie du traitement ne se produit que si la taille du contrôle ou quelques autres propriétés changent.WPF: Liaison à la propriété readonly dans le code

Pour que les données rééchelonnées semblent acceptables, j'ai besoin du ActualWidth du conteneur dans le modèle de vue. Je veux le lier à une propriété du viewmodel d'une manière, donc quand il change, je peux déclencher le traitement de redimensionnement. Tous les exemples que j'ai pu trouver lient une CLR ou une propriété de dépendance à un élément plutôt qu'à l'autre et il me manque clairement quelque chose pour comprendre comment je devrais le faire. J'ai essayé plusieurs choses pour mettre en place la reliure mais je ne comprends pas.

Des indices? Merci.

En MyView XAML:

<myItemsControl/> 

Dans le code MyView derrière, quelque chose comme:

Binding b = new Binding(MyWidthProperty); 
b.Mode = BindingMode.OneWay; 
b.Source = myItemsControl.Name; 
.........? 

et

public static readonly DependencyProperty MyWidthProperty = 
DependencyProperty.Register("MyWidth", typeof(Double), typeof(MyViewModel)); 

En MyViewModel:

public Double MyWidth{ 
     get { return _myWidth; } 
     set { _myWidth = value; ViewChanged(this); } } 
+0

je lirais un peu plus sur DependencyProperty. En particulier, votre objet doit être un objet DependencyObject et vous devez utiliser les méthodes GetValue et SetValue pour accéder à la valeur sous-jacente. Enfin, vous n'obtiendrez pas d'appel de setter lorsque le système de liaison accède au point d'accès (ce point est facile à manquer). Vous devrez donc passer un gestionnaire modifié dans le cadre de l'appel Register. –

Répondre

2

Vous ne pouvez pas le faire de cette façon. Vous ne pouvez pas définir un Binding sur ActualWidth, car il est en lecture seule.

Vous pouvez uniquement définir une liaison à MyWidth. Mais pour cela, vous devez d'abord convertir MyWidth en DependencyProperty. Ensuite, vous serez en mesure de faire quelque chose comme

Binding b = new Binding("ActualWidth") { Source = myItemsControl }; 
this.SetBinding(MyViewModel.MyWidthProperty, b); 

Pour convertir en une propriété de dépendance, vous devrez remplacer votre définition de MyWidth ce qui suit:

public static readonly DependencyProperty MyWidthProperty = 
    DependencyProperty.Register("MyWidth", typeof(double), typeof(MyViewModel), 
             new UIPropertyMetadata(
              0.0, 
              (d, e) => 
              { 
               var self = (MyViewModel)d; 
               ViewChanged(self); 
              })); 

Mais soyez prudent avec les propriétés de dépendance ; il est préférable de lire la documentation en premier.

Edit: Vous devez également définir la propriété de cette façon:

public double MyWidth 
{ 
    get { return (double)this.GetValue(MyWidthProperty); } 
    set { this.SetValue(MyWidthProperty, value); } 
} 
+0

Merci pour cette réponse très complète. Évitez les propriétés de dépendance dues à la syntaxe désagréable pendant que je faisais des progrès avec le reste de WPF. La première fois que j'ai été obligé d'en utiliser un ... on dirait que je ferais mieux d'aller au-dessus d'eux comme je m'attends à ce que ça se reproduise. – rjw