Выбор строк в GridView

167

Выбор строки означает, что пользователь может выделить или изменить внешний вид строки щелчком на какой-то кнопке или ссылке. Когда пользователь щелкает на кнопке, то не только строка изменяет свой внешний вид, но также появляется шанс обработать событие в коде.

Элемент GridView предоставляет встроенную поддержку выбора. Нужно просто добавить столбец CommandField со свойством ShowSelect, установленным в true. При этом CommandField может отображаться как гиперссылка, кнопка или фиксированное изображение. Тип указывается с помощью свойства ButtonType. Затем можно указать текст в свойстве SelectText или же ссылку на изображение в свойстве SelectImageUrl.

Ниже показан пример, отображающий кнопку выбора с маленьким значком (select.jpg), на котором можно щелкать:

<asp:CommandField ShowSelectButton="true" ButtonType="Image" 
	SelectImageUrl="~/select.jpg" />

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

Выбор в GridView

Использование CommandField обеспечивает максимальный контроль над размещением столбца выбора. Это также позволяет установить текст либо изображение, используемое для кнопки выбора. Однако существует сокращение, которое вообще исключает создание CommandField. Если установить свойство GridView.AutoGenerateSelectButton в true, то GridView добавит столбец с кнопками выбора автоматически. Этот столбец выбора будет помещен с левой стороны сетки и отобразит текстовую ссылку со словом Select (Выбрать).

При щелчке на кнопке выбора выполняется обратная отправка страницы, а также серия дополнительных шагов. Сначала генерируется событие GridView.SelectedIndexChanging, которое можно перехватить, чтобы отменить операцию. Далее изменяется значение свойства GridView.SelectedIndex, чтобы указать на выбранную строку. И, наконец, генерируется событие GridView.SelectedIndexChanged, которое можно обработать, если нужно вручную обновить другие элементы управления, отразив новый выбор. Когда страница отображается, выбранной строке назначается стиль SelectedRowStyle.

Чтобы выбор работал, потребуется сконфигурировать SelectedRowStyle так, чтобы выбранные строки выглядели иначе, чем нормальные. Обычно выделенные строки имеют другое значение BackColor.

Использование выбора для создания форм типа "главная-детальная"

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

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

К счастью, GridView позволяет легко извлечь эту информацию через свойство SelectedDataKeys. Чтобы использовать это средство, понадобится установить для свойства GridView.DataKeyNames список из одного или более ключевых полей, разделенный запятыми. Каждое имя в этом списке должно соответствовать одному из свойств привязанного объекта или одному из полей привязанной записи. Обычно будет применяться только одно ключевое поле.

После этого можно привязать второй источник данных к этому полю. Ниже приведен пример использования в запросе объединения поля EmployeeID для поиска всех соответствующих записей в таблице Territories. Другими словами, этот источник данных извлекает все регионы, за которые отвечает выбранный сотрудник:

<body>    
    <form id="form1" runat="server">
        <asp:SqlDataSource ID="getEmployeesSDS" runat="server"
             ConnectionString="<%$ ConnectionStrings:Northwind %>"
             SelectCommand="SELECT EmployeeID, LastName, FirstName, City FROM Employees" />

        <!-- Извлекает данные из трех связанных таблиц:
             Employees -> EmployeeTerritories (ключ EmployeeID)
             EmployeeTerritories -> Territories (ключ TerritoryID )
         -->
        <asp:SqlDataSource ID="sourceRegionsSDS" runat="server"
            ConnectionString="<%$ ConnectionStrings:Northwind %>"
            SelectCommand="SELECT Employees.EmployeeID, Territories.TerritoryID, 
                Territories.TerritoryDescription FROM Employees 
                INNER JOIN EmployeeTerritories 
                ON Employees.EmployeeID = EmployeeTerritories.EmployeeID 
                INNER JOIN Territories ON EmployeeTerritories.TerritoryID = Territories.TerritoryID 
                WHERE (Employees.EmployeeID = @EmployeeID)">
            <SelectParameters>
                <asp:ControlParameter ControlID="gridEmployees" Name="EmployeeID" 
                    PropertyName="SelectedDataKey.Values["EmployeeID"]" />
            </SelectParameters>
        </asp:SqlDataSource>

        <!-- Таблица сотрудников - "главная" -->
        <asp:GridView ID="gridEmployees" runat="server" DataSourceID="getEmployeesSDS" DataKeyNames="EmployeeID"
            BackColor="White" BorderColor="#336666" BorderStyle="Double" BorderWidth="3px"
            CellPadding="6" GridLines="Horizontal" AutoGenerateColumns="False">
            <Columns>
                <asp:CommandField ShowSelectButton="true" SelectText=">>" />
                <asp:BoundField DataField="EmployeeID" HeaderText="EmployeeId" ReadOnly="True" InsertVisible="False" />
                <asp:BoundField DataField="LastName" HeaderText="LastName" SortExpression="LastName" />
                <asp:BoundField DataField="FirstName" HeaderText="FirstName" SortExpression="FirstName" />
                <asp:BoundField DataField="City" HeaderText="City" SortExpression="City" />
            </Columns>

            <HeaderStyle BackColor="#336666" Font-Bold="True" ForeColor="White" />
            <RowStyle BackColor="White" ForeColor="#333333" />
            <SelectedRowStyle BackColor="#339966" Font-Bold="True" ForeColor="White" />
        </asp:GridView>

        <br /><br />
        <!-- Регионы, за которые отвечает выбранный сотрудник ("детальная") -->
        <asp:GridView ID="gridRegions" runat="server" DataSourceID="sourceRegionsSDS" />
    </form>
