2016-11-24 1 views
1

Lorsqu'un DependencyProperty est défini, la propriété target (viewmodel) liée obtient-elle sa nouvelle valeur immédiatement ou cela se produit-il de manière asynchrone? .: par exemple Quand les liaisons sont-elles mises à jour?

<TextBox x:Name="textBox" IsEnabled="{Binding IsEnabled,Mode=TwoWay}"/> 

Je définir explicitement la propriété IsEnabled:

textBox.IsEnabled = false; 

Je sais au sujet de la mise en UpdateSourceTrigger, et je crois que cette question est surtout pertinente pour la valeur par défaut UpdateSourceTrigger.PropertyChanged.

Répondre

2

La réponse courte est immédiatement et de manière synchrone.

La longue histoire

Je ne mélanger UpdateSourceTrigger avec (a) synchronicité de la liaison. Le premier définit la fréquence à laquelle la propriété source doit être mise à jour, par ex. quand un contrôle perd le focus ou peut-être quand la méthode UpdateSource est appelée ...

D'autre part, la synchronicité d'une liaison donnée définit si les opérations get/set d'une propriété source sont effectuées de manière synchrone ou asynchrone. En pratique, vous ne verrez qu'une différence si la lecture d'une propriété source peut prendre beaucoup de temps. Dans ce cas, l'interface utilisateur par défaut sera bloquée.

Vous pouvez contrôler la synchronicité de la liaison via la propriété Binding.IsAsync. Voici un exemple montrant une différence. Commençons par XAML:

<TextBox Text="{Binding Text, Mode=TwoWay}"/> 
<Button Click="Button_Click">Update</Button> 

Et voici un code derrière. MainWindow a Text propriété qui est une source d'une liaison. Si un bouton est cliqué, il est mis à jour. Si vous examinez la propriété Text, vous verrez que cela prend 10 secondes pour obtenir sa valeur.

public partial class MainWindow : Window, INotifyPropertyChanged 
{ 
    private string _text; 
    public string Text 
    { 
     get 
     { 
      System.Threading.Thread.Sleep(10000); 
      return _text; 
     } 

     set 
     { 
      _text = value; 
      OnPropertyChanged(nameof(Text)); 
     } 
    } 

    public MainWindow() 
    { 
     DataContext = this; 
     InitializeComponent(); 
    } 

    private void Button_Click(object sender, RoutedEventArgs e) 
    { 
     Text = DateTime.Now.ToString(); 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null) 
    { 
     PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 

Si vous exécutez ce code, vous remarquerez 2 choses:

  • L'application démarre lentement.
  • Si vous cliquez sur un bouton, l'application se bloque.

maintenant modifier la liaison de cette façon:

<TextBox Text="{Binding Text,Mode=TwoWay, IsAsync=true}"/> 

Exécutez l'application une nouvelle fois:

  • L'application démarre immédiatement.
  • Si vous cliquez sur un bouton, l'application ne se bloque pas.

L'exemple similaire peut être réalisé avec un décanteur de Text, c'est-à-diredéplacez simplement System.Threading.Thread.Sleep(10000); vers le setter.

1

Vous pouvez donner des propriétés de setter getter au champ de zone de texte et trouver comment cela fonctionne comme ..string st get {return _type; } set {_type = valeur; } .. et donc vous aurez la chance de chnage valeurs ou vous pouvez appliquer la validation