-1

我的DataGridView gridFilasWindows 窗体应用程序中有一个包含两列的应用程序,第二列始终包含可以转换为整数的字符串。当我单击对其进行排序时,它被排序为字符串,结果如下:

1, 11, 2, 22

但我需要将其排序为整数,例如:

1, 2, 11, 22

我已经尝试了这个问题的所有答案,但没有一个奏效,顺便说一句,接受的答案,它没有奏效,因为SortCompare事件没有因此而被触发

所以到目前为止我尝试的是添加 aColumnHeaderMouseClick并对其进行排序:

private void gridFilas_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{

    // this for loop has been added in a vain hope of converting all elements to integer to see if it works...
    for (int i = 0; i < gridFilas.Rows.Count; i++)
    {
        string v = gridFilas.Rows[i].Cells[1].Value.ToString();
        gridFilas.Rows[i].Cells[1].Value = Convert.ToInt32(v);
    }

    if (queuesSortedAscending)
    {
        gridFilas.Sort(gridFilas.Columns["Tamanho_Fila"], System.ComponentModel.ListSortDirection.Descending);
    }
    else
    {
        gridFilas.Sort(gridFilas.Columns["Tamanho_Fila"], System.ComponentModel.ListSortDirection.Ascending);
    }
    queuesSortedAscending = !queuesSortedAscending;

}

数据源在创建时设置(的构造函数Form):

dsComponentes = new DataSet();
// ... more code 
gridFilas.DataSource = dsComponentes.Tables["Queue"];

每当我向 DataSource 添加新行时,我都会确保将其解析为 int:

DataRow qlinha = dsComponentes.Tables["Queue"].NewRow();
qlinha["Nome_Fila"] = process;
qlinha["Tamanho_Fila"] = Int32.Parse(status);
dsComponentes.Tables["Queue"].Rows.Add(qlinha);

我也尝试过事先更改列的数据类型:

dsComponentes.Tables["Queue"].Columns["Tamanho_Fila"].DataType = typeof(int);

所以,我不知道还能做什么,我只需要将它作为整数而不是字符串来排序。欢迎任何解决方案。

4

2 回答 2

2

您永远不会显示您在哪里创建DataTable您要绑定到的 ( dsComponentes.Tables["Queue"]),但是当您添加该列时,您应该能够表明它是一个int.

var dataTable = new DataTable();
dataTable.Columns.Add("ColumnName", typeof(int));

这将导致绑定DataGridView将该列排序为整数。

如果DataType您使用设计器创建DataSet. 您可以System.Int32在该列上设置类型,它会按您的预期排序。

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace WindowsFormsApp1
{
   static class Program
   {
      /// <summary>
      /// The main entry point for the application.
      /// </summary>
      [STAThread]
      static void Main()
      {
         Application.EnableVisualStyles();
         Application.SetCompatibleTextRenderingDefault(false);

         var frm = new Form()
         {
            Text = "Data Grid View Form",
            Name = "DataGridViewForm",
            Size = new System.Drawing.Size(400, 400)
         };
         var dataGridView1 = new DataGridView();

         var dataTable = new DataTable();
         dataGridView1.DataSource = dataTable;
         dataGridView1.Dock = DockStyle.Fill;

         dataTable.Columns.Add("Id", typeof(int));
         dataTable.Columns.Add("IdAsString", typeof(string));
         var r1 = dataTable.NewRow();
         r1["Id"] = 1;
         r1["IdAsString"] = "1";
         dataTable.Rows.Add(r1);

         var r2 = dataTable.NewRow();
         r2["Id"] = 11;
         r2["IdAsString"] = "11";
         dataTable.Rows.Add(r2);

         var r3 = dataTable.NewRow();
         r3["Id"] = 2;
         r3["IdAsString"] = "2";
         dataTable.Rows.Add(r3);

         var r4 = dataTable.NewRow();
         r4["Id"] = 22;
         r4["IdAsString"] = "22";
         dataTable.Rows.Add(r4);

         frm.Controls.Add(dataGridView1);

         Application.Run(frm);
      }
   }
}
于 2019-07-10T20:44:30.593 回答
1

最简单的方法是使用 nuget 包:Equin ApplicationFramework BindingListView

它与标准的 .net BindingList 非常相似,只是它包含用于排序的函数。

  • 将 BindingListView nuget 导入您的项目
  • 使用 Visual Studio 设计器创建表单
  • 使用工具箱将 BindingSource 添加到表单
  • 转到此 BindingSource 的属性,选择 DataSource,添加项目数据源,选择 Object 并添加要在 DataGridView 中显示的项目类
  • 现在使用工具箱添加您的 DataGridView
  • 在 DataGridView 的属性中,选择 BindingSource 作为数据源。

现在,您的类的所有公共属性都将显示为 DataGridView 中的列。相应地编辑列:删除您不会使用的列。

在我的示例中,我将对 Person 序列进行排序:

class Person
{
    public int Id {get; set;}
    public string Name {get; set;}
    public DateTime BirthDate {get; set;}
}

转到您的 Form1 课程。我们将从 nuget 包中添加一个 BindingListView 作为成员。在构造函数中,我们将其分配给分配给 DataGridView 的 bindingsource。

class Form
{
    // the BindingListView from the nuget package:
    private readonly BindingListView<Person> sortableBindingListView;

    // constructor
    public Form1()
    {
        InitializeComponent();

        // make sure there is a Components Container, that will dispose
        // the components upon disposal of the form
        if (this.components == null)
        {
            this.components = new System.ComponentModel.Container();
        }

        // construct the sortable BindingListView for Persons:
        this.sortableBindingListView = new BindingListView<Person>(this.components);

        // create some Persons:
        var persons = new Person[]
        {
            new Person{Id = 1, Name = "F", BirthDate = new DateTime(2000, 1, 1)},
            new Person{Id = 2, Name = "A", BirthDate = new DateTime(1998, 4, 7)},
            new Person{Id = 3, Name = "C", BirthDate = new DateTime(2011, 3, 8)},
            new Person{Id = 4, Name = "Z", BirthDate = new DateTime(1997, 2, 3)},
            new Person{Id = 5, Name = "K", BirthDate = new DateTime(2003, 9, 5)},
        };

        // Assign the DataSources:
        this.sortableBindingListView.DataSource = persons;
        this.dataGridView1.DataSource = this.sortableBindingListView;
    }
}

这足以让您的排序工作。你不必添加任何额外的东西。单击列后,将过滤列。

一些有趣的功能:

private Person SelectedPerson
{
    get {return ((ObjectView<Person>)this.SortableBindingSource.Current)?.Object; }
}

private void DisplayPersons (IEnumerable<Person> personsToDisplay)
{
    this.SortableBindingSource.DataSource = personsToDisplay.ToList();
    this.SortableBindingSource.Refresh(); // this will update the DataGridView
}

private IEnumerable<Person> DisplayedPersons
{
    get {return this.SortableBindingSource; }
    // BindingListview<T> implements IEnumerable<T>
}

这就是全部。您无需创建特殊功能即可对鼠标单击进行排序。排序将自动完成,包括决定排序顺序并显示正确的排序字形。

如果您想以编程方式排序:

// sort columnPropertyA in descending order:
this.SortableBindingSource.Sort(this.columnPropertyA.ListsortDirection.Descending);

BindingListView 的优点之一是过滤选项:

// show only items where Name not null:
this.SortableBindingSource.ApplyFilter(person => person.Name != null);

// remove the filter:
this.SortableBindingSource.RemoveFilter();

我不确定在应用或删除过滤器后是否需要 Refresh()。

于 2019-07-10T21:24:28.390 回答