2012-01-17 51 views
12

Làm cách nào để sắp xếp một DataGridView theo hai cột (tăng dần)? Tôi có hai cột: daystatus.cách sắp xếp một khung dữ liệu theo 2 cột

Nếu tôi cần phải sắp xếp theo một cột, tôi làm:

this.dataGridView1.Sort (this.dataGridView1.Columns["day"], ListSortDirection.Ascending); 

Nhưng đối với hai?

+0

tôi không nghĩ rằng bạn có thể sắp xếp chúng với nhau, bạn có thể gọi mã của bạn cho 2 cột để đặt hàng theo ngày đầu tiên và bằng một cột khác sau – Moonlight

+0

bạn có thể xem tại đây: http://social.msdn.microsoft .com/Diễn đàn/vi-US/winformsdatacontrols/thread/7f819d92-5bd9-4b5b-b08c-fb15bb5331c4/ –

+0

Bạn đang sử dụng WinForms hay cái gì khác? –

Trả lời

8

Nếu bạn DataGridView là databound, bạn có thể sắp xếp Datatable nhìn của bạn và rebind để DataTable như sau:

private DataGridView dataGridView1 = new DataGridView(); 
private BindingSource bindingSource1 = new BindingSource(); 

private void Form1_Load(object sender, System.EventArgs e) 
{ 
    // Bind the DataGridView to the BindingSource   
    dataGridView1.DataSource = bindingSource1; 
    SortDataByMultiColumns(); //Sort the Data 
} 

private void SortDataByMultiColumns() 
{ 
    DataView view = dataTable1.DefaultView; 
    view.Sort = "day ASC, status DESC"; 
    bindingSource1.DataSource = view; //rebind the data source 
} 

OR, mà không sử dụng BindingSource và ràng buộc trực tiếp đến DataView:

private void SortDataByMultiColumns() 
{ 
    DataView view = ds.Tables[0].DefaultView; 
    view.Sort = "day ASC, status DESC"; 
    dataGridView1.DataSource = view; //rebind the data source 
} 
+0

dataGridView1.DataSource = ds.Tables [0]; – user1112847

+0

@ user1112847 Tôi không hiểu..if ur hỏi nếu inplace của bindingSource1 ds.Tables của bạn [0] mã sẽ hoạt động tốt sau đó có, tôi nghĩ như vậy nó sẽ làm việc tốt .. – VS1

0

Bạn có thể thử this, hoặc sử dụng sắp xếp tùy chỉnh:

private void dataGridView1_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) 
     { 
      if (dataGridView1.Columns[e.ColumnIndex].HeaderText =="day") 
      { 
       myBindingSource.Sort = "day, hour"; 
      } 
     } 
+0

dataGridView1.DataSource = ds.Tables [0]; – user1112847

+0

ds.Tables [0] .DefaultView.Sort = "ngày, giờ"; – pistipanko

6

Thêm một cột ẩn mà kết hợp hai và sắp xếp theo đó.

+1

Đó là một ý tưởng tốt nhưng sẽ không hoạt động nếu bạn muốn sắp xếp một cột asc và một desc khác. –

2

TLDR ; Tôi có một giải pháp hai dòng.

Tôi phải làm điều tương tự, nhưng sau khi nghiên cứu tất cả những cách phức tạp này để thực hiện điều này bằng cách bao gồm một .dll riêng biệt hoặc viết lớp/phương pháp riêng của tôi, tôi biết phải có cách dễ dàng hơn. Nó chỉ ra tôi đã đúng bởi vì tôi đã tìm ra cách để thực hiện điều này bằng cách sử dụng chỉ có hai dòng mã. Điều này làm việc cho tôi.

May thay, nó chỉ ra cho chúng ta rằng phương thức .NET Framework Sort() giúp chúng ta thực hiện điều này. Ý tưởng là bạn muốn sắp xếp các cột riêng lẻ, nhưng thứ tự mà bạn sắp xếp chúng là những gì sẽ tạo ra kết quả mong muốn.

Vì vậy, ví dụ, tôi có một cột cho loại tệp và cột cho tên tệp. Bất cứ khi nào tôi muốn sắp xếp dữ liệu theo các loại, tôi muốn đảm bảo rằng các tên cũng được sắp xếp trong mỗi loại được hiển thị.

MỤC TIÊU: Sắp xếp theo loại cũng sẽ sắp xếp tên tệp theo thứ tự bảng chữ cái.

dữ liệu:

zxcv.css

testimg3.jpg

asdf.html

testimg2.jpg

testimg1.jpg

dữ liệu Phân loại theo tên:

mConflictsDataGridView.Sort(mConflictsDataGridView.Columns[mNameLabel.Index], ListSortDirection.Ascending); 

asdf.html

testimg1.jpg

testimg2.jpg

testimg3.jpg

zxcv.css

Như bạn thấy, điều này sẽ đặt tên cho chắc chắn rằng những cái tên sẽ được sắp xếp cho phù hợp, như vậy mà khi tôi bây giờ sắp xếp theo loại tệp, cả hai yêu cầu sẽ thỏa mãn.

dữ liệu Phân loại theo loại file:

mConflictsDataGridView.Sort(mConflictsDataGridView.Columns[mFileExtensionLabel.Index], ListSortDirection.Ascending); 

zxcv.css

