2009-05-27 7 views
9

J'ai une boîte de dialogue qui apparaît sur l'écran principal (c'est un contrôle utilisateur qui apparaît sur la page selon la démo d'application de Billy Hollis) dans mon application qui contient des données de l'écran principal à éditer. L'écran principal est en lecture seule. Le problème que j'ai, c'est que lorsque je change les données dans la boîte de dialogue, les données de l'écran principal sont également mises à jour. De toute évidence, ils sont liés au même objet, mais existe-t-il un moyen d'arrêter la mise à jour de liaison jusqu'à ce que je clique sur Enregistrer dans ma boîte de dialogue?Comment arrêter la mise à jour des propriétés de liaison?

Répondre

10

Vous pouvez utiliser un :

... 
<StackPanel Name="panel"> 
    <StackPanel.BindingGroup> 
     <BindingGroup Name="bindingGroup"/> 
    </StackPanel.BindingGroup> 
    <TextBox Text="{Binding Foo}"/> 
    <TextBox Text="{Binding Bar}"/> 
    <Button Name="btnSubmit" Content="Submit" OnClick="btnSubmit_Click"/> 
    <Button Name="btnCancel" Content="Cancel" OnClick="btnCancel_Click"/> 
</StackPanel> 
... 

code derrière:

private void UserControl_Loaded(object sender, RoutedEventArgs e) 
{ 
    panel.BindingGroup.BeginEdit(); 
} 

private void btnSubmit_Click(object sender, RoutedEventArgs e) 
{ 
    panel.BindingGroup.CommitEdit(); 
    panel.BindingGroup.BeginEdit(); 
} 

private void btnCancel_Click(object sender, RoutedEventArgs e) 
{ 
    panel.BindingGroup.CancelEdit(); 
    panel.BindingGroup.BeginEdit(); 
} 
+0

Bonne idée! Je n'ai eu ce travail que si j'ai déclaré le groupe dans chaque déclaration contraignante. C'est cependant beaucoup plus facile que les autres alternatives. – Telavian

0

La seule manière que je l'ai vu faire est la façon dont Josh Smith mentionne here avec convertisseurs. Ce n'est pas la méthode la plus simple.

3

Regardez la propriété Binding.UpdateSourceTrigger.

Vous pouvez définir la Binding dans votre boîte de dialogue comme si

<TextBox Name="myTextBox" 
    Text={Binding Path=MyProperty, UpdateSourceTrigger=Explicit} /> 

Et puis appelez la méthode UpdateSource dans votre bouton Enregistrer événement

myTextBox.GetBindingExpression(TextBox.TextProperty).UpdateSource(); 

Une fois que vous avez appelé UpdateSource l'objet source sera mis à jour avec la valeur du TextBox

+0

J'ai essayé mais ça ne marche pas. Il met toujours à jour le TextBlock sur l'écran principal. L'option Explicit indique qu'elle ne sera mise à jour que lorsque la méthode UpdateSource sera appelée, mais pas dans ce cas. –

+0

Vraiment? Je suis surpris. Je l'ai juste essayé et ça marche pour moi. Peut-être qu'il y a quelque chose d'autre dans votre application qui cause des problèmes? – Ray

+0

Cela fonctionne définitivement, mais vous devez parcourir toutes les liaisons pour appeler UpdateSource() sur chacune d'elles. Le moyen le plus simple de le faire est d'associer les liaisons à un BindingGroup. En prime, UpdateSourceTrigger est défini sur Explicit sur les liaisons associées implicitement. – Lu55

0

Je choisis également d'utiliser BindingGroup. Mais à la place du modèle BeginEdit()/CommitEdit()/CancelEdit(), j'appelle UpdateSource() explicitement sur toutes les liaisons associées à BindingGroup. Cette approche me permet d'ajouter un seul gestionnaire d'événements au lieu de 3.

private void OkButton_Click(object sender, RoutedEventArgs e) 
{ 
    CommitChanges(); 
    DialogResult = true; 
    Close(); 
} 

private void CommitChanges() 
{ 
    foreach (var bindingExpression in this.BindingGroup.BindingExpressions) 
    { 
     bindingExpression.UpdateSource(); 
    } 
} 
Questions connexes