Мне любопытно выбрать лучший способ (больше ориентированный на простоту, а не на скорость или эффективность) для сортировки DropDownList в C# / ASP.NET - я просмотрел несколько рекомендаций, но они меня не устраивают.
Обновлено: ребята, у меня нет контроля над тем, как данные попадают в DropDownList - я не могу изменить SQL.
Сторона клиента. Я не могу контролировать, как данные поступают в DDL.
Очевидно, что в этом случае я не могу управлять оператором SQL.
Если ваши данные поступают к вам в виде DataTable (или DataSet), мой ответ ниже должен сработать для вас. Встроенная функция сортировки DataTable как бы скрыта.
Возможный обман stackoverflow.com/questions/667010/…





Я обычно загружаю DropDownList со значениями из таблицы базы данных, поэтому самый простой способ - отсортировать результаты по желанию с помощью предложения ORDER BY вашего оператора SELECT, а затем просто перебирать результаты и выгружать их в DropDownList.
OP указывает, что он не может изменить SQL, используемый для заполнения этого раскрывающегося списка
Этот ответ - именно то, что мне нужно, мне пришлось немного покопаться, чтобы понять, что вы имели в виду. Когда вы настраиваете источник данных вместо использования «указать столбцы из представления таблицы», вы используете «указать настраиваемый оператор SQL или хранимую процедуру», тогда мой SQL будет выглядеть примерно так: «ВЫБЕРИТЕ OrgTable. * FROM OrgAuthentication ORDER BY OrgName»
DropDownList принимает любой IEnumerable в качестве источника данных.
Просто отсортируйте его с помощью LINQ.
Я согласен с ребятами в сортировке ваших данных в модели перед их заполнением в DropDownList, поэтому, если вы заполняете это из БД, неплохо было бы отсортировать их уже там, используя простое предложение Сортировать по, это спасет вас несколько циклов на веб-сервере, и я уверен, что БД сделает это намного быстрее. Если вы заполняете это из другого источника данных, например XML-файла, использование LINQ будет хорошей идеей, или даже любой вариант Array.Sort будет хорошим.
Я согласен с сортировкой с использованием ORDER BY при заполнении запроса к базе данных, если все, что вам нужно, - это отсортировать отображаемые результаты по алфавиту. Позвольте ядру базы данных выполнять работу по сортировке.
Однако иногда вам нужно какой-то другой порядок сортировки помимо алфавитного. Например, вам может потребоваться логическая последовательность, такая как: Новый, Открыт, Выполняется, Завершено, Утверждено, Закрыто. В этом случае вы можете добавить столбец в таблицу базы данных, чтобы явно установить порядок сортировки. Назовите его как-нибудь вроде SortOrder или DisplaySortOrder. Затем в вашем SQL вы должны ЗАКАЗАТЬ ПО полю порядка сортировки (без извлечения этого поля).
Если ваши данные поступают к вам как System.Data.DataTable, вызовите метод DataTable .Select (), передав "" для filterExpression и "COLUMN1 ASC" (или любой другой столбец, по которому вы хотите сортировать) для сортировки. Это вернет массив объектов DataRow, отсортированных, как указано, которые вы затем можете перебирать и выгружать в DropDownList.
Взгляните на эта статья из CodeProject, который меняет порядок содержимого раскрывающегося списка. Если вы выполняете привязку данных, вам нужно будет запустить сортировщик после привязки данных к списку.
Какой объект вы используете для привязки данных? Обычно я использую Collection <T>, List <T> или Queue <T> (в зависимости от обстоятельств). Их относительно легко отсортировать с помощью специального делегата. См. Документация MSDN о делегате сравнения (T).
Спасибо, я думаю, это лучший способ сделать это. В моем случае я использую свойства набора данных для загрузки раскрывающегося списка «фильтры». Добавляя каждое свойство в список при получении данных, я могу отсортировать список позже и при необходимости привязать данные к моему раскрывающемуся списку. Также позволяет настраивать фильтры в списке для любых изменений текста. Спасибо!
Предполагая, что вы используете последнюю версию .Net Framework, это будет работать:
List<string> items = GetItemsFromSomewhere();
items.Sort((x, y) => string.Compare(x, y));
DropDownListId.DataSource = items;
DropDownListId.DataBind();
что такое x и y в items.Sort((x, y) => string.Compare(x, y));?
У вас может не быть доступа к SQL, но если у вас есть DataSet или DataTable, вы, безусловно, можете вызвать метод Sort().
Если бы у любого из них был метод сортировки, вы бы смогли.
Если вы получите DataTable с данными, вы можете создать DataView на основе этого, а затем привязать к нему раскрывающийся список. Ваш код будет выглядеть примерно так ...
DataView dvOptions = new DataView(DataTableWithOptions);
dvOptions.Sort = "Description";
ddlOptions.DataSource = dvOptions;
ddlOptions.DataTextField = "Description";
ddlOptions.DataValueField = "Id";
ddlOptions.DataBind();
Параметры текстового поля и поля значений отображаются в соответствующие столбцы в таблице данных, которую вы получаете.
Вы можете использовать эту функцию JavaScript:
function sortlist(mylist)
{
var lb = document.getElementById(mylist);
arrTexts = new Array();
arrValues = new Array();
arrOldTexts = new Array();
for(i=0; i<lb.length; i++)
{
arrTexts[i] = lb.options[i].text;
arrValues[i] = lb.options[i].value;
arrOldTexts[i] = lb.options[i].text;
}
arrTexts.sort();
for(i=0; i<lb.length; i++)
{
lb.options[i].text = arrTexts[i];
for(j=0; j<lb.length; j++)
{
if (arrTexts[i] == arrOldTexts[j])
{
lb.options[i].value = arrValues[j];
j = lb.length;
}
}
}
}
Рекомендуется отсортировать данные перед их привязкой к DropDownList, но в случае, если вы не можете, вы можете отсортировать элементы в DropDownList.
Сначала вам нужен класс сравнения
Public Class ListItemComparer
Implements IComparer(Of ListItem)
Public Function Compare(ByVal x As ListItem, ByVal y As ListItem) As Integer _
Implements IComparer(Of ListItem).Compare
Dim c As New CaseInsensitiveComparer
Return c.Compare(x.Text, y.Text)
End Function
End Class
Затем вам нужен метод, который будет использовать этот Comparer для сортировки DropDownList
Public Shared Sub SortDropDown(ByVal cbo As DropDownList)
Dim lstListItems As New List(Of ListItem)
For Each li As ListItem In cbo.Items
lstListItems.Add(li)
Next
lstListItems.Sort(New ListItemComparer)
cbo.Items.Clear()
cbo.Items.AddRange(lstListItems.ToArray)
End Sub
Наконец, вызовите эту функцию со своим DropDownList (после того, как она была привязана к базе данных)
SortDropDown(cboMyDropDown)
P.S. Извините, но я выбрал язык VB. Вы можете использовать http://converter.telerik.com/ для преобразования кода из VB в C#
List<ListItem> li = new List<ListItem>();
foreach (ListItem list in DropDownList1.Items)
{
li.Add(list);
}
li.Sort((x, y) => string.Compare(x.Text, y.Text));
DropDownList1.Items.Clear();
DropDownList1.DataSource = li;
DropDownList1.DataTextField = "Text";
DropDownList1.DataValueField = "Value";
DropDownList1.DataBind();
Решение C# для .NET 3.5 (требуются System.Linq и System.Web.UI):
public static void ReorderAlphabetized(this DropDownList ddl)
{
List<ListItem> listCopy = new List<ListItem>();
foreach (ListItem item in ddl.Items)
listCopy.Add(item);
ddl.Items.Clear();
foreach (ListItem item in listCopy.OrderBy(item => item.Text))
ddl.Items.Add(item);
}
Вызовите его после того, как вы связали свой раскрывающийся список, например OnPreRender:
protected override void OnPreRender(EventArgs e)
{
base.OnPreRender(e);
ddlMyDropDown.ReorderAlphabetized();
}
Вставьте его в свою библиотеку утилит для удобного повторного использования.
Dim items = (From item In ddl.Items.Cast (Of ListItem) () Order By item.Text Select item) .ToArray ddl.Items.Clear () ddl.Items.AddRange (items)
Чтобы отсортировать объектный источник данных, который возвращает набор данных, вы используете свойство Сортировать элемента управления.
Пример использования На странице aspx для сортировки по возрастанию ColumnName
<asp:ObjectDataSource ID = "dsData" runat = "server" TableName = "Data"
Sort = "ColumnName ASC" />
Другой вариант - поместить ListItems в массив и отсортировать.
int i = 0;
string[] array = new string[items.Count];
foreach (ListItem li in dropdownlist.items)
{
array[i] = li.ToString();
i++;
}
Array.Sort(array);
dropdownlist.DataSource = array;
dropdownlist.DataBind();
var list = ddl.Items.Cast<ListItem>().OrderBy(x => x.Text).ToList();
ddl.DataSource = list;
ddl.DataTextField = "Text";
ddl.DataValueField = "Value";
ddl.DataBind();
Лучше, если вы отсортируете Источник перед его привязкой к DropDwonList. но отсортируйте DropDownList.Items следующим образом:
Dim Lista_Items = New List(Of ListItem)
For Each item As ListItem In ddl.Items
Lista_Items.Add(item)
Next
Lista_Items.Sort(Function(x, y) String.Compare(x.Text, y.Text))
ddl.Items.Clear()
ddl.Items.AddRange(Lista_Items.ToArray())
(в этом случае я сортирую по строке (текст элемента), это может быть имя поставщика, идентификатор поставщика)
метод Sort() предназначен для каждого List(of ) / List<MyType>, вы можете его использовать.
Сделать это можно так просто
private void SortDDL(ref DropDownList objDDL)
{
ArrayList textList = new ArrayList();
ArrayList valueList = new ArrayList();
foreach (ListItem li in objDDL.Items)
{
textList.Add(li.Text);
}
textList.Sort();
foreach (object item in textList)
{
string value = objDDL.Items.FindByText(item.ToString()).Value;
valueList.Add(value);
}
objDDL.Items.Clear();
for(int i = 0; i < textList.Count; i++)
{
ListItem objItem = new ListItem(textList[i].ToString(), valueList[i].ToString());
objDDL.Items.Add(objItem);
}
}
И вызовите этот метод SortDDL (ref yourDropDownList); вот и все. Данные в вашем раскрывающемся списке будут отсортированы.
см. http://www.codeproject.com/Articles/20131/Sorting-Dropdown-list-in-ASP-NET-using-C#
Попробуй это
------- Хранить процедуру ----- (SQL)
USE [Your Database]
GO
CRATE PROC [dbo].[GetAllDataByID]
@ID int
AS
BEGIN
SELECT * FROM Your_Table
WHERE ID=@ID
ORDER BY Your_ColumnName
END
---------- Default.aspx ---------
<asp:DropDownList ID = "ddlYourTable" runat = "server"></asp:DropDownList>
--------- Default.aspx.cs -------
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
List<YourTable> table= new List<YourTable>();
YourtableRepository tableRepo = new YourtableRepository();
int conuntryInfoID=1;
table= tableRepo.GetAllDataByID(ID);
ddlYourTable.DataSource = stateInfo;
ddlYourTable.DataTextField = "Your_ColumnName";
ddlYourTable.DataValueField = "ID";
ddlYourTable.DataBind();
}
}
------- Вспомогательный класс LINQ ----
public class TableRepository
{
string connstr;
public TableRepository()
{
connstr = Settings.Default.YourTableConnectionString.ToString();
}
public List<YourTable> GetAllDataByID(int ID)
{
List<YourTable> table= new List<YourTable>();
using (YourTableDBDataContext dc = new YourTableDBDataContext ())
{
table= dc.GetAllDataByID(ID).ToList();
}
return table;
}
}
Попробуй это:
/// <summary>
/// AlphabetizeDropDownList alphabetizes a given dropdown list by it's displayed text.
/// </summary>
/// <param name = "dropDownList">The drop down list you wish to modify.</param>
/// <remarks></remarks>
private void AlphabetizeDropDownList(ref DropDownList dropDownList)
{
//Create a datatable to sort the drop down list items
DataTable machineDescriptionsTable = new DataTable();
machineDescriptionsTable.Columns.Add("DescriptionCode", typeof(string));
machineDescriptionsTable.Columns.Add("UnitIDString", typeof(string));
machineDescriptionsTable.AcceptChanges();
//Put each of the list items into the datatable
foreach (ListItem currentDropDownListItem in dropDownList.Items) {
string currentDropDownUnitIDString = currentDropDownListItem.Value;
string currentDropDownDescriptionCode = currentDropDownListItem.Text;
DataRow currentDropDownDataRow = machineDescriptionsTable.NewRow();
currentDropDownDataRow["DescriptionCode"] = currentDropDownDescriptionCode.Trim();
currentDropDownDataRow["UnitIDString"] = currentDropDownUnitIDString.Trim();
machineDescriptionsTable.Rows.Add(currentDropDownDataRow);
machineDescriptionsTable.AcceptChanges();
}
//Sort the data table by description
DataView sortedView = new DataView(machineDescriptionsTable);
sortedView.Sort = "DescriptionCode";
machineDescriptionsTable = sortedView.ToTable();
//Clear the items in the original dropdown list
dropDownList.Items.Clear();
//Create a dummy list item at the top
ListItem dummyListItem = new ListItem(" ", "-1");
dropDownList.Items.Add(dummyListItem);
//Begin transferring over the items alphabetically from the copy to the intended drop
downlist
foreach (DataRow currentDataRow in machineDescriptionsTable.Rows) {
string currentDropDownValue = currentDataRow["UnitIDString"].ToString().Trim();
string currentDropDownText = currentDataRow["DescriptionCode"].ToString().Trim();
ListItem currentDropDownListItem = new ListItem(currentDropDownText, currentDropDownValue);
//Don't deal with dummy values in the list we are transferring over
if (!string.IsNullOrEmpty(currentDropDownText.Trim())) {
dropDownList.Items.Add(currentDropDownListItem);
}
}
}
Это возьмет данный раскрывающийся список со свойством Text и Value элемента списка и вернет их в данный раскрывающийся список. Удачи!
Если вы добавляете параметры в раскрывающийся список один за другим без набора данных и хотите отсортировать его позже после добавления элементов, вот решение:
DataTable dtOptions = new DataTable();
DataColumn[] dcColumns = { new DataColumn("Text", Type.GetType("System.String")),
new DataColumn("Value", Type.GetType("System.String"))};
dtOptions.Columns.AddRange(dcColumns);
foreach (ListItem li in ddlOperation.Items)
{
DataRow dr = dtOptions.NewRow();
dr["Text"] = li.Text;
dr["Value"] = li.Value;
dtOptions.Rows.Add(dr);
}
DataView dv = dtOptions.DefaultView;
dv.Sort = "Text";
ddlOperation.Items.Clear();
ddlOperation.DataSource = dv;
ddlOperation.DataTextField = "Text";
ddlOperation.DataValueField = "Value";
ddlOperation.DataBind();
Это позволит отсортировать выпадающие элементы в алфавитном порядке.
Если вы используете DropDownList с ограничением данных, просто перейдите к мастеру и отредактируйте ограничивающий запрос:

Вы хотите отсортировать список на стороне сервера или клиента? Если серверный, какой тип источника данных вы будете использовать?