Laden...

[Gelöst] dataTable.DefaultView.Sort mit "fester" Summenzeile?

Erstellt von tikra vor 13 Jahren Letzter Beitrag vor 13 Jahren 3.116 Views
tikra Themenstarter:in
185 Beiträge seit 2007
vor 13 Jahren
[Gelöst] dataTable.DefaultView.Sort mit "fester" Summenzeile?

Hallo,

ich habe eine DataTable, welche eine Summenzeile mit Namen "Summe" beinhaltet, diese sortiere ich mittels dataTable.DefaultView.Sort.

Bei dieser Sortierung wird allerdings die Summenzeile "wild" mit sortiert und taucht dann irgendwo mittendrin in der Tabelle auf, nachdem ich sie an ein GridView (Webapplikation) gebunden habe.

Mein Basisansatz ist eben diese Summenzeile zu suchen, zu entfernen und mit ImportRow oder InsertAt ans Ende der DataTable wieder einzufügen.


protected void gvReport_Sorting(object sender, GridViewSortEventArgs e)
        {
            GridView gv = (GridView)sender;
            DataTable dt = (DataTable)gv.DataSource;

            if (dt != null)
            {
                // Daten sortieren.
                dt.DefaultView.Sort = e.SortExpression;
                //if (e.SortDirection == SortDirection.Ascending)
                //    dt.DefaultView.Sort += " ASC";
                //else
                    dt.DefaultView.Sort += " DESC";

                    
                    DataRow dr = dt.NewRow();
                    for (int i = 0; i < dt.Rows.Count; i++)
                    {
                        if (dt.Rows[i]["Name"].ToString() == "Summe")
                        {
                            dr.ItemArray = dt.Rows[i].ItemArray;
                            dt.Rows[i].Delete();

                            break;
                        }
                    }

                    dt.Rows.InsertAt(dr, dt.Rows.Count);

                // Sortierte DataTable wieder an das GridView binden.
                gv.DataSource = dt;
                gv.DataBind();
            }
        }

Dies funktioniert allerdings nicht, da sich die hinzugefügte Zeile immer wieder passend einsortiert...

Ist es über diesen Weg ÜBERHAUPT möglich?

Mittlerweile habe ich diesen Ansatz verworfen, versuche aber über die selbe Idee das entsprechende GridView dann zu bearbeiten (DataBound-Ereignis), ich fürchte hier sieht es nicht besser aus.

Geht es einfacher? Geht es überhaupt? Bin am verzweifeln...

Vielen Dank!

458 Beiträge seit 2007
vor 13 Jahren

Haeng doch mal einen Screenshot an, ich verstehe nicht ganz was hier das Problem ist.
Wie bindest du die Daten an dein Grid?
Sind es BoundFields oder TemplateFields?

be the hammer, not the nail!

tikra Themenstarter:in
185 Beiträge seit 2007
vor 13 Jahren

Binden mit .DataSource = dataTable und .DataBind(). Keine vordefinierten Felder da es eine sehr dynamische Tabelle ist.

Tabelle mit 2 Spalten

Name Wert

Günther 1,0
Timm 2,0
Summe 3,0

Nach der Sortierung nach dem Namen:

Name Wert

Günther 1,0
Summe 3,0
Timm 2,0

-> Die Tabelle soll sortiert werden, die Summe soll allerdings weiterhin als letzte Zeile unten stehen.

458 Beiträge seit 2007
vor 13 Jahren

Spricht etwas dagegen die Summenzeile in den Footer zu packen?

be the hammer, not the nail!

tikra Themenstarter:in
185 Beiträge seit 2007
vor 13 Jahren

Nein, ich denke erstmal nicht. Habe ich auch schon drüber nachgedacht, habe es aber nicht wirklich hinbekommen, hier ein Snippet für die GridView-Bearbeitung, falls dir ein paar Syntaxelemente aus dem Kopf heraus fehlen, es funktioniert so nicht, aber hab's grad zur Hand:


			//GridViewRow gvr = new GridViewRow(-1, -1, DataControlRowType.DataRow, DataControlRowState.Normal);
					  //DataControlRowType.Footer


            Table tbl = (Table)gv.Rows[0].Parent;
            GridViewRow gvr2 = null;
            for (int i = 0; i < gv.Rows.Count; i++)
            {

                if (gv.Rows[i].Cells[0].Text == "Summe")
                {
                    gvr2 = gv.Rows[i];
                    //gv.DeleteRow(i); // Exception...

                    break;
                }
                    
            }

            if (gvr2 != null)
            {
                
                tbl.Rows.AddAt(gv.Rows.Count + 1, gvr2);
            }

