Как сделать привязку происходить из ViewModel - PullRequest
0 голосов
/ 24 ноября 2011

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

В этом примере кажется, что привязка происходит не при нажатии клавиши, а через некоторое время.Мне нужно, чтобы привязка была завершена к тому времени, когда нажата клавиша ввода.Рассмотрим следующий XAML и функцию от виртуальной машины.

Вот XAML текстового поля

<TextBox Text="{Binding TextValue, Mode=TwoWay}" Height="23" Width="300">
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="KeyDown">
            <cmd:EventToCommand Command="{Binding KeyDownCommand}"
                PassEventArgsToCommand="True" />
        </i:EventTrigger>
    </i:Interaction.Triggers>
</TextBox>

KeyDownCommand срабатывает, как и ожидалось, однако значение еще не находится в свойстве TextValue.Если я нажму ввод второй раз, тогда значение будет в свойстве?Вот KeyDownCommand.Конструктор ViewModel правильно устанавливает keyDownCommand.

public RelayCommand<RoutedEventArgs> KeyDownCommand { get; private set; }
private void KeyDownAction(RoutedEventArgs eventArg)
{
    var source = eventArg.OriginalSource as FrameworkElement;
    var e = eventArg as KeyEventArgs;
    if (source != null && e != null && e.Key== Key.Enter)
    {
        e.Handled = true;
        MessageBox.Show(TextValue);
    }
}

Мне кажется, что мне нужен способ "опубликовать" текст TextBox обратно в свойство TextValue виртуальной машины, когда клавиша Enter являетсянажат.Или я что-то упускаю.

Ответы [ 2 ]

2 голосов
/ 24 ноября 2011

Попробуйте установить UpdateSourceTrigger в PropertyChanged при привязке, например:

<TextBox Text="{Binding TextValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Height="23" Width="300">

Теперь свойство модели представления будет обновляться при каждом изменении текста.

Обновление:

Для Silverlight, в качестве альтернативы UpdateSourceTrigger, вы можете использовать следующее простое поведение, которое обновляет источник привязки при изменении текста:

public class TextChangedUpdateSourceBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.TextChanged += OnTextChanged;
    }

    private void OnTextChanged(object sender, TextChangedEventArgs e)
    {
        var bindingExpression = AssociatedObject.GetBindingExpression(TextBox.TextProperty);

        if (bindingExpression != null)
        {
            bindingExpression.UpdateSource();
        }
    }
}

Используйте это так:

<TextBox Text="{Binding TextValue, Mode=TwoWay}" Height="23" Width="300">
    <i:Interaction.Behaviors>
        <b:TextChangedUpdateSourceBehavior />
    </i:Interaction.Behaviors>
</TextBox>
1 голос
/ 24 ноября 2011

Не успел я опубликовать вопрос, как наткнулся на ответ.

Вот исправленное действие KeyDown

private void KeyDownAction(RoutedEventArgs eventArg)
{
    var source = eventArg.OriginalSource as FrameworkElement;
    source.GetBindingExpression(TextBox.TextProperty).UpdateSource();
    var e = eventArg as KeyEventArgs;
    if (source != null && e != null && e.Key== Key.Enter)
    {
        e.Handled = true;
        MessageBox.Show(TextValue);
    }
}

Теперь, когда я набираю это, я осознаю, что я "ломаю" шаблон, поскольку теперь моя ViewModel знает больше о представлении, которое он должен.

...