</body>

В этом примере sourceRegionsSDS использует единственный параметр — EmployeeID выбранной записи о сотруднике. Значение EmployeeID извлекается из коллекции SelectedDataKey.Values. Поле EmployeeID можно найти по его индексной позиции (которая в данном примере равна 0, потому что это единственное поле, указанное в списке DataKeyName) или же по имени. Единственный трюк при выполнении поиска имени заключается в том, что нужно заменить символы кавычек соответствующим HTML-сущностью (").

На рисунке ниже показана форма "главная-детальная", которая содержит список регионов, назначенных выбранному сотруднику:

Страница с формой главная-детальная

Как показано в предыдущем примере, форму "главная-детальная" можно установить декларативно, без необходимости написания какого-либо кода. Однако существует много случаев, когда необходимо реагировать на событие SelectedIndexChanged. Например, можно переадресовать пользователя на новую страницу (скажем, с выбранным значением в строке запроса). Или же можно настроить другие элементы управления на странице.

Ниже показан код для добавления метки, описывающей дочернюю таблицу, которая была приведена в предыдущем примере (в разметке нужно будет добавить элемент управления Label с именем lblRegionCaption):

protected void gridEmployees_SelectedIndexChanged(object sender, EventArgs e)
{
        int index = gridEmployees.SelectedIndex;

        //  Ключевое поле можно извлечь из свойства SelectedDataKey
        int ID = (int)gridEmployees.SelectedDataKey.Values["EmployeeID"];

        // Другие данные можно извлечь непосредственно из коллекции Cells
        string firstName = gridEmployees.SelectedRow.Cells[2].Text;
        string lastName = gridEmployees.SelectedRow.Cells[3].Text;

        lblRegionCaption.Text = "Сотрудник <b>" + firstName + " " + lastName +
            "</b> (ID=" + ID.ToString() + ") отвечает за:";
}
Обработка события SelectedIndexChanged

Использование поля данных в качестве кнопки выбора

Чтобы поддержать возможность выбора строки, не обязательно создавать новый столбец. Вместо этого можно превратить существующий столбец в активную ссылку. Такой прием обычно используется, чтобы дать возможность пользователям выбирать строки таблицы по уникальному значению идентификатора.

Для этого добавьте столбец ButtonField. Затем установите в DataTextField имя поля, которое хотите использовать. Это поле будет подчеркнуто и превращено в ссылку, щелчок на которой приведет к обратной отправке страницы и генерации события GridView.RowCommand. Это событие можно обработать, определив, на какой строке был совершен щелчок, и программно установить свойство SelectedIndex. Однако можно воспользоваться и более простым методом. Для этого нужно настроить ссылку, чтобы она генерировала событие SelectedIndexChanged, указав для CommandName текст Select:

<asp:ButtonField DataTextField="EmployeeID" ButtonType="Button" CommandName="Select" />

Теперь щелчок на поле данных приводит к автоматическому выбору записи. Столбец CommandField, который использовался ранее для отображения ссылки Select, а также столбец BoundField, применяемый для отображения EmployeeID. можно удалить, потому что столбец ButtonField эффективно совмещает эти две детали в одном месте:

Использование столбца ButtonField в качестве кнопки для выделения строки
Пройди тесты
Лучший чат для C# программистов