Edit: (Okay, es scheint doch zu funktionieren, allerdings OHNE die Zeile zu löschen. Das zuweisen/zwischenspeichern von gvr2 und nochmalige adden mittels AddAt hat quasi ein "Verschieben" des Elements zur Folge. Das wundert mich...

194 Beiträge seit 2006
vor 13 Jahren

Hallo timmi

Ich hab da mal was für dich auf Basis von 2 Spalten.
Ich habe gesehen, dass su dein Problem gelöst hast, aber
jetzt habe ich es schon gecodet,also poste ich es auch. 🙂
Viielleicht hilft es ja jemand anderem.


<%@ Page language="C#" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
    "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<script runat="server">

	DataTable dt = GetData();
	decimal Summe=0;
	DataTable GetData()
	{
		// Deine 2-Spalten-Tabelle
	}

  void gridView1_RowDataBound(Object sender, GridViewRowEventArgs e)
  {

    if(e.Row.RowType == DataControlRowType.DataRow)
    {

	Summe+=(decimal)((DataRowView)e.Row.DataItem)["Wert"];
      /*edit*/
       return;
    }

    if(e.Row.RowType == DataControlRowType.Footer)
    {
	e.Row.Cells[0].Text = "<b>Summe:</b>";
		e.Row.Cells[1].Text = Summe.ToString();

    }

	

  }

void Page_Load(object sender, EventArgs e)
{
	        gridView1.DataSource = dt;
                gridView1.DataBind();
}


</script>

<html  >
  <head runat="server">
    <title>GridView RowDataBound Example</title>
</head>
<body>
    <form id="form1" runat="server">

      <h3>GridView RowDataBound Example</h3>

      <asp:gridview id="gridView1" 
        autogeneratecolumns="true"
        onrowdatabound="gridView1_RowDataBound" 
/*wichtig*/        showfooter="true"
        runat="server">
      </asp:gridview>

     </form>
  </body>
</html>

Gruss

Balaban_s

tikra Themenstarter:in
185 Beiträge seit 2007
vor 13 Jahren

Bist du sich, dass das funktioniert?

Wenn ich via DataSource/DataBind gehe gibt es diese Footer-Parameter doch gar nicht und kann dementsprechend auch nicht abgefragt werden oder sehe ich das falsch?
Oder ist die letzte Zeile einer DataTable automatisch immer ein Footer?

Meine entgültige Lösung, falls es noch irgendjemand mal benötigt:

        protected void gvReport_DataBound(object sender, EventArgs e)
        {
            GridView gv = (GridView)sender;

            Table tbl = (Table)gv.Rows[0].Parent;

            for (int i = 0; i < gv.Rows.Count; i++)
            {
                if (gv.Rows[i].Cells[1].Text == "Summe")
                {
                    tbl.Rows.AddAt(gv.Rows.Count + 1, gv.Rows[i]);
                    break;
                }
            }
        }

Intern wird mit Sicherheit mit Pointern gearbeitet und dieser wird dann einfach "umgebogen" und an die entsprechende Stelle gesetzt.

194 Beiträge seit 2006
vor 13 Jahren

Hallo timmi

Bist du sich, dass das funktioniert?

Ich habe es ehrlich gesagt nicht getestet.

Wenn ich via DataSource/DataBind gehe gibt es diese Footer-Parameter doch gar
nicht und kann dementsprechend auch nicht abgefragt werden oder sehe ich das falsch?

Das weiss ich nicht.

Oder ist die letzte Zeile einer DataTable automatisch immer ein Footer?

Eine DataTable hat meines Wissens keinen footer du meinst wahrscheinlich das GridView->siehe nachbearbeiteten Code: ich habe

showfooter="true"

gesetzt, dann sollte es klappen.

Gruss

Balaban_s