asdf.html

testimg1.jpg

testimg2.jpg

testimg3.jpg

Thì đấy! Nó được sắp xếp!

GIẢI PHÁP: Trong trường hợp của bạn, bạn có thể muốn thử một cái gì đó như sau, và bạn có thể cần phải tinh chỉnh một số chi tiết để có nó phục vụ cho mã của riêng bạn.

DataGridView1.Sort(DataGridView1.Columns["status"], ListSortDirection.Ascending); 
DataGridView1.Sort(DataGridView1.Columns["day"], ListSortDirection.Asscending); 

Điều này sẽ có thể hiển thị kết quả của bạn theo ngày với trường trạng thái được sắp xếp là tốt.

+0

Dường như nó sẽ không hoạt động nếu có một giá trị testimg2. css trong ví dụ của bạn – user3423149

2

Bạn có thể sử dụng phương pháp sắp xếp của DataGridView, nhưng chỉ định một đối số là một thể hiện của một lớp thực hiện IComparer.

Dưới đây là một ví dụ về một lớp học như:

public class MyTwoColumnComparer : System.Collections.IComparer 
{ 
    private string _SortColumnName1; 
    private int _SortOrderMultiplier1; 
    private string _SortColumnName2; 
    private int _SortOrderMultiplier2; 

    public MyTwoColumnComparer(string pSortColumnName1, SortOrder pSortOrder1, string pSortColumnName2, SortOrder pSortOrder2) 
    { 
     _SortColumnName1 = pSortColumnName1; 
     _SortOrderMultiplier1 = (pSortOrder1 == SortOrder.Ascending) ? 1 : -1; 
     _SortColumnName2 = pSortColumnName2; 
     _SortOrderMultiplier2 = (pSortOrder2 == SortOrder.Ascending) ? 1 : -1; 
    } 

    public int Compare(object x, object y) 
    { 
     DataGridViewRow r1 = (DataGridViewRow)x; 
     DataGridViewRow r2 = (DataGridViewRow)y; 

     int iCompareResult = _SortOrderMultiplier1 * String.Compare(r1.Cells[_SortColumnName1].Value.ToString(), r2.Cells[_SortColumnName1].Value.ToString()); 
     if (iCompareResult == 0) iCompareResult = _SortOrderMultiplier2 * String.Compare(r1.Cells[_SortColumnName2].Value.ToString(), r2.Cells[_SortColumnName2].Value.ToString()); 
     return iCompareResult; 
    } 
} 

Bây giờ, chúng ta có thể gọi đây là từ một cột mà SortMode là 'theo chương trình' trên một click chuột:

private void dgvAllMyEmployees_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e) 
{ 
    DataGridViewColumn dgvcClicked = dgvAllEmployees.Columns[e.ColumnIndex]; 
    if (dgvcClicked.SortMode == DataGridViewColumnSortMode.Programmatic) 
    { 
     _SortOrder = (_SortOrder == SortOrder.Ascending) ? SortOrder.Descending : SortOrder.Ascending; 
     MyTwoColumnComparer Sort2C = new MyTwoColumnComparer(dgvcClicked.Name, _SortOrder, "LastName", SortOrder.Ascending); 
     dgvAllEmployees.Sort(Sort2C); 
    } 
} 

Mức lớp biến _SortOrder giúp theo dõi thứ tự đi vào. Người ta có thể tăng cường điều này nhiều hơn để nhớ hai cột cuối cùng được nhấp và sắp xếp theo thứ tự mong muốn.

+0

Đây phải là câu trả lời –

+0

ok nhưng chờ .... myTwoColumnComparer.Compare được gọi ở đâu? –

+0

Suy nghĩ thứ hai ... Tôi không thể làm việc này được. Nó sắp xếp lần đầu tiên tôi bấm vào một cột, (tăng dần) nhưng nó sẽ không sắp xếp giảm dần nếu tôi bấm vào nó một lần nữa –

0

Câu trả lời mà John Kurtz cung cấp cho tôi rất gần gũi. Nhưng những gì tôi tìm thấy là khi tôi nhấp vào một cột một lần, nó đã thực sự sắp xếp theo hai cột ... Trong ví dụ của mình: dgvcClicked.Name, "LastName". Vì vậy, tốt !!

Nhưng, nếu tôi nhấp lại vào cột, thì nó sẽ KHÔNG sắp xếp theo hướng ngược lại. Vì vậy, cột trở nên bị mắc kẹt trong Tăng dần.

Để khắc phục điều này, tôi phải theo dõi thứ tự sắp xếp theo cách thủ công.Bắt đầu với lớp học này:

public class ColumnSorting 
{ 
    public int ColumnIndex { get; set; } 
    public ListSortDirection Direction { get; set; } 
} 

Sau đó, tôi đã thêm này Danh sách scoped toàn cầu:

List<ColumnSorting> _columnSortingList = new List<ColumnSorting>(); 

Sau đó, trong phương pháp mà không được Sắp xếp, tôi sẽ

  1. Kiểm tra xem chỉ mục cột đang được sắp xếp đã tồn tại trong _columnSortingList. Nếu không, hãy thêm nó.
  2. Nếu nó đã tồn tại, sau đó hoán đổi thứ tự sắp xếp

Và Bob là chú của bạn.

Các vấn đề liên quan