Windows窗体DataGridView C#:按标记名称和值名称排序数据

时间:2016-09-28 17:46:42

标签: c# winforms sorting datagridview

我一直在试图弄清楚这个想法,搜索堆栈溢出的网站,但我似乎无法做我想要的。

基本上,我在Windows窗体上有一个DataGridView,我希望按值名称对列0进行排序,还要按标记名称排序。我已经创建了一些简单的代码来帮助演示我的问题。

我在表格的第一部分,我用data

填充datagridview
public Form1()
{
    InitializeComponent();
    dataGridView1.Rows.Add(11);
    //column 1
    dataGridView1.Rows[0].Cells[0].Value = "0 - TITLE";
    dataGridView1.Rows[1].Cells[0].Value = "1";
    dataGridView1.Rows[2].Cells[0].Value = "2";
    dataGridView1.Rows[3].Cells[0].Value = "3";
    dataGridView1.Rows[4].Cells[0].Value = "4";
    dataGridView1.Rows[5].Cells[0].Value = "5";
    dataGridView1.Rows[6].Cells[0].Value = "6";
    dataGridView1.Rows[7].Cells[0].Value = "7";
    dataGridView1.Rows[8].Cells[0].Value = "8";
    dataGridView1.Rows[9].Cells[0].Value = "9";
    dataGridView1.Rows[10].Cells[0].Value = "10";


    dataGridView1.Rows[0].Cells[0].Tag = "TITLE";
    dataGridView1.Rows[1].Cells[0].Tag = "PASS";
    dataGridView1.Rows[2].Cells[0].Tag = "PASS";
    dataGridView1.Rows[3].Cells[0].Tag = "FAIL";
    dataGridView1.Rows[4].Cells[0].Tag = "PASS";
    dataGridView1.Rows[5].Cells[0].Tag = "PASS";
    dataGridView1.Rows[6].Cells[0].Tag = "PASS";
    dataGridView1.Rows[7].Cells[0].Tag = "PASS";
    dataGridView1.Rows[8].Cells[0].Tag = "FAIL";
    dataGridView1.Rows[9].Cells[0].Tag = "PASS";
    dataGridView1.Rows[10].Cells[0].Tag = "PASS";
    //column 2
    dataGridView1.Rows[0].Cells[1].Value = "A - TITLE";
    dataGridView1.Rows[1].Cells[1].Value = "B - THIS IS";
    dataGridView1.Rows[2].Cells[1].Value = "C - A";
    dataGridView1.Rows[3].Cells[1].Value = "D - TEST";
    dataGridView1.Rows[4].Cells[1].Value = "E - THAT";
    dataGridView1.Rows[5].Cells[1].Value = "F - I";
    dataGridView1.Rows[6].Cells[1].Value = "G - AM";
    dataGridView1.Rows[7].Cells[1].Value = "H - RUNNING";
    dataGridView1.Rows[8].Cells[1].Value = "I - RIGHT";
    dataGridView1.Rows[9].Cells[1].Value = "J - NOW";
    dataGridView1.Rows[10].Cells[1].Value = "K - !";
    //column 3
    dataGridView1.Rows[0].Cells[2].Value = "0 - TITLE";
    dataGridView1.Rows[1].Cells[2].Value = "14.999999999999";
    dataGridView1.Rows[2].Cells[2].Value = "15.0001";
    dataGridView1.Rows[3].Cells[2].Value = "15.00";
    dataGridView1.Rows[4].Cells[2].Value = "15.0";
    dataGridView1.Rows[5].Cells[2].Value = "15";
    dataGridView1.Rows[6].Cells[2].Value = "11.99";
    dataGridView1.Rows[7].Cells[2].Value = "12.01";
    dataGridView1.Rows[8].Cells[2].Value = "12";
    dataGridView1.Rows[9].Cells[2].Value = "88.65";
    dataGridView1.Rows[10].Cells[2].Value = "33.25";

}

