2009-05-20 2 views
6

У меня есть окно WPF, которое содержит текстовое поле. Я выполнил команду, которая выполняет на Crtl-S, которая сохраняет содержимое окна. Моя проблема в том, что если текстовое поле является активным элементом управления, и я недавно редактировал текст в текстовом поле, последние изменения в текстовом поле не выполняются. Мне нужно выйти из текстового поля, чтобы получить изменения.EndEdit эквивалент в WPF

В WinForms я обычно называю EndEdit в форме, и все ожидающие изменения будут совершены. Другой альтернативой является использование привязки forPropertyChange, а не onValidation, но я бы предпочел не делать этого.

Что такое эквивалент WPF для EndEdit или каков шаблон для использования в этом типе сценария?

Спасибо,

ответ

4

Чтобы избежать проблем с необходимостью закладки, вы можете просто изменить свойство UpdateSourceTrigger привязки элементов управления. Попробуйте следующее:

<TextBox.Text> 
    <Binding Path="MyProperty" UpdateSourceTrigger="PropertyChanged"/> 
</TextBox.Text> 

Это сообщает WPF обновлять объект-подложку при изменении свойства Text. Таким образом, вам не нужно беспокоиться о том, чтобы уйти. Надеюсь это поможет!

EDIT:

Принятый ответ на следующий вопрос SO обеспечивает возможность автоматического запуска правила проверки для страницы. Вы можете изменить его для вызова UpdateSource() для всех объектов BindingExpression.

Link

+0

Я бы лучше не добавлять UpdateSourceTrigger всем в моей текстовые поля формы, один звонок, чтобы убедиться, что все отложенные изменения «поручены» является то, что я ищу. Ваше предложение похоже на привязку «OnPropertyChange». Это выполнимо, но также вызывает больше событий, чем я хотел бы видеть. Я ищу общий шаблон WPF для решения этой проблемы. Благодарим вас за ответ. – Thies

1

HI, Ну, в то время как с помощью WPF, нужно принять к другому настрою.

Я бы привязал свойство TextBox к одному из своих свойств (Model, ViewModel, Code-Behind, независимо от того, что вас радует). Итак, когда вы обрабатываете CTRL + S, вы просто переходите к свойству clr, которое привязано, и продолжайте счастливо со всеми данными, которые вы хотите.

Надеюсь, что вам помогут, если вам потребуются примеры кода, оставьте мне комментарий. Ariel

5

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

var bindingExpression = txtInput.GetBindingExpression(TextBox.TextProperty); 
bindingExpression.UpdateSource(); 

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

+0

Возможно, это тоже сработает. Принятый ответ для следующего вопроса SO предоставляет возможность автоматически запускать правила проверки для страницы. Я думаю, вы можете изменить его, чтобы вместо этого использовать UpdateSource() для всех объектов BindingExpression. http://stackoverflow.com/questions/127477/detecting-wpf-validation-errors – Pwninstein

+0

Я ищу универсальное решение, которое не требует, чтобы я менял привязку ко всем формам. Что-то, что совершает все текущие изменения. Благодарим вас за ответ. – Thies

+0

Это именно то, что я искал, потому что у меня есть некоторые Attachable Properties, которые будут командами для них, которые требуют, чтобы текст был актуальным. –

3

Я не согласен с ArielBH. Проблема заключается в взаимодействии между клавиатурой и логическим фокусом, и если вы не изменили все триггеры обновления привязки данных к PropertyChanged, вы можете пропустить некоторые обновления исходных данных в определенных сценариях (например, щелчки кнопок на панели инструментов). Например, триггер обновления по умолчанию для TextBox.Text - LostFocus, и нажатие на кнопку панели инструментов не размывает активный фокус TextBox.

Если у вас есть механизм регистрации элементов управления, вы можете принудительно принудительно привязать данные к обновлению источника в том же месте, в котором вы бы вызывали EndEdit в приложении WinForms. Это не аккуратный или элегантный, но он выполняет свою работу.

Если кто-то придумал лучшее решение, я тоже буду уши.

+1

См. Ссылку, которую я опубликовал в своем комментарии к комментарию commongenius, для примера того, как можно было заставить форсировать привязки для обновления. Конечно, приведенный пример не делает именно этого, но может быть легко изменен, чтобы делать то, что вы предлагаете. :) – Pwninstein

5

На основании ответа Pwninstein я теперь внедрил EndEdit в свой общий класс для WPF Views/Windows, который будет искать привязки и принудительно обновлять их, код ниже;

Код под;

private void EndEdit(DependencyObject parent) 
{ 
    LocalValueEnumerator localValues = parent.GetLocalValueEnumerator(); 
    while (localValues.MoveNext()) 
    { 
     LocalValueEntry entry = localValues.Current; 
     if (BindingOperations.IsDataBound(parent, entry.Property)) 
     { 
      BindingExpression binding = BindingOperations.GetBindingExpression(parent, entry.Property); 
      if (binding != null) 
      { 
       binding.UpdateSource(); 
      } 
     } 
    }    

    for(int i=0; i < VisualTreeHelper.GetChildrenCount(parent); i++) 
    { 
     DependencyObject child = VisualTreeHelper.GetChild(parent, i); 
     this.EndEdit(child); 
    } 
} 

protected void EndEdit() 
{ 
    this.EndEdit(this); 
} 

В моей команде Сохранить, теперь я просто вызвать метод EndEdit, и я не придется беспокоиться о других выборе Программисты метода связывания.

+0

Отредактировал свой предыдущий ответ, чтобы включить мои комментарии. Благодаря! Рад, что помогло :) – Pwninstein

+0

Я поддержал это. Отлично работает, но вызывает проблему с включением виртуализации. Изменение ItemSource приводит к тому, что полосы прокрутки перестают работать. Смотрите: [http://stackoverflow.com/questions/8107618/datagrid-scroll-bar-stops-working](http://stackoverflow.com/questions/8107618/datagrid-scroll-bar-stops-working) – CrazyIvan1974

1

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

<Window.BindingGroup> 
    <BindingGroup /> 
</Window.BindingGroup> 

this.BindingGroup.CommitEdit(); 
+0

Спасибо для обратной связи. Это выглядит многообещающе, но сначала мне нужно попробовать. – Thies

Смежные вопросы