6
votes

La liaison XAML ne semble pas définir si la propriété est initialisée dans le constructeur

J'ai rencontré un problème avec la liaison de données à l'intérieur du modèle de commande lorsque la propriété est initialisée à l'intérieur du constructeur.

Voici le show-cas (vous pouvez également télécharger Solution ): p>

CustomControl1.cs P>

System.Windows.Data Warning: 52 : Created BindingExpression (hash=18961937) for Binding (hash=44419000)
System.Windows.Data Warning: 54 :   Path: 'Content'
System.Windows.Data Warning: 56 : BindingExpression (hash=18961937): Default mode resolved to OneWay
System.Windows.Data Warning: 57 : BindingExpression (hash=18961937): Default update trigger resolved to PropertyChanged
System.Windows.Data Warning: 58 : BindingExpression (hash=18961937): Attach to WpfApplication5.CustomControl1.Content (hash=47980820)
System.Windows.Data Warning: 62 : BindingExpression (hash=18961937): RelativeSource (FindAncestor) requires tree context
System.Windows.Data Warning: 61 : BindingExpression (hash=18961937): Resolve source deferred
System.Windows.Data Warning: 63 : BindingExpression (hash=18961937): Resolving source 
System.Windows.Data Warning: 66 : BindingExpression (hash=18961937): Found data context element: <null> (OK)
System.Windows.Data Warning: 69 :     Lookup ancestor of type CustomControl2:  queried Border (hash=11653293)
System.Windows.Data Warning: 69 :     Lookup ancestor of type CustomControl2:  queried CustomControl2 (hash=54636159)
System.Windows.Data Warning: 68 :   RelativeSource.FindAncestor found CustomControl2 (hash=54636159)
System.Windows.Data Warning: 74 : BindingExpression (hash=18961937): Activate with root item CustomControl2 (hash=54636159)
System.Windows.Data Warning: 104 : BindingExpression (hash=18961937):   At level 0 - for CustomControl2.Content found accessor DependencyProperty(Content)
System.Windows.Data Warning: 100 : BindingExpression (hash=18961937): Replace item at level 0 with CustomControl2 (hash=54636159), using accessor DependencyProperty(Content)
System.Windows.Data Warning: 97 : BindingExpression (hash=18961937): GetValue at level 0 from CustomControl2 (hash=54636159) using DependencyProperty(Content): 'Some content'
System.Windows.Data Warning: 76 : BindingExpression (hash=18961937): TransferValue - got raw value 'Some content'
System.Windows.Data Warning: 85 : BindingExpression (hash=18961937): TransferValue - using final value 'Some content'


1 commentaires

Comme il y a une deuxième réponse (il a même été supprimé par l'auteur) et ils ne correspondent même pas à distance aux questions, j'ai souligné mes questions avec audacieux. S'il vous plaît, assurez-vous d'avoir le problème Essentials et assurez-vous de répondre à les questions .


4 Réponses :


1
votes

Peut-être que vous devriez utiliser Twoway Mode de liaison? Que devriez-vous contrôler faire avec "certains contenus"? Il ne peut pas le stocker dans le modèle de votre contrôle car la liaison est simple. Dans votre reliure de cas voit qu'il y a une valeur dans la propriété de votre modèle et la résilide de «certains contenus». Si vous n'initialisez pas la propriété, la liaison ne fait rien, car elle ignore les valeurs nulles et que vous voyez «du contenu». J'espère que mon explication est claire.

edit

Désolé pour peu de malentendus de votre problème. J'ai téléchargé votre application de démonstration et reproduit le problème. Lecture Ceci et Ceci Les articles MSDN montrent que vos intentions avaient raison. Cependant, vous pouvez y trouver ces mots:

Les méthodes virtuelles ou rappels suivants sont potentiellement appelées lors des calculs de l'appel de SETValue qui définit une valeur de propriété de dépendance: validatevaluecallback, CoerceValuecallback, ONPROPERTYCHANGED.

Ainsi, la valeur de réglage de la dépendanceProperty dans le constructeur est aussi dangereuse que d'appeler une méthode virtuelle d'objet non construite.

OK, la définition d'une dépendanceProperty dans le constructeur est mauvaise. Ma prochaine idée était de définir une valeur dans certains rappels (j'ai utilisé onintialized car il devrait être appelé droit après le constructeur de contrôle). Et j'ai trouvé un autre comportement vraiment étrange. Si je ne définissons aucune valeur dans le constructeur (de cette façon) xxx

Je ne vois pas "Initial2" dans la fenêtre même si je ne spécifie aucune valeur pour Contenu dans Window1.xaml. Notez que la valeur est définie correctement (comme vous le voyez, vérifiez-le). Mais si je découvre content = "initial1"; chaîne, je vois "Initial2". En outre, si j'initialise que le contenu de la liaison onitialized fonctionne bien, mais cela ne résout pas que la valeur réelle du contenu est "Initial2". On dirait que sa source n'est pas que Propriété de contenu.

Je continuerai à travailler autour de cette question plus tard. J'espère que ces informations peuvent être utiles.


2 commentaires

En fait, lorsque j'ai heurté le problème, c'était dans le contexte d'une liaison à Twoway. Dans cet échantillon, j'ai enlevé toutes les choses qui n'avaient pas d'importance. Donc, aucune twoway ne le fait ne fonctionne pas. Quoi qu'il en soit, même si cela aurait: une liaison à sens unique doit fonctionner de manière à ce que chaque fois que je change de la source, la cible doit être mise à jour, peu importe une valeur nominale ou non. Mais le problème ne concerne pas une défaillance de liaison ponctuelle, il s'agit d'une liaison ne se fixant pas du tout sur la propriété. Comme s'il n'y avait pas de liaison du tout.


Un peu de cantonnier sur le design laid de l'échantillon. S'il vous plaît, ne regardez pas la non-applicabilité du code fourni, c'est uniquement pour les fins de démonstration uniquement. Le problème a émergé dans un énorme projet avec une signification parfaite pour les modes de liaison ou les contrôles avec leur contenu. J'espérais que c'était évident que l'échantillon était destiné à aider à reproduire le problème.




5
votes

1 commentaires

Super! SetCurrentValue () a travaillé comme un charme pour moi :)



0
votes

Ne pas initialiser la valeur en CTOR, utilisez coercevalue ()

dans CTOR P>

public static readonly DependencyProperty SomeProperty =
    DependencyProperty.Register(
        "Some", typeof(ObservableCollection<IModel>),
        typeof(SomeUserControl),
        new PropertyMetadata()
        {
            DefaultValue = null,
            PropertyChangedCallback = OnSomeChanged,
            CoerceValueCallback = OnCoerceSome
        }
    );

private static object OnCoerceSome(DependencyObject d, object baseValue)
{
    var v = (ObservableCollection<IModel>)baseValue;
    return v ?? new ObservableCollection<IModel>();
}   


0 commentaires