[英]How to sort a DataGridView based on its column content?
這里GrdView是一個DataGridView。 並且'obj.Code'是字母數字類型的(例如R12,BA3,BA21 ...)
private SortableBindingList<myClass> objList = new SortableBindingList<myClass>();
DataTable table = new DataTable();
table.Columns.Add("code", typeof(string));
foreach (var obj in objList)
{
table.Rows.Add(obj.Code);
}
GrdView.DataSource = table;
通過單擊其列標題對DataGridView進行排序,但是排序為字母數字。 我只想按其數字內容(而不是前導字母)對DataGridView的列進行排序。
解決此問題的最簡單方法是添加僅包含數字的另一列。 您實際上無法根據單元格的子部分對數組進行排序。
排序將必須進行大量比較(至少n * ln(n)),因此,對於每次訪問都轉換字符串不是一個好習慣。
您應該做的只是將列轉換為等效的數字形式,然后按該列排序。
排序之后,您可以刪除該列,然后將其全部傳遞以HTML形式呈現。
兩種選擇-
您可以捕獲SortCompare事件並修改其行為以適合您的需求。 在這里看看第二個示例-http: //msdn.microsoft.com/zh-cn/library/ms171608(v=vs.90).aspx
您可以捕獲ColumnHeaderMouseClick事件 ,然后使用適合您需求的IComparer手動運行Sort
就像pid在他的回答中說的那樣,考慮到大量元素,在實現比較邏輯時要考慮性能。 但是,在實施復雜的解決方案之前,我將首先對大量數據進行測試,以確保存在問題。
您需要創建另一列進行排序(可以將其設為Visible屬性= false)。 將所有這些代碼粘貼到新的Windows窗體中,它將完全按照您所描述的那樣工作(刪除FormX.designer.cs文件)。 SortableCode列使用正則表達式刪除前導字母字符。
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows.Forms;
namespace StackOverflowQuestion21361045
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public class myClass
{
public string Code { get; set; }
public string SortableCode
{
get
{
return Regex.Replace(Code, @"^[^\d]+", string.Empty);
}
}
}
private readonly SortableBindingList<myClass> objList = new SortableBindingList<myClass>();
private void Form1_Load(object sender, EventArgs e)
{
objList.Add(new myClass {Code = "A23"});
objList.Add(new myClass {Code = "B12"});
objList.Add(new myClass {Code = "C04" });
dataGridView1.DataSource = objList;
dataGridView1.Sort(dataGridView1.Columns[1], ListSortDirection.Ascending);
}
private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
DataGridViewColumn newColumn = dataGridView1.Columns[e.ColumnIndex];
DataGridViewColumn previouslySortedColumn = dataGridView1.SortedColumn;
ListSortDirection direction;
if (newColumn == dataGridView1.Columns[0])
newColumn = dataGridView1.Columns[1]; //if the user sorts by code, change the column so as to sort by SortableCode
// If oldColumn is null, then the DataGridView is not sorted.
if (previouslySortedColumn != null)
{
// Sort the same column again, reversing the SortOrder.
if (previouslySortedColumn == newColumn &&
dataGridView1.SortOrder == SortOrder.Ascending)
{
direction = ListSortDirection.Descending;
}
else
{
// Sort a new column and remove the old SortGlyph.
direction = ListSortDirection.Ascending;
previouslySortedColumn.HeaderCell.SortGlyphDirection = SortOrder.None;
}
}
else
{
direction = ListSortDirection.Ascending;
}
// Sort the selected column.
dataGridView1.Sort(newColumn, direction);
newColumn.HeaderCell.SortGlyphDirection =
direction == ListSortDirection.Ascending ?
SortOrder.Ascending : SortOrder.Descending;
}
private void dataGridView1_DataBindingComplete(object sender,
DataGridViewBindingCompleteEventArgs e)
{
// Put each of the columns into programmatic sort mode.
foreach (DataGridViewColumn column in dataGridView1.Columns)
{
column.SortMode = DataGridViewColumnSortMode.Programmatic;
}
}
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.dataGridView1 = new System.Windows.Forms.DataGridView();
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
this.SuspendLayout();
//
// dataGridView1
//
this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
this.dataGridView1.Dock = System.Windows.Forms.DockStyle.Fill;
this.dataGridView1.Location = new System.Drawing.Point(0, 0);
this.dataGridView1.Name = "dataGridView1";
this.dataGridView1.Size = new System.Drawing.Size(284, 261);
this.dataGridView1.TabIndex = 0;
this.dataGridView1.ColumnHeaderMouseClick += new System.Windows.Forms.DataGridViewCellMouseEventHandler(this.dataGridView1_ColumnHeaderMouseClick);
this.dataGridView1.DataBindingComplete += new System.Windows.Forms.DataGridViewBindingCompleteEventHandler(this.dataGridView1_DataBindingComplete);
//
// Form1
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(284, 261);
this.Controls.Add(this.dataGridView1);
this.Name = "Form1";
this.Text = "Form1";
this.Load += new System.EventHandler(this.Form1_Load);
((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
this.ResumeLayout(false);
}
#endregion
private System.Windows.Forms.DataGridView dataGridView1;
public class SortableBindingList<T> : BindingList<T>
{
private ArrayList sortedList;
private ArrayList unsortedItems;
private bool isSortedValue;
public SortableBindingList()
{
}
public SortableBindingList(IList<T> list)
{
foreach (object o in list)
{
this.Add((T)o);
}
}
protected override bool SupportsSearchingCore
{
get
{
return true;
}
}
protected override int FindCore(PropertyDescriptor prop, object key)
{
PropertyInfo propInfo = typeof(T).GetProperty(prop.Name);
T item;
if (key != null)
{
for (int i = 0; i < Count; ++i)
{
item = (T)Items[i];
if (propInfo.GetValue(item, null).Equals(key))
return i;
}
}
return -1;
}
public int Find(string property, object key)
{
PropertyDescriptorCollection properties =
TypeDescriptor.GetProperties(typeof(T));
PropertyDescriptor prop = properties.Find(property, true);
if (prop == null)
return -1;
else
return FindCore(prop, key);
}
protected override bool SupportsSortingCore
{
get { return true; }
}
protected override bool IsSortedCore
{
get { return isSortedValue; }
}
ListSortDirection sortDirectionValue;
PropertyDescriptor sortPropertyValue;
protected override void ApplySortCore(PropertyDescriptor prop,
ListSortDirection direction)
{
sortedList = new ArrayList();
Type interfaceType = prop.PropertyType.GetInterface("IComparable");
if (interfaceType == null && prop.PropertyType.IsValueType)
{
Type underlyingType = Nullable.GetUnderlyingType(prop.PropertyType);
if (underlyingType != null)
{
interfaceType = underlyingType.GetInterface("IComparable");
}
}
if (interfaceType != null)
{
sortPropertyValue = prop;
sortDirectionValue = direction;
IEnumerable<T> query = base.Items;
if (direction == ListSortDirection.Ascending)
{
query = query.OrderBy(i => prop.GetValue(i));
}
else
{
query = query.OrderByDescending(i => prop.GetValue(i));
}
int newIndex = 0;
foreach (object item in query)
{
this.Items[newIndex] = (T)item;
newIndex++;
}
isSortedValue = true;
this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
else
{
throw new NotSupportedException("Cannot sort by " + prop.Name +
". This" + prop.PropertyType.ToString() +
" does not implement IComparable");
}
}
protected override void RemoveSortCore()
{
int position;
object temp;
if (unsortedItems != null)
{
for (int i = 0; i < unsortedItems.Count; )
{
position = this.Find("LastName",
unsortedItems[i].GetType().
GetProperty("LastName").GetValue(unsortedItems[i], null));
if (position > 0 && position != i)
{
temp = this[i];
this[i] = this[position];
this[position] = (T)temp;
i++;
}
else if (position == i)
i++;
else
unsortedItems.RemoveAt(i);
}
isSortedValue = false;
OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
}
public void RemoveSort()
{
RemoveSortCore();
}
protected override PropertyDescriptor SortPropertyCore
{
get { return sortPropertyValue; }
}
protected override ListSortDirection SortDirectionCore
{
get { return sortDirectionValue; }
}
}
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.