WPF - MVVM - синхронизация текстового поля со свойством viewmodel

У меня есть представление WPF с TextBox, связывающее текстовое поле с ViewModel с UpdateSourceTrigger, установленным в PropertyChanged. В установщике свойств в ViewModel у меня есть простая проверка, чтобы текст не превышал 10 символов:

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

Если значение не установлено, я все еще RaisePropertyChanged (который просто запускает PropertyChanged).

Проблема в том, что когда я набираю 11-й символ в пользовательском интерфейсе, я не обновляю _Name. Я запускаю PropertyChanged и вижу, как вызывается метод доступа get, и он возвращает строку, содержащую всего 10 символов. Однако мой TextBox не отражает этого; он по-прежнему показывает строку из 11 символов.

Кроме того, если на 11-м символе я изменил текст в установщике на «ОШИБКА», а свойство огня изменилось, TextBox ОБНОВЛЯЕТСЯ обновляться, чтобы показать измененный текст.

Так почему же, если я верну текст в установщике обратно к предыдущему значению, пользовательский интерфейс не отразит это?

Я знаю, что есть альтернативные способы обработки макс символов, но почему это не сработает?

Ответы на вопрос(1)

Решение Вопроса

Это не что иное, как ошибка в структуре.Text недвижимость вTextBox действительно получает ваше новое значение, но графический интерфейс теперь не синхронизирован с его собственнымTextProperty, Это также происходит для любогоItemsControl когда вы хотите отменить изменениеSelectedItem от ViewModel, и это действительно раздражает.

Эта ошибка не происходит при использовании явногоBinding хотя, так что это может быть использовано в качестве обходного пути.

Xaml

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

Code behind

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

Чтобы убедиться, что графический интерфейс TextBox действительно не синхронизирован, просто соблюдайте значениеTextBox.Text,TextBox скажет "123456789 ___ 0" например покаTextBlock говорит "123456789".

<StackPanel>
    <TextBox Name="myTextBox"
             Text="{Binding Path=MyName,
                            UpdateSourceTrigger=PropertyChanged}"/>
    <TextBlock Text="{Binding ElementName=myTextBox, Path=Text}"/>
</StackPanel>
 31 мая 2012 г., 23:35
@Meleak - Спасибо, что указали на это. Я удалил свой пост, чтобы не путать никого.
 31 мая 2012 г., 23:19
Здорово, проголосовал за это. Я опубликую решение проблемы там через несколько дней после того, как они ответят на нее.
 Steve Osborn31 мая 2012 г., 23:14
 31 мая 2012 г., 23:01
@SteveOsborn: Ха-ха, я не уверен, было ли это сообщено материнскому кораблю :) Я смотрел раньше, но ничего не нашел, но немного сложно понять, что именно искать. Идите и сообщите об этом, дайте мне знать, когда у вас есть, и я добавлю это.
 Steve Osborn31 мая 2012 г., 22:56
Спасибо! Есть идеи, если об этом было сообщено материнству? Если нет, я буду.

Ваш ответ на вопрос