[SharePoint]SPGridView Control – Часть 1: Что такое SPGridView и с чем его едят

sharepoint2010-2013
Случилось так, что мне пришлось в экстренном порядке разбираться с данным контролом. Инфы в инете дохрена, но в целом толковой How-TO’шки я не нашел
Я убил порядка четырех дней на заморочки с контролом прежде, чем тот мне поддался.
Респект и уважуха Эрику Баргеру (Erik Burger), чьи заметки направили меня на путь истинный.
Давайте попробуем разобраться с контролом.


SPGridView — один из самых популярных контролов в SharePoint. Любой список платформы использует SPGridView для отображения данных в аккуратно сформированном виде. У пользователя имеется возможность сортировать, фильтровать, а также выполнять множество других действий над элементами контрола при использовании всяческих менюшек и иже с ними.
Как только дело доходит до разработки веб-частей, разработчик сталкивается с тем, что чтобы получить все прелести и удобности платформы надо еще покарпеть. Стандартный контрол ASP.Net GridView (который содержится в System.Web.UI.WebControls) теоретически дает все, что нам нужно, но требуется огромное количество усилий, чтобы контрол начал выглядеть, что называется SharePoint-Style-like. К счастью мелко-мягкие предоставили нам в пользование SPGridView (содержится в Microsoft.SharePoint.WebControls). Данный контрол является прямым наследником от GridView, потому Вам доступен тот же функционал и даже больше. И самое главное, он наследует стили платформы!

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

Давайте попробуем с ним разобраться.

В качестве основы под SPGridView мы возьмем тимплейт базовой веб-части. Можно все тоже самое организовать и в тимплейте страницы-приложения (Application Page) с некоторыми отличиями.
Мы будем использовать стандартный класс DataTable в качестве источника данны для нашего контрола, который мы прибиндим к объекту ObjectDataSource (содержится в System.Web.UI.WebControls). Почему так? Вполне можно использовать и сам DataTable в качестве источника, однако возникнет дополнительный геморой когда дойдет дело до реализации сортировки и фильтрации. Потому использовать в качестве источника данных ObjectDataSource существенно легче, чем DataSet. К тому же у меня не было особо времени на то, чтобы разбираться с этим на момент, когда потребовалось использовать контрол.

Метод выборки данных (SelectData) будет выглядеть примерно так:

public DataTable SelectData()
{
DataTable dataSource = new DataTable();

dataSource.Columns.Add(«ID»);
dataSource.Columns.Add(«Name»);
dataSource.Columns.Add(«Region»);
dataSource.Columns.Add(«Total Sales»);

dataSource.Rows.Add(1, «Иванов», «Москва», 110);
dataSource.Rows.Add(2, «Иванов», «Санкт-Петербург», 370);
dataSource.Rows.Add(3, «Иванов», «Самара», 30);
dataSource.Rows.Add(4, «Петров», «Москва», 11);
dataSource.Rows.Add(5, «Петров», «Санкт-Петербург», 770);
dataSource.Rows.Add(6, «Петров», «Самара», 15);
dataSource.Rows.Add(7, «Сидоров», «Москва», 23);
dataSource.Rows.Add(8, «Сидоров», «Санкт-Петербург», 500);
dataSource.Rows.Add(9, «Сидоров», «Самара», 250);

return dataSource;
}

Инициализацию данных мы будем проводить внутри перегрузки метода CreateChildControls:

protected sealed override void CreateChildControls()
{
const string GRIDID = «grid»;
const string DATASOURCEID = «grdDS»;

grdDS = new ObjectDataSource();
grdDS.ID = DATASOURCEID;
grdDS.SelectMethod = «SelectData»;
grdDS.TypeName = this.GetType().AssemblyQualifiedName;
grdDS.ObjectCreating += new ObjectDataSourceObjectEventHandler(grdDS_ObjectCreating);
this.Controls.Add(grdDS);

grid = new SPGridView();
grid.ID = GRIDID;
grid.DataSourceID = grdDS.ID;
grid.AutoGenerateColumns = false;

// Разбивка на страницы
grid.AllowPaging = true;
grid.PageSize = 5;

// Сортировка
grid.AllowSorting = true;

this.Controls.Add(grid);

SPGridViewPager pager = new SPGridViewPager();
pager.GridViewId = grid.ID;

this.Controls.Add(pager);
}

Здесь следует обратить внимание на несколько моментов:
1. Для контрола определяется свойство DataSourceID, а не DataSource. Это потребуется нам для фильтрации элементов в дальнейшем.
2. Назначение свойства TypeName объекта класса ObjectDataSource непосредственно к SPGridView. Это позволит нам получить доступ ко всем свойствам SPGridView в методе GetDataSource, который пригодится на этапе биндинга данных к списку. Такая реализация может и, скорее всего, породит проблемы, где ObjectDataSource “cannot find a non-generic method ‘GetDataSource’ …” или, проблему когда ObjectDataSource создает новый инстанс SPGridView, который полностью скидывает все установленные нами свойства для объекта. К частью, фикс проблемы довольно прост.

Когда ObjectDataSource создает экземпляр класса с указанием типа в свойстве TypeName, вызывается ивентхендлер ObjectCreating. В описании данного евентхендлера мы попросту назначаем текущих контекст объекта данному экземпляру.

private void grdDS_ObjectCreating(object sender, ObjectDataSourceEventArgs e)
{
e.ObjectInstance = this;
}

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

Если вы уже рыли тему в интернете, то почти наверняка заметили, что в моем примере нет описания колонок (BoundField). В момент разборок с контролом мне потребовалось организовать на одной странице сразу два контрола SPGridView. В процессе реализации я наткнулся на весьма странный баг, который заключался в том, что если ты определяешь свойство Visible одного из контролов в False, то заголовки колонок другого контрола пропадают! Для того, чтобы этого избежать, я описываю колонки и провожу биндинг данных внутри перегрузки метода Render():

protected sealed override void Render(HtmlTextWriter writer)
{
GenerateColumns();
grid.DataBind();
base.Render(writer);
}

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

Буду надеяться, что кому-то данная статья сильно упростит жизнь.
Референсы:
SPGridView and SPMenuField: Displaying custom data through SharePoint lists
Using the SharePoint v3 Data Grid Control (SPGridView)
Filtering with SPGridView

[SharePoint]SPGridView Control – Часть 1: Что такое SPGridView и с чем его едят: 1 комментарий

  1. Уведомление: [SharePoint]SPGridView Control – Часть 2: Фильтрация — Alexey Kurylev's blog

Добавить комментарий