Сообщений 0 Оценка 0 Оценить |
Серверный элемент управления CountChooser Known bugs или что можно улучшить? Исходный текст на GitHub |
В сердце каждой трудности кроется возможность. Альберт Эйнштейн
На веб-страницах с таблицами, где применяется постраничный вывод (paging), иногда можно увидеть возможность выбора количества выводимых строк на странице.
Причины делать такой выбор могут быть, например, такими:
При использовании платформы ASP.NET возможность выбора числа из набора легко реализовать с помощью элемента управления DropDownList, и это может выглядеть так:
Получается очень просто и проблем или недостатков в такой реализации на первый взгляд нет. Но при следующих дополнительных возможностях страница будет более user-friendly:
1. Если всего строк в таблице (на примере 756) не больше, чем максимально возможного количества элементов на странице (на примере 200), то скрыть лишние варианты, и вместо них показать «вывести все»:
Тут всего элементов – 23, поэтому варианты «50 на странице» и тем более «100 (200) на странице» лишние.
2. Если всего строк в таблице не больше, чем минимальный возможный выбор количества строк на странице (на примере 10), то выбор размера окна и не нужен – лучше скрыть этот выбор:
Тут всего элементов 7, а минимальный выбор на странице – 10, поэтому все выборы лишние.
Функциональность эта весьма проста, ее можно запрограммировать и в коде страницы, но гораздо удобнее, если бы она была в готовом элементе управления.
Реализовать описанное поведение удобно и несложно в новом серверном элементе управления (server control). Я назову его CountChooser. Нацелимся на то, чтобы в разметке страницы объявлять его так:
<ucc:CountChooser runat="server" ID="cc" Counts="10,20,200,500"Title="Количество пользователей на странице:" DefaultValue="20" AutoPostBack="True" OnSelectedIndexChanged="FilterChanged" /> |
Наследовать будем от DropDownList. Свойства AutoPostBack и OnSelectedIndexChanged – унаследованные, а остальные новые:
Заслуживает внимания код основного свойства:
int[] _counts; public string Counts { set { _counts = value.Split(new[] {';', ','}, StringSplitOptions .RemoveEmptyEntries) .Select(s => s.Trim()) .Where(s => !string.IsNullOrEmpty(s)) .Select(int.Parse).ToArray(); } } |
Свойство Title – тривиальное автосвойство, а DefaultValue – сохраняется во ViewState, чтобы была возможность его устанавливать программно с сохранением между postback’ами:
public int DefaultValue { get { object obj = ViewState["df"]; return (obj == null) ? _counts.Min() : (int) obj; } set { ViewState["df"] = value; SelectedValue = value; } } |
Свойство SelectedValue переопределено как int с использованием DefaultValue:
public new int SelectedValue { get { return string.IsNullOrEmpty(base.SelectedValue) ? DefaultValue : int.Parse(base.SelectedValue); } set { base.SelectedValue = value.ToString(); } } |
Обозначенные свойства на самом деле никак не расширяют функциональность исходного DropDownList. Чтобы достичь обозначенного расширения, нужно дополнительное поведение, дополнительный метод. Назовем его SetAsCount – он устанавливает видимость control-а или изменяет элементы выбора в зависимости от общего количества строк в таблице.
public void SetAsCount(int cnt) { this.Visible = cnt >= _counts.Min(); if (!this.Visible) return; int prevSelectedValue = SelectedValue; if (cnt <= _counts.Max()) { int beginCut = _counts.Where(s => s >= cnt).Min(); this.Items.Clear(); this.Items.AddRange(_counts.Where(s => s < cnt) .Select(s => new ListItem(s.ToString(), s.ToString())) .Concat(new[] { new ListItem("вывести все", (prevSelectedValue < beginCut ? beginCut : prevSelectedValue).ToString()) }) .ToArray()); } else { this.DataSource = _counts; this.DataBind(); } SelectedValue = prevSelectedValue; } |
Функциональность CountChooser’а раскрывается в использовании метода SetAsCount, вызывать его удобно в методе веб-страницы, отвечающем за выборку количества элементов таблицы, например, так:
public int SelectCount() { int count = <get total count of elements>; labelFoundCount.Text = count.ToString(); countChooser.SetAsCount(count); return count; } |
Этот метод в таком явном виде появляется при использовании ObjectDataSource, который удобно использовать для привязки данных к таблице, вот пример его объявления для постраничного вывода:
<asp:ObjectDataSource runat="server" ID="ods" TypeName="pagetypename" OnObjectCreating="ods_ObjectCreating" OnObjectDisposing="ods_ObjectDisposing" EnablePaging="True" SelectMethod="Select" MaximumRowsParameterName="count" SortParameterName="orderBy" StartRowIndexParameterName="startIndex" SelectCountMethod="SelectCount" /> |
Исходник самого control-а лежит в github тут. Небольшой показательный пример проекта можно посмотреть здесь, а пример страницы, использующей CountChooser – здесь aspx и здесь aspx.cs.
Сообщений 0 Оценка 0 Оценить |