Элементы управления DetailsView и FormView

183

GridView и ListView — непревзойденные элементы управления, когда нужно показать плотную таблицу с множеством строк информации. Однако иногда необходимо видеть подробное представление отдельной записи. Хотя можно отыскать решение с использованием шаблонных столбцов в GridView, ASP.NET также включает два элемента управления, которые специально предназначены для этой цели — DetailsView и FormView. Оба отображают по одной записи за раз, но могут включать необязательные кнопки управления страницами, которые позволяют перемещаться по последовательности записей (отображая по одной на странице). Оба они поддерживают шаблоны, при этом FormView требует их. В этом состоит ключевое отличие между упомянутыми двумя элементами управления.

Еще одно отличие заключается в том, что DetailsView отображает свое содержимое внутри таблицы, в то время как FormView предоставляет гибкость в отображении содержимого без таблицы. Таким образом, если вы планируете использовать шаблоны, то FormView обеспечит максимальную гибкость. Однако если вы хотите избежать сложностей, связанных с шаблонами, то DetailsView предложит более простую модель, которая позволяет строить многострочные формы для отображения данных, состоящие из объектов-полей — почти так же, как GridView строится из объектов-столбцов.

Разобравшись в средствах GridView и ListView, можно очень легко и быстро освоить DetailsView и FormView. Это объясняется тем, что DetailsView и FormView заимствуют часть модели GridView.

DetailsView

Элемент DetailsView спроектирован для отображения по одной записи за раз. Он размещает каждую часть информации (будь то поле или свойство) в отдельной строке таблицы.

Элемент DetailsView может быть привязан к коллекции элементов. В этом случае он отображает первый элемент в группе. Он также позволяет перемещаться от одной записи к другой, используя страничные элементы управления, если установить свойство AllowPaging в true. Элементы управления страницами при этом можно конфигурировать, используя свойства PagingStyle и PagingSettings — точно таким же способом, как это делается в GridView. Единственное отличие в том, что здесь нет поддержки настраиваемой обработки страниц, а это значит, что объект исходных данных всегда извлекается целиком.

На рисунке ниже показан элемент DetailsView, привязанный к набору записей о сотрудниках, с полной информацией о каждом сотруднике:

DetailsView с управлением страницами

Элементы управления страницами DetailsView соблазнительно использовать для создания удобного браузера записей. К сожалению, такой подход несколько неэффективен. Для начала, при каждом перемещении пользователя от одной записи к другой всегда выполняется отдельная обратная отправка (в то время как табличные элементы управления отображают множество записей сразу). Но самый главный недостаток состоит в том, что при каждой обратной отправке страницы заново извлекается полный набор записей, несмотря на то, что отображается только одна. Если вы решите реализовать браузер записей на основе DetailsView, то, как минимум, должны будете включить кэширование, чтобы снизить нагрузку на базу данных. Таким образом, полный набор записей извлекается из кэша, когда это возможно, не требуя отдельных операций с базой данных.

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

Конечно, на определение наилучшего подхода влияют многие факторы, включая полный размер записи (насколько она больше, чем простые два поля — имя и фамилия), шаблоны использования (нужно ли среднему пользователю просматривать одну или две записи, либо же видеть их все), а также общее количество записей. (Если количество записей исчисляется несколькими десятками, можете спокойно извлекать их все, но следует дважды подумать, если записей тысячи.)

Определение полей

Для генерации отображаемых полей элемент DetailsView использует рефлексию. Это значит, что он проверяет объект данных и создает отдельное поле для каждого поля (в строке) или свойства (в пользовательском объекте) — точно так же, как и GridView. Эту автоматическую генерацию полей можно отключить, установив свойство AutoGenerateRows в false. Но тогда объявление объектов полей возлагается полностью на вас.

Интересно, что для построения DetailsView применяются те же объекты, что и при проектировании GridView. Например, поле элемента данных представлено дескриптором BoundField, кнопки могут быть созданы с помощью ButtonField и т.д. Ниже показана часть объявления полей для DetailsView и источник данных:

<asp:DetailsView ID="DetailsView1" runat="server" DataSourceID="getEmployeesSDS"
	AutoGenerateRows="false" AllowPaging="true">
	
	<Fields>
	    <asp:BoundField DataField="EmployeeID" HeaderText="EmployeeID" ReadOnly="True" InsertVisible="False" />
	    <asp:BoundField DataField="LastName" HeaderText="LastName" />
	    <asp:BoundField DataField="FirstName" HeaderText="FirstName" />
	    <asp:BoundField DataField="Title" HeaderText="Title" />
	    <asp:BoundField DataField="TitleOfCourtesy" HeaderText="TitleOfCourtesy" />
	    <asp:BoundField DataField="BirthDate" HeaderText="BirthDate" />
        ...
	</Fields>
</asp:DetailsView>

<asp:SqlDataSource ID="getEmployeesSDS" runat="server"
            ConnectionString="<%$ ConnectionStrings:Northwind %>"
            SelectCommand="SELECT * FROM Employees" />

