SIP не позволяет EF автоматически обнаруживать изменение объекта в WP7 - PullRequest
0 голосов
/ 16 февраля 2012

У меня есть проблема при попытке сохранить сущности в БД с использованием техники первого кода.Например, что я делаю, вы можете посмотреть на MSDN Sample .Приложение обычно работает так, как задумано, за исключением одного случая.

Если у меня есть существующая сущность, и я привязываю ее к странице, на которой есть TextBox для хранения поля заголовка и значок AppBar для сохранения (аналогично «Снимок экрана «Новая задача» в приведенной выше ссылке, но со значениями, предварительно заполненными существующей сущностью с двусторонней привязкой), возникает следующая проблема.Если я выбрал TextBox, изменил заголовок и нажал кнопку «Сохранить», он обновляет сущность в памяти, так что теперь в полном списке отображается новый заголовок.Но новый заголовок не сохраняется в БД (он не обнаруживает изменения автоматически).Это странно не только потому, что объект в памяти изменился, но и потому, что если я отменил выбор TextBox, а затем нажал «Сохранить», он сохранит изменения в БД.

Я видел другие вопросы по SOпри некоторых проблемах с обнаружением изменений они предлагают добавить this.Focus() или выделить какой-то другой элемент в начале метода сохранения.Это не помогает в моем случае.Если я не коснусь экрана, чтобы отменить выбор TextBox и скрыть клавиатуру (или нажать клавишу «Return» на клавиатуре, что я и должен сделать. Focus ()), он не обнаружит измененный объект.

Как я могу решить это?Что именно мешает EF обнаруживать изменение объекта, когда клавиатура все еще видна?

1 Ответ

1 голос
/ 21 февраля 2012

Не уверен, что я точно следую тому, что вы описали, но я думаю, что проблема в том, что свойство, к которому вы привязали текстовое поле, не обновляется до тех пор, пока TextChanged не будет запущен в текстовом поле, и это делается в первую очередь, когда вы покидаете текстовое поле, в основном, он потеряет Фокус, если вы нажмете где-то еще.

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

Поведение:

/// <summary>
/// Update property on every keystroke in a textbox
/// </summary>
public class UpdateTextSourceTriggerBehavior : Behavior<TextBox>
{
    protected override void OnAttached()
    {
        this.AssociatedObject.TextChanged += OnTextBoxTextChanged;
    }

    void OnTextBoxTextChanged(object sender, TextChangedEventArgs e)
    {
        var bindingExpression = AssociatedObject.ReadLocalValue(TextBox.TextProperty) as BindingExpression;
        if (bindingExpression != null)
        {
            bindingExpression.UpdateSource();
        }
    }

    protected override void OnDetaching()
    {
        this.AssociatedObject.TextChanged -= OnTextBoxTextChanged;
    }
}

Теперь простоприкрепите это поведение к вашему текстовому полю следующим образом:

<TextBox Text="{Binding YourPropertyName, Mode=TwoWay}">
                <i:Interaction.Behaviors>
                    <UpdateTextSourceTriggerBehavior/>
                </i:Interaction.Behaviors>
            </TextBox>

Это будет постоянно обновлять свойство вашей модели представления, так что при нажатии на сохранить сразу после ввода в текстовое поле будет сохранено правильное значение,Надеюсь, это поможет!

Ура, Андерс

...