2012-05-31 16 views
9

Tengo una vista WPF con un TextBox, vinculando el campo Texto a un modelo de vista con UpdateSourceTrigger establecido en PropertyChanged. En la incubadora propiedad en el modelo de vista, tengo una sencilla comprobación para evitar que el texto superior a 10 caracteres:WPF - MVVM - Cuadro de texto que no se sincroniza con la propiedad viewmodel

<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"); 
     } 
    } 
} 

Si el valor no está establecido, todavía RaisePropertyChanged (que simplemente dispara PropertyChanged).

El problema es que cuando escribo el undécimo carácter en la interfaz de usuario, no actualizo _Name. Disparo PropertyChanged, y puedo ver que se llama al acceso get y devuelve la cadena con solo 10 caracteres. Sin embargo, mi TextBox no refleja esto; todavía muestra la cadena con 11 caracteres.

Además de eso, si en el 11º carácter cambio el texto en el colocador a "ERROR", y la propiedad de fuego cambió, el cuadro de texto se actualiza para mostrar el texto modificado.

Entonces, ¿por qué si cambio el texto en el ajustador al valor anterior, la IU no refleja esto?

Sé que hay formas alternativas de manejar los caracteres máx., Pero ¿por qué no funciona?

Respuesta

22

Esto no es más que un error en el marco. La propiedad Text en el TextBox obtiene su nuevo valor pero la GUI ahora no está sincronizada con su propio TextProperty. Esto también ocurre para cualquier ItemsControl cuando desee cancelar un cambio de SelectedItem desde ViewModel y es realmente molesto.

Este error no se produce cuando se usa explícitamente Binding, así que esto puede usarse como una solución alternativa.

Xaml Código

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

detrás

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

Para comprobar que la interfaz gráfica de usuario cuadro de texto a la verdad está fuera de sincronía, simplemente observe el valor de TextBox.Text. El TextBox dirá "123456789___0" por ejemplo, mientras que TextBlock dice "123456789".

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

Gracias! ¿Alguna idea de si esto ha sido reportado a la nave nodriza? Si no, lo haré. –

+0

@SteveOsborn: Jaja, no estoy seguro de si esto ha sido reportado a la nave nodriza :) He buscado antes, pero no he encontrado nada, pero es un poco difícil saber qué buscar exactamente. Adelante e infórmame, házmelo saber cuando lo tengas y lo votaré por encima. –

+0

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

Cuestiones relacionadas