【问题标题】:Windows Forms DataGridView C#: Sort Data by Tag Names and Value NamesWindows 窗体 DataGridView C#:按标记名称和值名称对数据进行排序
【发布时间】:2016-09-28 17:46:42
【问题描述】:

我一直在努力想弄清楚这一点,搜索堆栈溢出网站,但我似乎无法做我想做的事。

基本上,我在 Windows 窗体上有一个 DataGridView,我想按值名称对第 0 列进行排序,但也按标签名称。我创建了一段简单的代码来帮助演示我的问题。

表单中的第一部分,我用值填充数据网格视图

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 列进行排序,但是当我再次单击按钮时,我希望能够按标签名称并按特定顺序排序,即标题优先,然后是失败,然后是通过。

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

【问题讨论】:

  • 您可以对数据源进行排序,例如包含数据的DataTableList<T>
  • 他好像没有。第二个和第三个答案here 是关于为 DGV 编写自定义排序。但是创建和使用 DataSource 可能更简单,尽管自定义的可能更灵活..

标签: c# winforms sorting datagridview


【解决方案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;

    // ...    
}

【讨论】:

    【解决方案2】:

    由于您的 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.Handledparam 设置为true

    就是这样。

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

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

    等等。

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

    请查看DataGridViewSortCompareEventArgs e 的参数!

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-10
      • 1970-01-01
      • 2014-03-23
      • 1970-01-01
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      相关资源
      最近更新 更多