TheRedEye Ответов: 2

Выполняет ли WPF привязку данных к элементам управления, которые в данный момент не видны?


Я все еще новичок в WPF (родом из Winforms). Я занят приложением WPF, которое будет прослушивать и получать строки через TCPIP и отображать их в виде списков на различных вкладках окна.
Я планирую заполнить несколько наблюдаемых коллекций, когда получу эти строки. Затем эти данные будут привязаны к спискам представлений на нескольких вкладках tabcontrol.

Мой вопрос заключается в том, как влияет на производительность привязка данных с элементами управления, которые не отображаются. Должен ли я обращать внимание на то, какую вкладку пользователь в данный момент просматривает и заполняет только эту конкретную observablecollection? Или WPF знает, какие listviews в данный момент не видны, и выполняет привязку данных только по мере необходимости.

Кроме того, используя этот метод, я ожидаю столкнуться с CrossThreadExceptions (или каким бы то ни было эквивалентом WPF), так что любой совет для этого тоже поможет.

Что я уже пробовал:

Еще ничего не пробовал. Ищу совета.

2 Ответов

Рейтинг:
7

PureNsanity

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

Последняя часть смягчается в WPF с помощью виртуализации. Итак, предположим, что ваш список скрыт или, возможно, имеет только 10 строк, и вы привязываете к нему список из 10 000 элементов. Насколько это повлияет на производительность? Не вдаваясь в обширные подробности виртуализации, этот ответ совсем не подходит для нормального отображения пользовательского интерфейса.

Теперь в этом уравнении есть еще одна вещь, которая может повлиять на производительность, и это получение первоначального списка из 10 000 элементов, верно? Возможно, это сложный вызов базы данных или работа с огромным API... Надеюсь, что этот список загружается лениво, но даже когда вы делаете это, если привязываете данные к списку, эта привязка все равно будет происходить и пытаться инициализировать этот объект, даже если он скрыт, - и это может быть бесполезным расходом.

В этом последнем сценарии вы все еще хотите использовать привязку данных; однако вы хотите инициализировать/заполнить элементы, когда элемент управления фактически находится в поле зрения (т. е. на текущем TabItem в TabControl). Существует множество способов сделать это, но обычно ваше представление вызывает метод/команду инициализации в вашей модели представления. Если представление уже привязано, добавление элементов в существующую коллекцию может вызвать проблемы с перекрестной потоковой передачей; однако если вы установите свойство в новую коллекцию, то этого не произойдет. И если вы работаете с большими коллекциями, как правило, этот подход работает лучше всего, поэтому вы не запускаете уведомления с каждым добавлением.

Как бы то ни было, оба подхода имеют свои плюсы и минусы. Если вы собираетесь выполнять фоновую работу и хотите избежать проблем с потоками, я бы взглянул на эту статью:

Многопоточность в C# .NET 4.5 (Часть 2)[^]


Рейтинг:
0

Graeme_Grant

Если вы используете привязку данных с ObservableCollection, то ответ-да.

Чтобы убедиться, попробуйте это сделать. Создайте новый проект, добавьте список, установите источник данных элементов, добавьте две кнопки, одну для переключения состояния видимости, другую для очистки (не новую) и перезагрузите ObservableCollection с фиктивными данными. Запустите, нажмите кнопку Скрыть, нажмите кнопку Перезагрузить, снова нажмите кнопку Скрыть, чтобы показать. Вы получите подтвержденный ответ.