Дескриптор BoundField можно использовать для установки таких свойств, как текст заголовка, форматирующая строка, поведение при редактировании и т.п. Вдобавок можно использовать свойство ShowHeader. Когда оно равно false, это вынуждает DetailsView исключить текст заголовка из строки, и поле занимает оба столбца.

Модель полей — не единственная часть GridView, которую наследует элемент DetailsView. Он также использует схожий набор стилей, схожий набор событий и схожую модель редактирования.

Операции с записью

DetailsView поддерживает операции удаления, вставки и редактирования. Однако в отличие от GridView, добавлять CommandField с элементами управления редактированием не понадобится. Вместо этого вы просто устанавливаете булевские свойства AutoGenerateDeleteButton, AutoGenerateEditButton и AutoGenerateInsertButton. Это добавляет CommandField в нижнюю часть DetailsView со ссылками на эти задачи.

После щелчка на кнопке Delete (Удалить) операция удаления выполняется немедленно. Однако когда осуществляется щелчок на кнопке Edit (Правка) или Insert (Вставка), то DetailsView переходит в режим вставки или редактирования. Формально DetailsView поддерживает три режима (представленные перечислением DetailsViewMode). Этими режимами являются Readonly, Edit и Insert. Текущий режим можно определить в любой момент, проверив свойство CurrentMode, а изменить режим можно вызовом ChangeMode(). С помощью свойства DefaultMode можно создать DetailsView, который всегда начинает работу в режиме редактирования или вставки.

В режиме вставки DetailsView всегда использует стандартные элементы управления типа текстовых полей — такие же, как и GridView. Для большей гибкости при редактировании можно применять элемент управления FormView.

Редактирование в DetailsView

Если вы переводите DetailsView в режим редактирования для модификации записи, а затем переходите к новой записи, используя кнопки управления страницами, то DetailsView остается в режиме редактирования. Если такое поведение не требуется, можете отреагировать на событие PageIndexChanged и программно вызвать метод ChangeMode(), чтобы вернуть его в режим только для чтения.

FormView

Если необходима максимальная гибкость шаблонов, то FormView предоставляет только шаблонные элементы управления для отображения и редактирования одиночной записи. Изящество модели шаблонов FormView в том, что она довольно точно соответствует модели TemplateField в GridView. Это значит, что можно работать со следующими шаблонами:

Это значит также, что можно взять полное содержимое шаблона TemplateField из GridView и поместить его внутрь FormView. Ниже приведен пример, основанный на ранее рассмотренном шаблонном GridView:

<asp:FormView ID="FormView1" runat="server" DataSourceID="getEmployeesSDS">
	<ItemTemplate>
		<b>
		    <%# Eval("EmployeeID") %> - 
		            <%# Eval("TitleOfCourtesy") %> <%# Eval("FirstName") %>
		    <%# Eval("LastName") %>
		</b>
		<hr />
		<small><i>
		    <%# Eval("Address") %><br />
		    <%# Eval("City") %>, <%# Eval("Country") %>,
		            <%# Eval("PostalCode") %><br />
		    <%# Eval("HomePhone") %></i>
		    <br />
		    <br />
		    <%# Eval("Notes") %>
	</ItemTemplate>
</asp:FormView>

На рисунке показан результат:

Одиночная запись в FormView

Во многом подобно DetailsView, элемент FormView работает в трех взаимоисключающих режимах: только чтение, вставка и редактирование. Однако в отличие от DetailsView и GridView, элемент управления FormView не поддерживает класс CommandField, который автоматически создает кнопки редактирования. Вместо этого такие кнопки должны создаваться самостоятельно.

Чтобы сделать это, вы просто добавляете элемент управления Button или LinkButton и устанавливаете его свойство CommandName в соответствующее значение. Например, Button с CommandName, установленным в Edit, переводит элемент FormView в режим редактирования. За краткой справкой обращайтесь в таблице ниже, где перечислены все распознаваемые имена команд, предназначенные для использования:

Значения CommandName для редактирования FormView
Значение Описание К чему относится
Edit

Переводит FormView в режим редактирования. FormView отображает текущую запись, используя EditItemTemplate с определенными вами редактирующими элементами

ItemTemplate
Cancel

Отменяет операцию редактирования или вставки и возвращает в режим, указанный в свойстве DefaultMode. Обычно это будет нормальный режим (FormViewMode.Readonly), и элемент FormView отобразит текущую запись, используя ItemTemplate

EditItemTemplate и InsertItemTemplate
Update

Применяет редактирование и инициирует события ItemUpdating и ItemUpdated

EditItemTemplate
New

Переводит FormView в режим вставки. FormView отображает новую пустую запись, используя InsertItemTemplate с определенными вами редактирующими элементами

ItemTemplate
Insert

Вставляет новые данные и инициирует события ItemInserting и ItemInserted

InsertItemTemplate
Delete

Удаляет текущую запись из источника данных, инициируя события ItemDeleting и ItemDeleted. Не изменяет режим FormView

ItemTemplate
Пройди тесты
Лучший чат для C# программистов