Оценка 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 Оценить ![]() ![]() ![]() ![]() ![]() ![]()
|