ppsGrid und die Datenbindung...

Anregungen und Verbesserungsvorschläge zum ppsGrid..
Post Reply
torsten
Site Admin
Posts: 92
Joined: 02.05.2006, 09:04
Spamschutz: 10
Location: Bremen

ppsGrid und die Datenbindung...

Post by torsten »

Hallo an alle

Da bei mir immer wieder der Wunsch nach Datenbindung geäußert wird, habe ich mich mal hingesetzt und ein paar Zeilen diesbezgl. geschrieben:

Code: Select all

using System;
using System.Windows.Forms;
using System.ComponentModel;
using System.Data;

namespace ppsGrid{
  /// <summary>Summary description for ppsDataGrid.</summary>
  /// <remarks>
  /// Demo: 
  /// Wie kann ich das ppsGrid so erweitern, dass es 
  /// eine "DataTable" anzeigen kann ?
  /// </remarks>
  public class ppsDataGrid:ppsGrid.Grid{
    /// <summary>Verbindung zur Datenquelle</summary>
    private DataTable vDataSource;

    /// <summary>
    /// Setzt die Datenquelle auf die erste Tabelle  im übergebenen "DataSet"
    /// </summary>
    /// <param name="ds">DataSet mit min. einer Tabelle</param>
    public void SetDataBinding(DataSet ds){
      if(ds==null)
        throw new ArgumentNullException();
      if(ds.Tables.Count==0)
        throw new ArgumentException("No DataTables avaible");
      SetDataBinding(ds,ds.Tables[0].TableName);
    }

    /// <summary>
    /// Setzt die Datenquelle auf die Tabelle mit 
    /// übergebenen Namen im übergebenen "DataSet"
    /// </summary>
    /// <param name="ds">DataSet mit min. einer Tabelle</param>
    /// <param name="tblName">Name der Tabelle, welche benutzt werden soll.</param>
    public void SetDataBinding(DataSet ds,string tblName){
      // Parameter prüfen
      if(ds==null)
        throw new ArgumentNullException();
      if(ds.Tables.Count==0)
        throw new ArgumentException("No DataTables avaible");
      if(tblName==null || tblName=="")
        tblName=ds.Tables[0].TableName;

      // datenquelle setzen
      if(ds.Tables.IndexOf(tblName)==-1)
        throw new ArgumentException("DataTable not found");
      else
        DataSource=ds.Tables[tblName];
    }

    /// <summary>Übergebene Datenquelle setzen</summary>
    public DataTable DataSource{
      get{return(vDataSource);}
      set{
        // alte Datenquelle vorhanden ?, freigeben
        if(vDataSource!=null){                                    
          vDataSource.Dispose();
          vDataSource=null;

          // alte Daten(Spalten/Zelen) löschen
          base.Rows.Clear();
          base.Cols.Clear();
        }
        if(value!=null){
          base.BeginUpdate();
          vDataSource=value;

          // Spalten/Zeilen/Header einfügen
          base.AddCols(vDataSource.Columns.Count);
          base.AddRows(vDataSource.Rows.Count+1);
          base.Rows[0].Fixed=true;

          // Daten lesen und Zellwerte setzen
          for(int idx=0;idx<vDataSource.Columns.Count;idx++){
            int col=vDataSource.Columns[idx].Ordinal;
            string colName=vDataSource.Columns[col].ColumnName;
            DataRelation rel=null;

            // Vorhandene Beziehungen prüfen (Name=Spaltenname)
            if(vDataSource.ParentRelations.IndexOf(colName)>-1)
              rel=vDataSource.ParentRelations[colName];

            for(int row=1;row<vDataSource.Rows.Count;row++){
              DataRow dRow=vDataSource.Rows[row];
              DataRow[] lkup=dRow.GetParentRows(rel);

              // lookup-Daten oder normale Daten lesen
              if(lkup!=null && lkup.Length>0)
                this[col,row].Value=lkup[0][1];
              else
                base[col,row].Value=vDataSource.Rows[row][col];
            }
          }
          base.EndUpdate();
        }
      }
    }
  }
}

"Gefüttert" wird ein solches ppsDataGrid dann wie folgt:

Code: Select all

    public void Init(){
      string sql,connStr ="";

      vConnection = new SqlConnection();

      connStr += "user id=sa;";
      connStr += "password=sa;";
      connStr += "initial catalog=Northwind;";
      connStr += "data source=NONE;";
      connStr += "Connect Timeout=10";
      vConnection.ConnectionString = connStr;
      vConnection.Open();
    
      sql ="SELECT ShipName, ShipAddress, ShipCity FROM Orders";
      SqlDataAdapter da = new SqlDataAdapter(sql, vConnection);

      DataSet ds = new DataSet("Northwind");
      da.TableMappings.Add("Orders", "Orders");
      da.Fill(ds);
      this.ppsDataGrid1.SetDataBinding(ds);
    }
...oder mit Beziehungen etwas komplexer...

Code: Select all

public void Init(){
  string sql,connStr ="";
  DataColumn colPrnt,colChld;

  vConnection = new SqlConnection();

  connStr += "user id=sa;";
  connStr += "password=sa;";
  connStr += "initial catalog=Northwind;";
  connStr += "data source=NONE;";
  connStr += "Connect Timeout=10";
  vConnection.ConnectionString = connStr;
  vConnection.Open();

  sql ="SELECT * FROM Orders;";
  sql+="SELECT * FROM Customers;";
  sql+="SELECT * FROM Employees;";
  sql+="SELECT * FROM Shippers";

  SqlDataAdapter da = new SqlDataAdapter(sql, vConnection);
  DataSet ds = new DataSet("Northwind");

  da.TableMappings.Add("Orders", "Orders");
  da.TableMappings.Add("Customers", "Customers");
  da.TableMappings.Add("Employees", "Employees");
  da.TableMappings.Add("Shippers", "Shippers");
  da.Fill(ds);

  colChld=ds.Tables[0].Columns["CustomerID"];
  colPrnt=ds.Tables[1].Columns["CustomerID"];
  ds.Relations.Add("CustomerID",colPrnt,colChld);

  colChld=ds.Tables[0].Columns["EmployeeID"];
  colPrnt=ds.Tables[2].Columns["EmployeeID"];
  ds.Relations.Add("EmployeeID",colPrnt,colChld);

  colChld=ds.Tables[0].Columns["ShipVia"];
  colPrnt=ds.Tables[3].Columns["ShipperID"];
  ds.Relations.Add("ShipVia",colPrnt,colChld);

  this.ppsDataGrid1.SetDataBinding(ds);
}



In den Bespielen wird der SQL-Server mit der berühmten Tabelle "Northwind" benutzt (der Connectionstring muss natürlich angepasst werden).

Wer Datenänderungen der Tabelle im Grid mitverfolgen will, kann dies z. Beisp. über die Ereignisse "RowChanged/ing" oder RowDeleted/ing" sehr einfach erreichen. Das Demo verfolgt für Lookup's sogar die Beziehungen zwischen den Tabellen.

Das ganze ist aber nur ein Demo. Wer sich davon inspiriert füllt...bitte schön :-)

Gruß Torsten

Post Reply