Как отложить обновление привязки в WPF - PullRequest
8 голосов
/ 29 января 2009

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

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

Я использовал расширение DelayBinding Пола Стовелла (его сайт сейчас недоступен, поэтому я не могу с ним связаться). Однако я подозреваю, что это является причиной утечки памяти в моем приложении (вызванной тем, что не удаляются обработчики событий).

У кого-нибудь есть еще идеи?

Ответы [ 3 ]

16 голосов
/ 13 марта 2013

Я также опоздал на несколько лет, но если вы используете WPF 4.5+ , теперь для этой цели есть свойство , которое называется Delay.

Описание

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

Пример использования

<TextBlock Text="{Binding Name, Delay=500}"/>
5 голосов
/ 03 мая 2012

Немного опоздал на вопрос здесь (всего на несколько лет :), но для тех, кто заинтересовался, у меня было похожее требование в проекте, поэтому я создал два расширения разметки под названием DelayBindingExtension и DelayMultiBindingExtension.

Они работают как обычно Bindings с добавлением, которое вы можете указать UpdateSourceDelay и / или UpdateTargetDelay, оба из которых являются TimeSpan свойствами. Кроме того, я проверил, что он без утечек (он использует обратный вызов с измененным свойством привязки свойства зависимости через контекст наследования, а не DependencyPropertyDescriptor) .

Пример использования для DelayBinding

<TextBox Text="{db:DelayBinding Path=TextProperty,
                                UpdateSourceTrigger=PropertyChanged,
                                UpdateSourceDelay='00:00:01'}"/>

А для DelayMultiBinding

<cs:ColorSelector.SelectedColor>
    <db:DelayMultiBinding Mode="TwoWay"
                          Converter="{StaticResource ColorConverter}"
                          UpdateSourceDelay="00:00:02"
                          UpdateTargetDelay="00:00:01">
        <Binding Path="Red" />
        <Binding Path="Green" />
        <Binding Path="Blue" />
    </db:DelayMultiBinding>
</cs:ColorSelector.SelectedColor>

Исходный код и пример использования для DelayBinding и DelayMultiBinding можно загрузить здесь .
Если вас интересуют подробности реализации, вы можете ознакомиться с моей записью в блоге об этом здесь: DelayBinding и DelayMultiBinding с Source и Target delay

2 голосов
/ 29 января 2009

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

Во-вторых, если ваша фильтрация занимает много времени, я бы изучил использование CollectionViewSource в вашем ListBox. У Bea Stollnitz есть хороший учебник здесь , и я использовал этот пост , чтобы показать мне, как фильтровать. Когда я переключился, я заметил огромную разницу в скорости по сравнению с другой моей реализацией, даже если они используют одни и те же функции фильтрации. Также CollectionViewSource будет автоматически обрабатывать обновление отфильтрованных элементов, если список, к которому вы привязаны, изменяется, даже на уровне элементов, если вы привязываетесь к ObservableCollection (это первоначальная причина, по которой я изменил на CollectionViewSource).

НТН

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