2012-05-31 11 views
9

Ich habe eine WPF-Ansicht mit einem TextBox, binden das Textfeld an ein ViewModel mit UpdateSourceTrigger auf PropertyChanged festgelegt. In der Eigenschaft Setter in dem Ansichtsmodell, ich habe eine einfache Prüfung den Text aus mehr als 10 Zeichen zu verhindern:WPF - MVVM - Textfeld nicht mehr synchron mit viewmodel -Eigenschaft

<TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}" /> 

public partial class MainWindow : Window 
{ 
    public MainWindow() 
    { 
     InitializeComponent(); 

     this.DataContext = new MainViewModel(); 
    } 
} 


public string Name 
{ 
    get { return _Name; } 
    set 
    { 
     if (_Name != value) 
     { 
      if (value.Length <= 10) 
      { 
       _Name = value; 
      } 
      RaisePropertyChanged("Name"); 
     } 
    } 
} 

Wenn der Wert nicht gesetzt, ich RaisePropertyChanged noch (was einfach feuert Property).

Das Problem ist, dass wenn ich das 11. Zeichen in der Benutzeroberfläche eingeben, ich nicht aktualisieren _Name. Ich fire PropertyChanged, und ich kann sehen, dass der Get Accessor get aufgerufen wird und es die Zeichenfolge mit nur 10 Zeichen zurückgibt. Meine TextBox spiegelt dies jedoch nicht wider; Es zeigt immer noch die Zeichenfolge mit 11 Zeichen.

Darüber hinaus ist, dass, wenn auf dem 11. Zeichen ich den Text in der Setter zu "ERROR" ändern und Feuer Eigenschaft geändert, die TextBox aktualisiert, um den geänderten Text anzuzeigen.

Warum also, wenn ich den Text im Setter zurück auf den vorherigen Wert ändern, spiegelt die Benutzeroberfläche dies nicht wider?

Ich weiß, es gibt alternative Möglichkeiten der Handhabung von Max-Zeichen, aber warum funktioniert das nicht?

Antwort

22

Dies ist nichts als ein Fehler im Framework. Die Eigenschaft in der TextBox bekommt Ihren neuen Wert, aber die GUI ist jetzt nicht mehr synchron mit ihrer eigenen TextProperty. Das passiert auch für alle ItemsControl, wenn Sie eine Änderung von SelectedItem vom ViewModel abbrechen wollen und es ist wirklich nervig. Dieser Fehler tritt nicht auf, wenn Sie explizit Binding verwenden.

XAML

<TextBox Text="{Binding Path=MyName, 
         UpdateSourceTrigger=Explicit}" 
     TextChanged="TextBox_TextChanged"/> 

-Code hinter

private void TextBox_TextChanged(object sender, TextChangedEventArgs e) 
{ 
    TextBox textBox = sender as TextBox; 
    textBox.GetBindingExpression(TextBox.TextProperty).UpdateSource(); 
} 

Um sicherzustellen, dass die TextBox GUI ist in der Tat nicht mehr synchron, nur den Wert von TextBox.Text beobachten. Die TextBox wird sagen "123456789___0" zum Beispiel während TextBlock sagt "123456789".

<StackPanel> 
    <TextBox Name="myTextBox" 
      Text="{Binding Path=MyName, 
          UpdateSourceTrigger=PropertyChanged}"/> 
    <TextBlock Text="{Binding ElementName=myTextBox, Path=Text}"/> 
</StackPanel> 
+0

Vielen Dank! Irgendeine Idee, wenn das dem Mutterschiff gemeldet wurde? Wenn nicht, werde ich. –

+0

@SteveOsborn: Haha, ich bin mir nicht sicher, ob das dem Mutterschiff gemeldet wurde :) Ich habe schon einmal nachgeschaut, aber ich habe nichts gefunden, aber es ist ein bisschen schwierig zu wissen, wonach genau gesucht werden soll. Geh und berichte es, lass es mich wissen, wenn du es hast, und ich werde es verbessern. –

+0

https://connect.microsoft.com/VisualStudio/feedback/details/745368/wpf-textbox-binding-doesnt-work-properly –