winforms 从对绑定DataGridView排序中排除汇总行

bzzcjhmw  于 2022-12-04  发布在  其他
关注(0)|答案(3)|浏览(171)

我将合计行显示为最后一行。我希望在用户单击列标题时将该行排除在排序之外。通过使用sql union,我将合计列添加到结果中。我使用SQL、C#和DataGridView控件。我无法公开ColumnHeader_Click事件。我仅使用TableStyle[0].AllowSorting = false。如何在控件上应用自定义排序?
谢谢

pb3s4cty

pb3s4cty1#

感谢TaW,您的回答帮助了我。我的需求有点不同,我需要在顶部显示总计,同时保留整个排序列,因为我的网格与正在显示的数据中的过滤负载和更改具有高度交互性。
我的排序是通过

protected void ReportGridView_Sorting(object sender, GridViewSortEventArgs e)

下面是我在我的方法中填充GridView所使用的内容:

if (!myDataTable.Columns.Contains("SortLevel"))
{
    myDataTable.Columns.Add("SortLevel", typeof(Int16));
    foreach (DataRow dr in myDataTable.Rows)
    {
        dr["SortLevel"] = 0;
    }
    dt.Rows[0]["SortLevel"] = 1;
}

if ((Session["SortDirection"] != null) && (Session["SortExpression"] != null))
{
    myDataTable.DefaultView.Sort = "SortLevel DESC, " + Session["SortExpression"] + " " + Session["SortDirection"];
}
MyGridView.DataSource = myDataTable;
MyGridView.AllowSorting = true;
MyGridView.DataBind();

边注:我不得不使用Sessions来保存自定义排序,而不是ViewState,因为它不能与我的gridview中动态创建的按钮一起正常工作

sz81bmfz

sz81bmfz2#

此解决方案基于@T.S.的建议,但直接在DataSet中工作,而不是在SQL中工作。
我已经在VS 2013中测试过了;我不知道它是否能在.Net 1.1中工作,而且必须恢复一台非常旧的机器来测试它。
我不知道你说的
无法公开columnheader_click事件
我已经将解决方案拆分为函数和ColumnHeaderMouseClick事件;如果确实不能使用该事件,则必须找到其他方法;但无论如何,您都需要触发排序并决定按哪些列进行排序。
解决方案的核心是设置新列值和标识“TotalsRow”的表达式。我使用了测试表的PK列“ID”,并将“ID=1记录”推到底部。在所有行上将排序列设置为0后,将适合表达式的第一行设置为maxInt。
您必须将其修改为适用于结果集的表达式。
我正在动态添加设置自定义排序列,并在排序后删除它; DGV暂停其布局直到整个事件完成。

DataTable yourTable = .. 

private void dataGridView1_ColumnHeaderMouseClick(object sender, 
                                                  DataGridViewCellMouseEventArgs e)
{
    string col = dataGridView1.Columns[e.ColumnIndex].Name;
    if (col != "") sortDGV (col );
 }

private void sortDGV(string col)
{
    dataGridView1.SuspendLayout();
    yourTable.Columns.Add("sortMe", typeof(Int32));

    yourTable.DefaultView.Sort = col;

    DataRow[] dr = yourTable.Select("ID='1'");
    for (int r = 0; r < yourTable.Rows.Count; r++) yourTable.Rows[r]["sortMe"] = 0;
    dr[0]["sortMe"] = int.MaxValue;

    yourTable.DefaultView.Sort = "sortMe," + col;

    yourTable.Columns.Remove("sortMe");
    dataGridView1.ResumeLayout();
}
guz6ccqo

guz6ccqo3#

虽然我只有8岁,但我自己也遇到了这个愿望,但我有一个不同的解决办法:我希望最后一行是一个“编辑行”,无论如何排序,它都将始终保留在底部。因此,创建一个与常规数据网格分开的DataGridViewRow,在填充DGV之后添加它。在排序之前,从DGV中删除Row,然后在排序之后再次添加它。我使用单击RowHeaderText来触发排序(使用私有类比较器进行手动排序,和DGV_Sort事件来指示排序已经完成。(您必须跟踪何时输入此事件,因为我发现它在排序之前和之后输入-所以我使用了一个表单全局布尔值来跟踪它。
我单独跟踪我的“我的可移除行”上的任何编辑,但是如果你不想这样做,你总是可以在移除之前克隆该行。
请注意,我在开始时设置了AllowUserToAddRows = true,但在以编程方式填充网格后,我将其切换为false,以防止在我一次编辑1行的愿望下添加更多“可编辑”行。我有一个按钮,用于在完成编辑时将行添加到DGV,此时我只需创建一个新的myRemovableRow并将该行添加到DGV。

Public partial class Form1 : Form
{
     public DataGridViewRow myRemoveableRow;
     public bool bDoingSort = false;
     .
     .
     private DataGridViewRow CreateNewBlankRow()
     { // create your a new row with whatever default values for DGV

       DataGridViewRow newRow = (DataGridViewRow) DGV.Rows[0].Clone();

       // or however you want to create your row and fill in default values

       return newRow;
     }

     private void FillDGV()
     {
      // Do whatever to fill your DataGridView  (called DGV here)

         myRemoveableRow = CreateNewBlankRow();
         DGV.Rows.Add(myRemoveableRow);
     }

     private void DGV_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
     {
         bDoingSort = true;
         DGV.Rows.Remove(myRemoveableRow);
         SortOrder dir = SortOrder.Ascending; // or whatever logic you use
         .
         DGV.Sort(new RowComparer(dir, e.ColumnIndex));
      }

      private void DGV_Sorted(object sender, EventArgs e)  
      {  // 'Sorted'  Event from the DataGridView events
         if (bDoingSort) 
         {  
               DGV.Rows.Add(myRemoveableRow);  
               bDoingSort = false;         //reset sorting boolean
         }
         else  // we haven't set the sorting up yet
         {
             return;
         }
     }

     // setup manual sorter (I use separate Classes for int, string, double etc)
     private class RowComparer : System.Collections.IComparer
     {   
         private static int sortOrderModifier = 1;  
         private readonly int Column;
         
         public RowComparer(SortOrder sortorder, int iColumn)
         {
            if (sortOrder == SortOrder.Descending) 
                sortOrderModifier = -1;
            else
                sortOrderModifier = 1;
            this.Column = iColumn;
         }
         public int Compare (Object objA, Object objB)
         {
             DataGridViewRow row1 = (DataGridViewRow)objA;
             DataGridViewRow row2 = (DataGridViewRow)objB;
         // do your sort compare (for eg.)
              return sortOrderModifier * (row1.Cells[Column].Value).CompareTo(row2.Cells[Column].Value); 
          }
      }
  }

我发现这很好用--我不仅可以对条目进行排序,还可以在运行中过滤(出)条目。

相关问题