第二部分是按钮点击触发事件,触发排序。

private void button1_Click(object sender, EventArgs e)
{
    DataGridViewColumn newColumn = dataGridView1.Columns[0];
    DataGridViewColumn oldColumn = dataGridView1.SortedColumn;
    ListSortDirection direction;

    // If oldColumn is null, then the DataGridView is not sorted.
    if (oldColumn != null)
    {
        // Sort the same column again, reversing the SortOrder.
        if (oldColumn == newColumn &&
            dataGridView1.SortOrder == SortOrder.Ascending)
        {
            direction = ListSortDirection.Descending;
        }
        else
        {
            // Sort a new column and remove the old SortGlyph.
            direction = ListSortDirection.Ascending;
            oldColumn.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;
}

因此,此代码可以按值名称(升序和降序)对列0进行排序,但是当我再次单击该按钮时,我希望能够按标签名称排序,并按特定顺序排序,这意味着标题首先,然后失败,然后通过。

如果有任何想法,请告诉我。感谢。

2 个答案:

答案 0 :(得分:1)

由于您的DGV没有DataSource,您必须编写自定义排序

这实际上相当简单;编写逻辑以在您想要提供的各种排序中进行切换可能更难。

首先准备要排序的所有列:

dataGridView1.Columns[0].SortMode = DataGridViewColumnSortMode.Automatic;
dataGridView1.Columns[1].SortMode = DataGridViewColumnSortMode.Automatic;
dataGridView1.Columns[2].SortMode = DataGridViewColumnSortMode.Automatic;

使用您的专栏名称!

接下来,您将对SortCompare事件进行编码。这是一个简单的例子,按value.ToString表示的长度排序:

private void dataGridView1_SortCompare(object sender, DataGridViewSortCompareEventArgs e)
{
    var v1 = e.CellValue1.ToString().Length;
    var v2 = e.CellValue2.ToString().Length;
    e.SortResult = v1 < v2 ? -1 : v1 == v2 ? 0 : 1;
    e.Handled = true;
}

如您所见,您需要将e.SortResult设置为-1, 0 or 1,意为less, equal and greater。然后将e.Handled参数设置为true

就是这样。

要访问Tag数据,您可以使用以下代码:

 var v1 = dataGridView1[e.Column.Index, e.RowIndex1].Tag.ToString();

等..

当然,由于您可以访问所有数据,因此可以编写更复杂的代码,以任何方式处理单元数据,甚至可以从其他列访问数据。

请查看DataGridViewSortCompareEventArgs e

的参数

要切换您的排序模式,您可以存储当前的排序模式,增加它,可以在ColumnHeaderMouseClick事件中并在SortCompare代码中进行测试..

答案 1 :(得分:1)

在调用Sort方法并在那里应用逻辑之前,您可以将处理程序附加到DataGridView.SortCompare事件。

例如:

static readonly Dictionary<string, int> sortOrder = new Dictionary<string, int>
{
    { "TITLE", 0 },
    { "FAIL", 1 },
    { "PASS", 2 }
};

static void OnSortCompareByTag(object sender, DataGridViewSortCompareEventArgs e)
{
    var dgv = (DataGridView)sender;
    var tag1 = dgv.Rows[e.RowIndex1].Cells[e.Column.Index].Tag as string;
    var tag2 = dgv.Rows[e.RowIndex2].Cells[e.Column.Index].Tag as string;
    int result = sortOrder[tag1].CompareTo(sortOrder[tag2]);
    if (result == 0)
        result = Comparer<string>.Default.Compare(e.CellValue1 as string, e.CellValue2 as string);
    e.SortResult = result;
    e.Handled = true;
}

private void button1_Click(object sender, EventArgs e)
{
    // ...

    // Sort the selected column.
    dataGridView1.SortCompare += OnSortCompareByTag;
    dataGridView1.Sort(newColumn, direction);
    dataGridView1.SortCompare -= OnSortCompareByTag;

    // ...    
}