при сложной привязке в список объектов к которым можно привязать
Установка привязок границ элементов управления
Настройку производят на этапе создания формы для каждого элемента управления или группы выделенных элементов. Привязке доступны элементы управления любого типа.
Существует два вида привязок: ручная (простая и сложная привязка границ элементов) и автоматическая привязки (авто-привязка).
При ручной привязке производится установка пользователем привязок. При автопривязке механизм привязки зависит от вида элемента управления.
Ручная привязка
Настройка привязок производится в окне «Привязка границ для элемента …«, запускаемого по ссылке Установить правила свойства Привязка границ категории Расположение.
Допускается установка привязок для группы выделенных элементов.
Простая привязка границ
Настройка привязок производится на закладке «Простая«.
Группа реквизитов окна «Привязать горизонтально» предназначена для настройки поведения элемента при горизонтальном изменении размеров формы.
Действия по настройке привязки в этих группах одинаковы.
При простой привязке элемент может быть привязан как к самой форме или панели, а также к элементам управления типа «Разделитель«.
В реквизите «Тип привязки» указывается способ привязки:
Во всех случаях, кроме пропорциональной привязки, элемент управления привязан жестко: при такой привязке изменение положения границ элемента относительно привязанной границы не происходит.
Аналогично производится настройка поведения элемента при вертикальном изменении размеров формы.
Реквизит «Ручная привязка» окна «Привязка границ для элемента …» предназначен для блокировки механизма автопривязки.
Для сброса всех привязок нажмите кнопку «Сбросить все привязки«.
Сложная привязка границ
Привязка производится на закладке «Сложная«. На закладке находятся четыре группы реквизитов, заключенных в рамки. Каждая группа осуществляет привязку одной границы элемента. Заголовок рамки группы соответствует названию привязываемой границы элемента (например, группа «Левая граница» отвечает за привязку левой границы элемента). Действия по настройке привязки в этих группах одинаковы, поэтому рассмотрим настройку на примере привязки одной границы.
Реквизиты «Привязать к:» осуществляют первичную привязку. Следует выбрать объект, к которому привязывается граница, затем указывается, к какой границе этого объекта будет привязан элемент. В списке границ выберите границу, к которой будет привязываться элемент. В список объектов включаются все элементы управления текущей страницы формы. В том числе и сам привязываемый элемент управления, чтобы привязать одну границу к другой. Это делается для установки таких привязок, которые не приводят к изменению размеров элемента (за исключением привязки к центру), но элемент при этом может быть привязан к другим элементам области. Если в этом случае нужно будет перепривязать элемент к другому элементу, то достаточно будет изменить привязку только одной его границы.
Реквизит «Сохранять пропорции до:» осуществляет вторичную привязку.
Для сброса всех привязок нажмите кнопку «Сбросить все привязки«.
Автоматическая привязка границ
Привязки, установленные автоматически, не всегда могут соответствовать желаемому результату, поэтому стратегию автопривязок необходимо менять вручную.
Режим автопривязок можно отменять. Если при отключенном режиме автопривязок требуется, чтобы элементы управления «отслеживали» изменение размеров формы, то разработчик формы должен установить привязки вручную.
В случае повторной установки свойства Автопривязка границ программно ко всем элементам формы, для которых не установлен режим «Ручная привязка«, будет применена автоматическая привязка. Если до этого элемент был привязан, но флажок «Ручная привязка» не был установлен, то привязки этого элемента также будут изменены.
Каждый новый элемент также будет автоматически привязываться к границам формы. Более того, при перемещении элемента будут изменяться и его привязки.
Для установки автоматической привязки границ установите свойство Авто-привязка границ.
Проверка привязок
Привязка элементов управления Windows Forms к данным в Visual Studio
вы можете отображать данные для пользователей приложения, привязывая данные к Windows Forms. чтобы создать эти элементы управления с привязкой к данным, перетащите элементы из окна источники данных на конструктор Windows Forms в Visual Studio.
Перед перетаскиванием элементов можно задать тип элемента управления, к которому необходимо выполнить привязку. Различные значения отображаются в зависимости от выбора самой таблицы или отдельного столбца. Можно также задать пользовательские значения. Для таблицы сведения означает, что каждый столбец привязан к отдельному элементу управления.
Элементы управления BindingSource и BindingNavigator
Компонент BindingSource служит двум целям. Во-первых, он предоставляет уровень абстракции при привязке элементов управления к данным. Элементы управления в форме привязываются к BindingSource компоненту, а не непосредственно к источнику данных. Во-вторых, он может управлять коллекцией объектов. Добавление типа в BindingSource создает список этого типа.
Дополнительные сведения о BindingSource компоненте см. в следующих статьях:
элемент управления BindingNavigator предоставляет пользовательский интерфейс для навигации по данным, отображаемым Windows приложением.
Привязка к данным в элементе управления DataGridView
Поведение DataGridView и BindingNavigator можно настроить, щелкнув смарт-тег в правом верхнем углу каждого из них:
Привязка к данным в отдельных элементах управления
При привязке источника данных к подробностям каждый столбец в наборе данных привязывается к отдельному элементу управления.
Обратите внимание, что каждый элемент управления имеет смарт-тег. Этот тег включает настройки, применяемые только к этому элементу управления.
Форма, элементы управления
Привязки элементов управления
В отличие от версии 7.7, когда при масштабировании формы реквизиты диалога неконтролируемо «разбредались» по форме, в версии 8.0 для каждого реквизита диалога формы возможна настройка привязок границ к форме (простая привязка) и к расположенным рядом другим элементам управления (сложная привязка).
В диалоговом окне «Привязка границ для элемента управления», вызываемого из палитры свойств элемента управления из категории свойств «Расположение», можно на закладке «Простая» установить простые привязки объекта:
При простой привязке элемент может быть привязан как к самой форме или панели, а также к элементам управления типа «Разделитель». При этом в список объекта включаются только те разделители, которые попадают в зону пересечения с привязываемым элементом.
На закладке «Сложная» можно установить привязки каждой границы объекта, как к другим элементам, так и к границам формы. При создании новой формы, в её свойствах всегда установлено «Автоматическая привязка». Система автоматически настраивает правила привязок. Если в форме настройки привязок были настроены пользователем, то установка данного правила приведет к потере существующих настроек.
Появились маркеры положения элемента на форме, сигнализирующие о несовпадении координат по вертикали или горизонтали по отношению к ближайшим элементам управления. Наличие привязки показывается специальным маркером , расположенным рядом с маркерами сторон элемента.
Маркеры появляются, когда два элемента управления находятся в непосредственной близости друг от друга (зона в +16 пикселей от ближайшей границы установленного элемента).
Синие выравнивающие маркеры указывают желаемое направление перемещения элемента управления для выравнивания его по одной из границ соседнего элемента управления:
Красные выравнивающие маркеры указывают желаемое направление перемещения элемента управления в случае, когда он перекрывает другой элемент управления:
Также редактор поддерживает операции выравнивания, изменения размеров и порядка для группы элементов управления:
В диалоге показывается дерево всех элементов управления, размещенных в текущей форме.
Справа от имени элемента управления может размещаться пиктограмма, вид которой показывает на особенности расположения данного элемента. Пиктограммами показывается наложение элемента управления на другой элемент, отсутствие выравнивания. В случае полного расположения над или под другим элементом показывается прямоугольник с красным пунктиром внутри.
Редактор форм поддерживает использование выравнивающих линий, которые служат для облегчения выравнивания и взаимного расположения элементов управления формы. Выравнивающие линии могут отсутствовать. Для установки режима использования выравнивающих линий в свойствах формы необходимо установить «Использовать выравнивающие линии». Если свойство установлено, то по умолчанию каждая страница формы содержит выравнивающие линии по периметру формы. Это краевые выравнивающие линии. Все элементы управления располагаются на странице в пределах, установленных этими линиями.
На странице можно расположить дополнительные вертикальные и горизонтальные выравнивающие линии (в контекстном меню выбрать пункт «Добавить : выравнивающую линию») и осуществить по ним привязку места расположения элементов управления. Для удаления выравнивающей линии в контекстном меню необходимо выбрать пункт «Удалить выравнивающую линию».
Если требуется удалить все выравнивающие линии, в контекстном меню формы необходимо выбрать пункт «Удалить все выравнивающие линии». В этом случае сбрасываются все дополнительные выравнивающие линии, а краевые линии устанавливаются по периметру формы с отступом.
Невидимые выравнивающие линии редактор создает автоматически после того, как два или более элемента управления выравнены по любой из границ. Например, если два поля одинакового размера были выровнены по левой границе, то невидимая выравнивающая линия будет создана вдоль правых выровненных границ этих полей.
Порядок обхода элементов управления
Для возможности интерактивной настройки порядка обхода элементов управления формы необходимо в палитре свойств формы снять флажок «Автопорядок обхода».
Если мы хотим продолжить и нажмем кнопку «Да», то будет открыто окно «Настройка порядка обхода».
Задание 6
Настройте порядок обхода элементов в форме документа «Акт об оказании услуг».
Обновление данных формы
Ваш браузер устарел, пожалуйста обновите ваш браузер пройдя по ссылке www.microsoft.com/download
Нужно было программно установить видимость таблице посредине формы, долго мучался, пока разобрался с этим механизмом.
Решение, понятно, для обычных форм) в управляемых за нас делают разрабы)
Нашел типовое решение через изменение высоты элементов. Но, как я и думал, можно проще, только привязками и сверткой.
И нашел рабочий алгоритм действий. Обработка с открытым кодом, можете посмотреть реализацию и использовать для своих творческих нужд.
Так как сам на данную публикацию потратил день для создания примера, не считаю ее дорогой! Ваше время ценнее. Надеюсь, кому-то пригодится для примера работы с программным изменением видимости на форме!
Тестировал на 8.2.19.
Скачать файлы
Специальные предложения
Программная свертка элементов на форме
К тому же цена в 5 стартмани как бы намекает, что автор толкает этот антиквариат в расчете на Буратино.
у меня пост-праздничный синдром и все кажется кривым, корявым и недосказанным, простите.
К тому же цена в 5 стартмани как бы намекает, что автор толкает этот антиквариат в расчете на Буратино.
у меня пост-праздничный синдром и все кажется кривым, корявым и недосказанным, простите.
Сейчас с похожим вожусь, но там сразу несколько элементов нужно сворачивать, а они привязанны друг к другу
Левый эл1
Левый эл2
Эл свертки 1
Эл свертки 2
Эл свертки 3
Эл свертки 4
Эл свертки 5
И сворачивает любые элементы хорошо, но вот когда разворачивает, тч1 которая привязана к нижней границе Эл свертки 5, через раз остаётся на месте, а элементы все на неё лезут ), не сталкивались с таким?
P.S. Даже если закрыть и открыть форму ей всё так же плохо) только перезапуск помогает)
Обновление 13.05.19 17:00
См. также
Альтернативный способ добавления элементов и реквизитов на формы Промо
Предлагаю альтернативный вариант добавления динамически создаваемых элементов и реквизитов на форму.
09.09.2019 17857 35 bmk74 7
Выделение текущей строки в отчете (сделать сразу во всех отчетах и ничего не сломать)
Как за 10 минут упростить работу с отчётами программистам и пользователям. Добавить ВО ВСЕ ОТЧЁТЫ механизм автоматического выделения текущей строки отчёта (той, на которой установлен курсор). И ПРИ ЭТОМ НИЧЕГО НЕ СЛОМАТЬ.
17.10.2021 2614 5 Патриот 48
Самые красивые шахматы для 1С на управляемых формах
Здравствуйте, представляем Вашему вниманию классическую игру – Шахматы! Написана игра средствами 1С, на управляемых формах. Программный код представляет собой с аккуратностью составленную систему, содержащую лаконичные логические приемы и описательные имена переменных, объектов и функций. Программа полностью отлажена и многократно протестирована. Оригинальный авторский дизайн фигур, иконок и кнопок приятен глазу. Игра содержит большое количество функций, настроек и режимов игры, включая сетевую игру, тренировку с ботом или игру на двоих. Не упустите возможность найти ряд технических решений, применимых для реализации различных задач, а также поиграть в вечную игру с отличным оформлением! Желающие научиться программировать на управляемых формах могут многое почерпнуть в этой конфигурации.
18.02.2021 5611 13 compmir 30
Интерактивная справка по объектам 1С (подключаемое расширение)
База знаний, подключаемая к объектам основной базы. Пополняется интерактивно, формируется в виде статей прямо в 1С (текст, картинки, таблицы, ссылки). Есть возможность прикрепления файлов, привязки к объектам 1С, возможности рейтинга и комментирования пользователями.
29.09.2020 15795 82 sapervodichka 47
Расширенная настройка динамического списка УФ Промо
Открывая управляемую форму выбора и не увидев там видимых в форме списка элементов, часто хочется узнать причину их отсутствия там, т. е. какой наложен отбор. Но стандартная настройка списка управляемой формы показывает только пользовательские настройки, скрывая от пользователя фиксированный отбор. Предлагаю вам расширение конфигурации с расширенной настройкой динамического списка, отображающей пользователю кроме пользовательских настроек еще фиксированные.
31.05.2017 39174 161 tormozit 25
Привязка данных в WPF имеет несколько преимуществ перед традиционными моделями, включая внутреннюю поддержку привязки данных широким диапазоном свойств, гибкое представление данных пользовательского интерфейса, а также четкое разделение бизнес-логики и пользовательского интерфейса.
В этой статье сначала будут рассматриваться основные понятия привязки данных в WPF, а затем — использование класса Binding и других возможностей привязки данных.
Понятие привязки данных
Основные понятия привязки данных
Независимо от того, какой элемент привязывается и какой источник данных используется, каждая привязка всегда соответствует модели, показанной на приведенном ниже изображении.
Как показано на рисунке, привязка данных является, по существу, мостом между целью привязки и источником привязки. На рисунке представлены следующие основные концепции привязки данных WPF.
Как правило, каждая привязка состоит из четырех компонентов:
Параметр | Значение |
---|---|
Target | TextBox |
Целевое свойство | Text |
Исходный объект | Employee |
Путь к значению исходного объекта | Name |
Целевое свойство должно быть свойством зависимостей.
Важно помнить, что при связывании целевой объект привязки привязывается к источнику привязки. Например, при отображении некоторых базовых данных XML в ListBox с помощью привязки данных вы привязываете ListBox к XML-данным.
Контекст данных
Можно настроить разрешение привязки с использованием определенного объекта, а не контекста данных. Явное указание исходного объекта используется, например, при привязке цвета переднего плана объекта к цвету фона другого объекта. В этом случае контекст данных не нужен, так как привязка разрешается между этими двумя объектами. Но если для привязки не указан конкретный исходный объект, используется разрешение на основе контекста данных.
При изменении свойства DataContext все привязки, на которые может повлиять контекст данных, оцениваются повторно.
Направление потока данных
Как показывает стрелка на приведенном выше рисунке, поток данных связывания может идти от цели привязки к источнику привязки (например, исходное значение изменяется, когда пользователь изменяет значение TextBox ) или от источника привязки к цели привязки (например, содержимое TextBox обновляется при изменениях в источнике привязки), если источник привязки предоставляет соответствующие уведомления.
Возможно, требуется, чтобы в приложении пользователи могли изменить данные и передать их обратно объекту источника. Или может потребоваться не предоставлять пользователям возможности обновления источника данных. Для управления потоком данных можно задать Binding.Mode.
На следующем рисунке показаны различные типы потоков данных.
ПривязкаOneWay приводит к автоматическому изменению свойства цели при изменении свойства источника, но изменения свойства цели не передаются обратно к свойству источника. Этот тип привязки подходит, если привязываемый элемент управления неявно доступен только для чтения. Например, можно привязаться к источнику, такому как биржевые сводки, или, возможно, свойство цели не имеет интерфейса для внесения изменений, например, цвета фона привязанной к данным таблицы. Если нет необходимости отслеживать изменения целевого свойства, можно работать в режиме привязки OneWay — в этом случае удастся избежать издержек режима привязки TwoWay.
ПривязкаTwoWay приводит к изменению либо исходного свойства, либо целевого свойства для автоматического обновления другого свойства. Этот тип привязки подходит для изменяемых форм или других полностью интерактивных сценариев пользовательского интерфейса. Большинство свойств по умолчанию применяют привязку OneWay, но некоторые свойства зависимости (обычно это свойства пользовательских элементов управления, таких как TextBox.Text и CheckBox.IsChecked) по умолчанию имеют значение привязки TwoWay. Существует способ определить программно, использует ли свойство зависимостей односторонние или двухсторонние привязки по умолчанию: для этого нужно получить метаданные свойства, воспользовавшись методом DependencyProperty.GetMetadata, а затем проверить логическое значение свойства FrameworkPropertyMetadata.BindsTwoWayByDefault.
OneWayToSource — это обратная привязка OneWay; она обновляет свойство источника при изменении свойства цели. Одним из примеров является пересчет исходного значения из пользовательского интерфейса.
На изображении не показана привязка OneTime, которая приводит к инициализации целевого свойства исходным свойством, но последующие изменения при этом не распространяются. Если в контексте данных производятся изменения или меняется объект, это изменение не отражается в свойстве цели. Этот тип привязки подходит, если приемлемо использовать снимок текущего состояния или данные действительно являются статичными. Кроме того, этот тип привязки полезен, если нужно инициализировать целевое свойство с использованием какого-либо значения из исходного свойства, а контекст данных заранее неизвестен. Этот режим, по сути, — упрощенная форма привязки OneWay, которая обеспечивает более высокую производительность в случаях, когда значение в источнике не меняется.
Чтобы обнаружить изменения источника (применимые к привязкам OneWay и TwoWay), источник должен реализовать подходящий механизм уведомления об изменении свойств, например INotifyPropertyChanged. См. практическое руководство по реализации уведомления об изменении свойства (.NET Framework) в качестве примера реализации INotifyPropertyChanged.
Свойство Binding.Mode содержит дополнительные сведения о режимах привязки и пример того, как указать направление привязки.
Что инициирует обновления источника
Привязки, которые являются TwoWay или OneWayToSource, ожидают изменений в свойстве цели и распространяют их обратно в источник, что называется обновлением источника. Например, можно изменять текст элемента TextBox для изменения базового значение источника.
Но обновляется ли значение в источнике во время изменения текста или когда изменения текста завершается, а элемент управления теряет фокус? Свойство Binding.UpdateSourceTrigger определяет, что инициирует обновление источника. Точки правой стрелки на следующем рисунке иллюстрируют роль свойства Binding.UpdateSourceTrigger.
Если значение UpdateSourceTrigger равно UpdateSourceTrigger.PropertyChanged, то значение, на которое указывает стрелка вправо TwoWay или привязки OneWayToSource, обновляется, как только изменяется свойство цели. Однако если значение UpdateSourceTrigger равно LostFocus, то это значение обновляется с новым значением, только когда целевое свойство теряет фокус.
В следующей таблице приведен пример сценария для каждого значения UpdateSourceTrigger с использованием TextBox в качестве примера.
Значение UpdateSourceTrigger | Когда обновляется значение источника | Пример сценария для TextBox |
---|---|---|
LostFocus (по умолчанию для TextBox.Text) | Возникает при потере фокуса элементом управления TextBox | TextBox, связанный с логикой проверки (см. раздел ниже Проверка данных) |
PropertyChanged | При вводе данных в TextBox. | Элементы управления TextBox в окне комнаты чата. |
Explicit | Когда приложение вызывает UpdateSource. | Элемент управления TextBox в редактируемой форме (исходные значения обновляются только при нажатии пользователем кнопки отправки). |
Пример привязки данных
Привязку данных можно рассмотреть на примере следующего пользовательского интерфейса приложения со страницы примера привязки данных, в котором отображается список элементов аукциона.
Приложение демонстрирует следующие возможности привязки данных.
Содержимое ListBox привязано к коллекции объектов AuctionItem. Объект AuctionItem имеет такие свойства, как Description, StartPrice, StartDate, Category и SpecialFeatures.
Типом свойства StartDate является DateTime, который возвращает дату, включая время с точностью до миллисекунды. В этом приложении пользовательский преобразователь использовался для отображения даты в укороченном формате. Сведения о преобразователях см. в разделе Преобразование данных.
При нажатии кнопки Добавить продукт появляется следующая форма.
Пользователь может изменить поля формы, просмотреть список продуктов с помощью панелей краткого и подробного предварительного просмотра и выбрать Submit для добавления данных нового продукта. К новой записи будут применимы все существующие настройки группировки, фильтрации и сортировки. В этом конкретном случае элемент, введенный на приведенном выше рисунке, будет отображаться как второй элемент в категории Компьютер.
На этом рисунке не показана логика проверки, предоставленная в элементе управления Start Date TextBox. Если пользователь вводит недопустимую дату (недопустимый формат или прошедшую дату), он будет уведомлен с помощью ToolTip и красного восклицательного знака рядом с TextBox. Сведения о создании логики проверки см. в разделе Проверка данных.
Прежде чем перейти к другим описанным выше возможностям связывания данных, обсудим основные понятия, важные для понимания привязки данных WPF.
Создание привязки
Подводя итог некоторым основным понятиям, описанным в предыдущих разделах, следует сказать, что привязка устанавливается с помощью объекта Binding и каждая привязка обычно состоит из четырех компонентов: цели привязки, свойства цели, источника привязки и пути к используемому значению источника. Этот раздел описывает установку привязки.
Рассмотрим следующий пример, в котором объектом источника привязки является класс с именем MyData, определенный в пространстве имен SDKSample. В качестве демонстрационного примера MyData имеет строковое свойство с именем ColorName со значением Red. Таким образом, в этом примере создается кнопка с красным фоном.
Дополнительные сведения о синтаксисе объявления привязки и примеры настройки привязки в коде см. в разделе Общие сведения об объявлении привязок.
Если применить этот пример к основной диаграмме, полученное изображение будет выглядеть следующим образом. На этом рисунке описывается привязка OneWay, так как свойство Background поддерживает привязку OneWay по умолчанию.
Может возникнуть вопрос, почему эта привязка работает, даже несмотря на то, что свойство ColorName имеет тип «строка», а свойство Background имеет тип Brush. Эта привязка происходит в результате преобразования типов по умолчанию, которое обсуждается в разделе Преобразование данных.
Указание источника привязки
Обратите внимание, что в предыдущем примере источник привязки задается путем установки свойства DockPanel.DataContext. Затем Button наследует значение DataContext от DockPanel, которое является его родительским элементом. Повторим, что объект источника привязки является одним из четырех необходимых компонентов привязки. Таким образом, без указания объекта источника привязки эта привязка не имела бы смысла.
Есть несколько способов для указания объекта источника привязки. С помощью свойства DataContext родительского элемента удобно привязывать несколько свойств к одному источнику. Однако иногда удобнее указывать источник привязки в отдельных объявлениях привязки. В предыдущем примере вместо использования свойства DataContext можно указать источник привязки, задав свойство Binding.Source непосредственно в объявлении привязки кнопки, как показано в следующем примере.
Кроме установки свойства DataContext непосредственно на элемент, наследуя значение DataContext из родительского элемента (например, кнопки в первом примере), и явного указания источника привязки путем установки свойства Binding.Source для привязки (например, кнопку в последнем примере), можно также использовать свойство Binding.ElementName или свойство Binding.RelativeSource, чтобы указать источник привязки. Свойство ElementName полезно при привязке к другим элементам в приложении, например при использовании ползунка для настройки ширины кнопки. Свойство RelativeSource полезно, когда привязка указана в ControlTemplate или Style. Дополнительные сведения см. в разделе Общие сведения об источниках привязки.
Указание пути к значению
Если источник привязки является объектом, используйте свойство Binding.Path для указания значения, используемого для привязки. Если вы выполняете привязку к данным XML, для указания значения используется свойство Binding.XPath. В некоторых случаях удобно применять свойство Path, даже если это данные XML. Например, если требуется получить доступ к свойству Name возвращаемого XmlNode (в результате выполнения запроса XPath), в дополнение к свойству XPath следует использовать свойство Path.
Дополнительные сведения см. в описаниях свойств Path и XPath.
Хотя мы и подчеркнули, что путь Path к используемому значению является одним из четырех необходимых компонентов привязки, в сценариях, когда требуется выполнить привязку ко всему объекту, используемое значение будет таким же, как у объекта источника привязки. В этих случаях можно не указывать Path. Рассмотрим следующий пример.
В приведенном выше примере используется синтаксис пустой привязки:
Кроме привязки к коллекции, этот сценарий полезен также для привязки ко всему объекту, а не только к одному свойству объекта. Например, если объект источника является объектом типа String, вы можете захотеть выполнить привязку к самой строке. Другим распространенным сценарием является необходимость привязки элемента к объекту с несколькими свойствами.
Может потребоваться применить пользовательскую логику, чтобы данные имели смысл для свойства целевого объекта привязки. Пользовательская логика может иметь вид пользовательского преобразователя, если тип преобразования по умолчанию не существует. Сведения о преобразователях см. в разделе Преобразование данных.
Привязка и класс BindingExpression
Прежде чем перейти к другим возможностям и использованию привязки данных, полезно ознакомиться с классом BindingExpression. Как было показано в предыдущих разделах, класс Binding является классом высокого уровня для объявления привязки. Он предоставляет множество свойств, которые позволяют указать характеристики привязки. Связанный класс BindingExpressionявляется базовым объектом, поддерживающим связь между источником и целью. Привязка содержит всю информацию, которая может использоваться совместно в нескольких выражениях привязки. BindingExpression — это выражение экземпляра, которое не может быть общим и содержит все сведения об экземпляре Binding.
Один и тот же объект myBinding можно использовать для создания других привязок. Например, объект myBinding можно использовать для привязки текстового содержимого флажка к ColorName. В этом сценарии будут два экземпляра BindingExpression, совместно использующие объект myBinding.
Объект BindingExpression возвращается путем вызова GetBindingExpression для объекта, привязанного к данным. В следующих статьях демонстрируются некоторые случаи использования класса BindingExpression.
Преобразование данных
В разделе Создание привязки кнопка имеет красный цвет, так как ее свойство Background привязано к строковому свойству со значением «Red». Это строковое значение работает, так как преобразователь типов находится в типе Brush для преобразования строкового значения в Brush.
Если добавить эти сведения на рисунок из раздела Создание привязки, схема будет выглядеть следующим образом.
Однако что делать, если вместо свойства строкового типа объект источника привязки имеет свойство Color типа Color? В этом случае для создания привязки в первую очередь необходимо преобразовать значение свойства Color в нечто, что примет свойство Background. Понадобится создать пользовательский преобразователь, реализовав интерфейс IValueConverter, как показано в следующем примере.
Дополнительные сведения см. в разделе IValueConverter.
Теперь пользовательский преобразователь используется вместо преобразования по умолчанию и схема выглядит следующим образом.
Таким образом, преобразования по умолчанию могут быть доступны благодаря преобразователям типов, присутствующим в типе, к которому производится привязка. Такое поведение будет зависеть от того, какие преобразователи типов доступны в целевом объекте. Если существуют какие-то сомнением, создайте свой собственный преобразователь.
Ниже приведены некоторые типовые сценарии, где имеет смысл реализация преобразователя данных.
Данные должны отображаться по-разному в зависимости от региональных стандартов. Например, можно реализовать преобразователь валюты или преобразователь даты/времени в календаре на основе соглашений, используемых в определенных региональных стандартах.
Используемые данные не обязательно предназначены для изменения текстового значения свойства. Они могут применяться для изменения некоторых других значений, например источника изображения, цвета или стиля отображаемого текста. Преобразователи могут использоваться в данном экземпляре для преобразования привязки неподходящего свойства, например привязки текстового поля к свойству Background ячейки таблицы.
К одним и тем же данным можно привязать несколько элементов управления или несколько свойств элементов управления. В этом случае основная привязка может просто отображать текст, тогда как другие привязки обрабатывают специфичные проблемы отображения, но они по-прежнему используют одну и ту же привязку в качестве исходных данных.
В целевом свойстве есть набор привязок, который называется MultiBinding. Чтобы получить конечное значение из значений привязок, для MultiBinding используется пользовательский IMultiValueConverter. Например, цвет может быть вычислен из соотношения красного, синего и зеленого значений, которые могут быть значениями одних и тех же или разных объектов источника привязки. Примеры и сведения см. в MultiBinding.
Привязка к коллекциям
Объект источника привязки может рассматриваться как отдельный объект, свойства которого содержат данные, или как коллекция данных полиморфных объектов, часто группируемых вместе (например, в результате запроса к базе данных). До сих пор мы обсуждали привязку только к отдельным объектам. Однако распространенным сценарием также является привязка к коллекции данных. Например, обычным сценарием является использование ItemsControl как ListBox, ListView или TreeView для отображения коллекции данных, например, в приложении, показанном в разделе Понятие привязки данных.
К счастью, наша основная схема по-прежнему применима. При привязке ItemsControl к коллекции схема выглядит следующим образом:
Как показано на данной схеме, для привязки свойства ItemsControl к объекту коллекции свойство ItemsControl.ItemsSource является свойством, которое необходимо использовать. ItemsSource можно представить как содержимое ItemsControl. Привязка — OneWay, потому что свойство ItemsSource поддерживает привязку OneWay по умолчанию.
Способы реализации коллекций
Можно перечислить любую коллекцию, которая реализует интерфейс IEnumerable. Однако чтобы настроить динамические привязки таким образом, чтобы вставки и удаления элементов в коллекции автоматически обновляли пользовательский интерфейс, в коллекции должен быть реализован интерфейс INotifyCollectionChanged. Этот интерфейс предоставляет событие, которое должно вызываться при каждом изменении коллекции.
Представления коллекций
Так как ItemsControl привязан к коллекции данных, могут потребоваться сортировка, фильтрация и группировка данных. Для этого используются представления коллекций, которые являются классами, реализующими интерфейс ICollectionView.
Понятие о представлениях коллекций
Представление коллекции — это слой, расположенный в верхней части связанной исходной коллекции, с помощью которого можно перемещаться по исходной коллекции и просматривать ее содержимое на основе запросов сортировки, фильтрации и группировки, не изменяя саму коллекцию. В представлении коллекции также поддерживается указатель на текущий элемент коллекции. Если исходная коллекция реализует интерфейс INotifyCollectionChanged, изменения, вызванные событием CollectionChanged, передаются в представления.
Так как представления не меняют базовые исходные коллекции, каждая исходная коллекция может иметь несколько связанных с ней представлений. Например, имеется коллекция объектов Task. С помощью представлений можно отображать одни и те же данные различными способами. Например, в левой части страницы можно отображать задачи, отсортированные по приоритету, а справа — сгруппированные по областям.
Создание представления
Одним из способов создания и использования представления является непосредственное создание объекта представления и затем использование его в качестве источника привязки. В качестве примера рассмотрим приложение Пример привязки данных, показанное в разделе Понятие привязки данных. Приложение реализовано таким образом, что ListBox привязывается к представлению коллекции данных, а не к коллекции данных напрямую. Следующий пример извлекается из приложения Пример привязки данных. Класс CollectionViewSource является XAML-прокси класса, который наследуется от CollectionView. В данном конкретном примере Source представления привязывается к коллекции AuctionItems (типа ObservableCollection ) текущего объекта приложения.
Затем ресурс listingDataView служит источником привязки для элементов в приложении, таких как ListBox.
В приведенной ниже таблице показано, какие типы данных представления созданы в качестве представления коллекции по умолчанию либо объектом CollectionViewSource на основе типа исходной коллекции.
Тип исходной коллекции | Тип представления коллекции | Примечания |
---|---|---|
IEnumerable | Внутренний тип, основанный на CollectionView | Невозможно группировать элементы. |
IList | ListCollectionView | Самый быстрый. |
IBindingList | BindingListCollectionView |
Использование представления по умолчанию
Один из способов создания и использования представления коллекции заключается в указании представления коллекции в качестве источника привязки. WPF также создает представление коллекции по умолчанию для каждой коллекции, используемой в качестве источника привязки. Если выполнить привязку непосредственно к коллекции, WPF выполняет привязку к представлению коллекции по умолчанию. Данное представление по умолчанию совместно используется всеми привязками к одной и той же коллекции, поэтому изменения, внесенные в представление по умолчанию одним привязанным элементом управления либо кодом (например, сортировка или изменение указателя на текущий элемент, что будет рассмотрено ниже), распространяются на все привязки к одной коллекции.
Использование представлений коллекций с таблицами данных ADO.NET
Для улучшения производительности представления коллекции для ADO.NET DataTable или DataView объектов делегируют сортировку и фильтрацию DataView, что приводит к тому, что сортировка и фильтрация совместно используются всеми представлениями коллекции источника данных. Чтобы включить возможность независимой сортировки и фильтрации для каждого представления коллекции, инициализируйте каждое представление коллекции с использованием собственного объекта DataView.
Сортировка
Как уже отмечалось ранее, представления могут применять сортировку для коллекции. Так как данные находятся в базовой коллекции, они могут иметь или не иметь некий порядок следования. Представление коллекции позволяет установить порядок или изменить порядок, используемый по умолчанию, на основе введенных признаков сравнения. Так как это представление данных на стороне клиента, распространен сценарий, когда пользователь сортирует столбцы табличных данных по значениям, содержащимся в столбце. С использованием представлений управляемая пользователем сортировка может применяться еще раз без необходимости внесения изменений в основную коллекцию или создания повторного запроса к содержимому коллекции. Пример см. в статье Практическое руководство. Сортировка столбцов GridView при нажатии на заголовок (.NET Framework).
В следующем примере показана логика сортировки для флажка «Sort by category and date» (Сортировать по категории и дате) в CheckBox пользовательского интерфейса приложения, описанного в подразделе Понятие привязки данных.
Фильтрация
Представления могут также применять фильтр к коллекции, так чтобы представление отображало только определенное подмножество полной коллекции. Возможна фильтрация по условию в данных. Например, как показано в приложении из подраздела Понятие привязки данных, флажок CheckBox «Show only bargains» (Показывать только товары по сниженным ценам) содержит логику фильтрации товаров с ценой 25 долл. США и выше. Следующий код выполняется для установки ShowOnlyBargainsFilter в качестве обработчика событий Filter при выборе CheckBox.
Обработчик события ShowOnlyBargainsFilter реализуется следующим образом.
Если вместо CollectionViewSource используется один из классов CollectionView, для указания обратного вызова следует использовать свойство Filter. Пример см. в статье Практическое руководство. Фильтрация данных в представлении (.NET Framework).
Группирование
За исключением внутреннего класса, предназначенного для просмотра коллекции IEnumerable, все представления коллекций поддерживают функцию группировки, которая позволяет пользователю логически разбить коллекцию в представлении коллекции на группы. Группы могут быть явными, если пользователь предоставляет список групп, или неявными, если эти группы создаются динамически в зависимости от данных.
В следующем примере показана логика флажка «Группировка по категориям» CheckBox.
Указатели на текущий элемент
В представлениях также присутствует понятие текущего элемента. Существует возможность перемещаться по объектам в представлении коллекции. При переходе перемещается указатель элемента, позволяющий извлечь объект, расположенный в определенном расположении в коллекции. Пример см. в статье Практическое руководство. Перемещение по объектам в Data CollectionView (.NET Framework).
Поскольку WPF выполняет привязку к коллекции только с помощью представления (либо указанного пользователем, либо представления коллекции по умолчанию), для всех привязок к коллекциям имеется указатель на текущий элемент. При привязке к представлению символ косой черты («/») в значении Path указывает на текущий элемент представления. В следующем примере контекст данных является представлением коллекции. В первой строке выполняется привязка к коллекции. Во второй строке выполняется привязка к текущему элементу коллекции. В третьей строке выполняется привязка к свойству Description текущего элемента коллекции.
На указатель текущего элемента влияют примененные к коллекции операции сортировки и фильтрации. При сортировке указатель текущего элемента устанавливается на последний выбранный элемент, однако представление коллекции перестраивается относительно его. (Возможно, до этого выбранный элемент был в начале списка, но теперь выбранный элемент может оказаться где-нибудь в середине.) При фильтрации выбранный элемент сохраняется, если данный выбор остается в представлении после фильтрации. В противном случае указатель текущего элемента устанавливается на первый элемент отфильтрованного представления коллекции.
Сценарий «основной — подробности»
Понятие текущего элемента применимо не только для перемещения элементов в коллекции, но также для сценария привязки «основной — подробности». Еще раз рассмотрим пользовательский интерфейс приложения из подраздела Понятие привязки данных. В этом приложении выбор внутри ListBox определяет содержимое, отображаемое в ContentControl. Другими словами, когда выбран элемент ListBox, ContentControl показывает сведения выбранного элемента.
Для реализации этого сценария необходимо наличие двух или более элементов управления, привязанных к одному и тому же представлению. Следующий пример из примера привязки данных показывает разметку ListBox и ContentControl, которую вы видите в пользовательском интерфейсе приложения в разделе Понятие привязки данных.
Можно заметить, что в приведенном выше примере используется шаблон. Фактически данные не будут отображаться выбранным способом без использования шаблонов (один явно используется элементом ContentControl, а другой — неявно элементом ListBox). К шаблонам данных мы перейдем в следующем разделе.
Шаблоны данных
Без использования шаблонов данных пользовательского интерфейса приложения в подразделе Понятие привязки данных будет выглядеть следующим образом.
Как показано в примере из предыдущего раздела, оба элемента управления — как ListBox, так и ContentControl, привязываются ко всему объекту коллекции (а точнее к представлению объекта коллекции) элементов AuctionItem. При отсутствии особых инструкций по способу отображения коллекции данных элемент управления ListBox отвечает за отображение строкового представления каждого объекта в базовой коллекции, а элемент управления ContentControl отвечает за отображение строкового представления привязанного к ней объекта.
Чтобы решить эту проблему, приложение определяет DataTemplates. Как показано в примере в предыдущем разделе, ContentControl явно использует шаблон данных detailsProductListingTemplate. Элемент управления ListBox неявно использует следующий шаблон данных при отображении объектов AuctionItem в коллекции.
При использовании двух шаблонов DataTemplate результирующий пользовательский интерфейс будет аналогичен пользовательскому интерфейсу, показанному в разделе Понятие привязки данных. Как можно увидеть на этом снимке, в дополнение к тому, что шаблоны DataTemplate дают возможность располагать данные в элементах управления, они позволяют определять подходящие визуальные элементы для данных. Например, элементы DataTrigger используются в приведенном выше шаблоне DataTemplate, чтобы элементы AuctionItem со значением SpecialFeatures для HighLight отображались с оранжевой границей и звездочкой.
Дополнительные сведения о шаблонах данных см. в статье Общие сведения о шаблонах данных (.NET Framework).
Проверка данных
Для большинства приложений, принимающих входные данные от пользователя, необходима логика проверки, чтобы убедиться, что пользователь ввел ожидаемые данные. Проверка может основываться на типе, диапазоне, формате или других требованиях конкретного приложения. В этом разделе рассматривается, как работает проверка данных в WPF.
Связь правил проверки и привязки
Модель привязки данных WPF позволяет связать ValidationRules с объектом Binding. Например, в следующем примере TextBox привязывается к свойству с именем StartPrice и в свойство Binding.ValidationRules добавляется объект ExceptionValidationRule.
Объект ValidationRule проверяет, является ли значение свойства допустимым. В состав WPF входят два типа встроенных объектов ValidationRule:
ExceptionValidationRule выполняет проверку исключений, возникающих во время обновления свойства источника привязки. В предыдущем примере StartPrice имеет тип integer. Когда пользователь вводит значение, которое невозможно преобразовать в целое число, создается исключение, приводящее к тому, что привязка будет помечена как недопустимая. Альтернативным синтаксисом для явной установки свойства ExceptionValidationRule является установка свойства ValidatesOnExceptions в true для вашего объекта Binding или MultiBinding.
Объект DataErrorValidationRule проверяет наличие ошибок, вызванных объектами, реализующими интерфейс IDataErrorInfo. Дополнительные сведения об использовании этого правила проверки см. в разделе DataErrorValidationRule. Альтернативным синтаксисом для явной установки свойства DataErrorValidationRule является установка свойства ValidatesOnDataErrors в true для вашего объекта Binding или MultiBinding.
Вы можете также создать собственное правило проверки, выполнив наследование от класса ValidationRule и реализовав метод Validate. В следующем примере показано правило, используемое элементом управления «Дата начала» для Добавление списка продуктов TextBox, показанного в разделе Понятие привязки данных.
StartDateEntryForm TextBox использует это правило FutureDateRule, как показано в следующем примере.
Поскольку значение UpdateSourceTrigger равно PropertyChanged, механизм привязки обновляет исходное значение при каждом нажатии клавиши, что означает, что он также проверяет каждое правило в коллекции ValidationRules при каждом нажатии клавиши. Это будет обсуждаться далее в разделе «Процесс проверки».
Предоставление визуального отклика
Если пользователь вводит недопустимое значение, можно сформировать отклик пользовательского интерфейса приложения на ошибку. Одним из способов предоставления такой обратной связи является установка присоединенного свойства Validation.ErrorTemplate для пользовательского ControlTemplate. Как показано в предыдущем подразделе, StartDateEntryForm — TextBox использует ErrorTemplate с именем validationTemplate. В следующем примере показано определение элемента validationTemplate.
Элемент AdornedElementPlaceholder указывает, где должен размещаться элемент управления.
Если применяются пользовательские ErrorTemplate и ToolTip, TextBox StartDateEntryForm при наличии ошибки проверки выглядит следующим образом:
Если к Binding присоединены правила проверки, но для привязанного элемента управления не указано значениеErrorTemplate, для уведомления пользователей об ошибке проверки по умолчанию будет использоваться ErrorTemplate. ErrorTemplate по умолчанию — это шаблон элемента управления, определяющий красную границу на слое декоративных элементов. Если используются ErrorTemplate и ToolTip по умолчанию, пользовательский интерфейс TextBox StartPriceEntryForm при наличии ошибки проверки выглядит следующим образом:
Пример предоставления логики проверки всех элементов управления в диалоговом окне см. в подразделе «Пользовательские диалоговые окна» раздела Общие сведения о диалоговых окнах.
Процесс проверки
Проверка обычно выполняется, когда целевое значение передается свойству источника привязки. Этот перенос выполняется для привязок TwoWay и OneWayToSource. Таким образом, причина обновления источника зависит от значения свойства UpdateSourceTrigger, как описано в подразделе Что инициирует обновления источника.
Следующие элементы описывают процесс проверки. При возникновении ошибки проверки или ошибки другого типа на любом этапе данного процесса процесс будет прерван.
Обработчик привязки проверяет, есть ли определенные пользовательские объекты ValidationRule, где для ValidationStep задано значение RawProposedValue для этого Binding. В этом случае он вызывает метод Validate на каждом ValidationRule до тех пор, пока один из них не выдаст ошибку или пока все они не сработают.
Обработчик привязки вызывает преобразователь, если таковой существует.
Если преобразователь сработает корректно, механизм связывания проверяет, нет ли каких-либо пользовательских объектов ValidationRule, чей ValidationStep имеет значение ConvertedProposedValue для этого Binding, и в этом случае он вызывает метод Validate для каждого ValidationRule, чей ValidationStep имеет значение ConvertedProposedValue, пока один из них не встретится с ошибкой или пока все они не пройдут.
Обработчик привязки присваивает значение исходному свойству.
Обработчик привязки проверяет, есть ли определенные пользовательские объекты ValidationRule, где для ValidationStep задано значение CommittedValue для этого Binding. В этом случае он вызывает метод Validate на каждом ValidationRule, чей ValidationStep имеет значение CommittedValue, до тех пор пока один из них не выдаст ошибку или пока все они не сработают.