Si je désactive la mise à jour automatique de la source de données de liaison par paramètre DataSourceUpdateMode = JAMAIS, puis utilisez un bouton pour mettre à jour le lot entier (en utilisant la liaison.writevalue), un problème se produit - à savoir, seule la source de données de la première liaison est mis à jour. Tous les autres contrôles sont réinitialisés aux valeurs d'origine.
Ceci est parce que lorsque l'objet actuel change (comme cela se produit après l'écriture écartée ci-dessus), si contrôleUpdateMode = onpropertychange, alors toutes les autres commandes reluées dans la valeur des données Source. P>
Quel est le moyen standard d'éviter ce problème? P>
Un moyen est de dériver une classe de liaison de liaison et d'ajouter une méthode WriteAllValues. Cette méthode procède aux éléments suivants: p>
(1) pour chaque liaison, enregistrez le contrôleUpdateMode p>
(2) pour chaque reliure, définissez contrôlé contrôlé = jamais p>
(3 ) Pour chaque liaison, appelez la méthode ELTRÉVALUE P>
(4) pour chaque reliure, réinitialisez contrôlé à la valeur enregistrée p>
(5) pour chaque liaison, si contrôleUptDaMode = OnproperTychange, appelez le Méthode LisveValue. P>
Pouvez-vous voir des problèmes avec cela? P>
Si vous travaillez avec vos propres cours, implémenteriez ieditableObject résoudre le problème? P>
dans un autre contrôle Je travaille sur, je mettez ma propre liaison. La façon dont je me passe autour de la question est avec le code suivant. (J'ai mis au minimum le minimum, j'espère que vous pouvez le suivre!): P> Donc, lorsque mis à jourAsourceFrrolControl est appelé, tous les événements actuelsImchanged seront appelés à tous autres contrôles dans la même liaison. Toutefois, étant donné que ControldoingExplicdate est définie, ils ne reliront pas de la valeur de la source de données à moins qu'ils ne soient le contrôle qui a fait la mise à jour.
ControlloingExplicdate n'est défini sur rien après que tous ces événements ont terminé, de sorte que le service normal reprend. P> J'espère que vous pouvez suivre cela, et - - - Je vous demande, pouvez-vous voir des problèmes avec cela? P > p>
3 Réponses :
J'ai eu des exigences similaires pour une forme. Dans mon cas, je voulais seulement que la base de données de tous les contrôles du formulaire se produise lorsque j'ai cliqué sur le bouton Enregistrer le formulaire. P>
La meilleure solution que j'ai trouvée était de définir chaque liaison de DataSourceUpdateMode sur ONVALIDATION, puis définissez la propriété AutoVovalidate du formulaire contenant pour désactiver. Cela empêche la liaison lorsque vous changez de concentration entre les commandes sur la forme. Ensuite, dans l'événement de clic pour mon bouton Enregistrer, je validai manuellement l'entrée de mon formulaire et, si c'est correct, appelez la méthode ValidateChadren du formulaire pour déclencher la liaison. P>
Cette méthode présente également l'avantage de vous donner le contrôle total sur la manière dont vous validez votre entrée. Winforms n'inclut pas un bon moyen de le faire par défaut. P>
Cette méthode ne résout pas le problème. Lorsque la méthode de ValidatechatRen de la forme est appelée, il n'ya toujours qu'une seule valeur de contrôle est mise à jour. Tous les autres contrôles sont réinitialisés à la valeur d'origine. Je me suis testé moi-même. C'est-à-dire la même raison que la question ci-dessus mentionnée "lorsque l'objet actuel change, si contrôleUpDaTemode = onpropertychange, alors toutes les autres commandes reluées dans la valeur de la source de données".
Je crois que je suis récemment lu sur Stackoverflow où cela a été donné comme une réponse: Désactiver Databinding à deux voies
public static class DataBindingUtils { public static void SuspendTwoWayBinding( BindingManagerBase bindingManager ) { if( bindingManager == null ) { throw new ArgumentNullException ("bindingManager"); } foreach( Binding b in bindingManager.Bindings ) { b.DataSourceUpdateMode = DataSourceUpdateMode.Never; } } public static void UpdateDataBoundObject( BindingManagerBase bindingManager ) { if( bindingManager == null ) { throw new ArgumentNullException ("bindingManager"); } foreach( Binding b in bindingManager.Bindings ) { b.WriteValue (); } } }
Cela est encore pire que la question de la question fournie. Même si vous voulez désactiver la liaison de 2 voies. Vous devez désactiver ContralupDaTemode, pas seulement DataSourceUpdateMode. Et je n'aime pas leur façon de gérer ce problème. Parce qu'il se bat avec la liaison de données. Et la liaison de données censée faciliter notre travail.
@Luojionghui Si la base de données est supposée, OT facilite le travail que pourquoi l'OP a-t-il un problème? Évidemment, cela ne facilite pas le travail - donc l'OP doit créer une solution pour surmonter le fait que la liaison à deux voies ne facilite pas son travail. BTW: Sous le capot de la liaison à 2 voies, c'est plus de code de code créé pour surmonter un problème. Il y a toutes sortes de code là-bas pour surmonter les problèmes que le cadre n'a pas, inclure ou fonctionne correctement. Cependant, une personne choisit de contourner ces problèmes.
Je suggérerais de ne pas vous battre avec la liaison de données. Gardez DataSourceUpdateMode comme survalidation. Ensuite, choisissez l'une des 2 options suivantes.
1, avant de modifier les valeurs des commandes, faites une valeur de courant de sauvegarde. Si l'utilisateur cliquez sur le bouton Annuler, copiez les valeurs sauvegardées vers la source de données. Et exécutez UserBindingSource.ResetCurrentItem () pour rafraîchir les valeurs des commandes aux valeurs d'origine. P>
2, si utilisateur cliquez sur le bouton Annuler, tirez un nouvel objet par ID de la base de données. Et utilisez le nouvel objet pour remplacer l'objet actuel dans la source de liaison. Le code pourrait être quelque chose comme ceci: p> I Personnellement comme la deuxième option car il évite de copier l'objet, il peut nécessiter une copie de chaque propriétés et rendre la maintenance plus difficile si Les propriétés ont changé dans le futur. Il tire également les dernières données, qui rend l'enregistrement très frais. En outre, la première option n'enregistre que 1 copie de l'enregistrement. Si vous accédez à d'autres enregistrements et effectuez d'autres modifications, la copie est perdue. Cependant, la deuxième option tire des données de la base de données. Vous pouvez donc toujours naviguer sur n'importe quel précédemment modifié mais n'a pas enregistré enregistrement et cliquez sur le bouton Annuler pour ramener la valeur d'origine. P> P>