Custom DB Web Controls

Custom DB Web Controls

Ik laat in dit artikel zien hoe we Custom ASP.NET DBWeb Web Controls kunnen maken met Delphi 2006. Dit artikel bevat informatie die ik ook tijdens mijn sessie op het Software Developer Event van 15 september zal presenteren.

DB Web Controls

ASP.NET DB Web controls zijn te vinden in de Enterprise editie van Delphi for .NET (bijvoorbeeld Delphi 2006, wat ik in dit artikel zal gebruiken). Een ASP.NET DB Web control is een beetje te vergelijken met een VCL data-aware control. Via een DataSource kan de visuele component zich voorzien van data, door een tablename en optioneel fieldname property. En waar we vanaf Delphi 1.0 met behulp van een TDataSource de data-aware componenten zoals TDBGrid en TDBEdit kunnen voorzien van data, zo kunnen we in Delphi for .NET met een DBWebDataSource de DBWeb controls zoals de DBWebGrid en DBWebTextBox voorzien van data.

Custom DB Web Control

Voor alle .NET custom controls moeten we eerst een Delphi for .NET Package project starten om uiteindelijk tot een .NET Assembly te komen. Speciaal voor custom DB Web controls heeft Delphi een DBWeb Custom Control wizard, te vinden in de New ASP.NET Files category in de Object Repository (zei figuur 1).

Fig. 1: Object Repository

Hiermee krijg je de New DBWeb Control Wizard, waar je behalve de naam van de nieuwe control, ook een aantal keuzemogelijkheden hebt, zoals in figuur 2 te zien is. De default keuze geeft je een nieuwe DB Web control die aan een hele DataTable bindt. Dat is iets dat je bij een DataGrid bijvoorbeeld ziet. Het alternatief is een DB Web control die aan een DataColumn (alsmede een DataTable) bindt, zoals een TextBox control. De laatste keuze is ook mogelijk in combinatie met een loopup link (zoals in een DBLookupCombobox).

Fig. 2: New DBWeb Control Wizard

Bij een keuze voor de DataTable zal het nieuwe control een DBDataSource en TableName property hebben, en bij keuze voor de DataColumn zal er behalve de DBDataSource en TableName ook een ColumnName property zijn. Dit wordt afgedwongen door respectievelijk het IDBWebDataLink en IDBWebColumnLink interface uit de Borland.Data.Web namespace.

Tijdens het SDE van 15 september zal ik een aantel verschillende nieuwe DB Web controls bouwen, waaronder een DBWebDataTableInfo die de DataTable binding doet, en een DBWebSpinEdit die de DataColumn binding doet. De DBWebSpinEdit kan overigens op verschillende manieren aangepakt worden, en legt nog een klein probleem bloot met de door de New DB Web Control Wizard gegenereerde code, maar daarover meer tijdens het SDE. Het voorproefje in dit artikel gaat slechts over de DBWebDataTableInfo.

DBWebDataTableInfo

Voor de DBWebDataTableInfo moeten we dus de default keuze op Bind to DataTable laten staan. De dan gegenereerde unit bevat de class DBWebDataTableInfo, afgeleid van System.Web.UI.WebControls.WebControl, met de interfaces IPostBackDataHandler en IDBWebDataLink. De IDBWebDataLink zorgt dat we de DBDataSource en TableName properties tot onze beschikking hebben.

Delegate

Als we de gegenereerde source code van de DBWebDataTableInfo bekijken, dan valt al snel op dat er een FMyDelegate veld in voorkomt, in commentaar. Het idee is dat we of deze default FMyDelegate gebruiken, of zelf een veld definiëren dat de waarde alsmede de (re)presentatie van de waarde voor zijn rekening neemt. De FMyDelegate is standaard een TextBox control, maar in ons geval wil ik eigenlijk liever een (read-only) Label gebruiken. Dus alle plaatsen waar de FMyDelegate staat moeten we die uit het commentaar halen, maar wel van een TextBox in een Label veranderen.

In de class declaratie van de DBWebDataTableInfo is dat als volgt:

strict private FMyDelegate: &Label; // BS

Vervolgems moeten we in de constructor het FMyDelegate veld als type Label aanmaken, als volgt:

constructor DBWebDataTableInfo.Create;
begin
  inherited;
  FMyDelegate := &Label.Create; // BS
  FDataLink := DBWebDataLink.Create(self);
  // Standard DB Web interface should always be defined
  FIDataLink := (FDataLink as IDBWebDataLink);
end;

En in GetText moeten we alleen het gebruik van FMyDelegate uit het commentaar halen.

function DBWebDataTableInfo.GetText: string;
var
  sw: StringWriter;
  tw: HtmlTextWriter;
begin
  sw := StringWriter.Create;
  tw := HtmlTextWriter.Create(sw);
  DataBind();
  FMyDelegate.RenderControl(tw); // BS
  Result := sw.ToString();
end;

De implementatie van GetText verzorgt meteen de HTML rendering voor ons. Straks gaan we daar in de DataBind een stukje extra informatie aan toevoegen, maar eerst nog een laatste stap die noodzakelijk is voor read-only DB Web controls. We moeten voor read-only controls de aanroep naar de RegisterHiddenField in de OnPreRender method in commentaar zetten of helemaal verwijderen. In ons geval is de DBWebDataTableInfo inderdaad read-only, dus moeten we de OnPreRender als volgt aanpassen:

procedure DBWebDataTableInfo.OnPreRender(args: EventArgs);
begin
  inherited OnPreRender(args);
  // You need to register the hidden field to identify the key for
  // read-write controls only. Remove this call if control is read-only.
  // Page.RegisterHiddenField(DBWebDataSource.IdentPrefix +
  //   DBWebConst.Splitter + IDataLink.TableName, self.ID);
  DataBind;
end;

Daarna komen we uiteindelijk bij de DataBind aan, waar de inhoud van het DB Web control wordt weggeschreven naar de FMyDelegate’s Text property. In de DataBind method moeten we de data verzorgen, maar de HTML opmaak wordt over het algemeen in de GetText method gedaan. In dit eenvoudige voorbeeld wijk ik af van die regel, en stop ik de HTML opmaak in de DataBind (het is toch maar een read-only control, en op deze manier is de opmaak sneller gedaan).

DataBind – Analysing DBDataSource

In de DataBind method kunnen we de DBDataSource property analyseren, en daar dan het resultaat van weergeven. Allereerst moeten we controleren of de DBDataSource wel assigned is, wat bijvoorbeeld nog niet het geval is als de DBWebDataTableInfo net op een form is gezet. Alleen als de DBWebDataSource property een waarde heeft, kunnen we er gebruik van maken om de GetDataSourceName method aan te roepen. Dit geeft ons de naam van de DBWebDataSource zelf. Daarnaast kunnen we de GetDataSource method aanroepen, die niet de DBWebDataSource, maar juist de DataSet, DataTable of DataView teruggeeft waar de DBWebDataSource mee verbonden is.

Als we eenmaal de DataSource hebben, dan kunnen we kijken of er DataTables in zitten, en daarvan dan de kolommen (de meta-data), waarbij we van iedere kolom de ColumnName, DataType en de MaxLength waarde kunnen weergeven. Een soort analyse van de data structuur binnen de tabellen dus.

procedure DBWebDataTableInfo.DataBind;
var
  DS: DataSet;
  DT: DataTable;
  DC: DataColumn;
begin
  try
    // DataBind whatever properties you require wherever you see
    // See the C# source code for DBWebNavigator and DBWebLabeledTextBox
    // for additional examples.

    // Set value to blank if not data bound

    // call to inherited triggers setting of DBDataSource.
    inherited DataBind;

    if Assigned(FIDataLink.DBDataSource) then
    try
      FMyDelegate.Text :=
        FIDataLink.DBDataSource.GetDataSourceName(Page) +
        '
';
      if FIDataLink.DBDataSource.GetDataSource(Page) is DataSet then
      begin
        DS := FIDataLink.DBDataSource.GetDataSource(Page) as DataSet;
        for DT in DS.Tables do
        begin
          FMyDelegate.Text := FMyDelegate.Text +
            '';
          for DC in DT.Columns do
            if DC.MaxLength > -1 then
              FMyDelegate.Text := FMyDelegate.Text +
                ''
            else
              FMyDelegate.Text := FMyDelegate.Text +
                ''
        end
      end
      else
      begin
        if FIDataLink.DBDataSource.GetDataSource(Page) is DataView then
          DT := (FIDataLink.DBDataSource.GetDataSource(Page) as
                 DataView).Table
        else
          if FIDataLink.DBDataSource.GetDataSource(Page) is DataTable then
            DT := FIDataLink.DBDataSource.GetDataSource(Page) as DataTable
          else DT := nil;
        if Assigned(DT) then // DataTable
        begin
          FMyDelegate.Text := FMyDelegate.Text +
            '';
          for DC in DT.Columns do
            if DC.MaxLength > -1 then
              FMyDelegate.Text := FMyDelegate.Text +
                ''
            else
              FMyDelegate.Text := FMyDelegate.Text +
                ''
        end
      end;
      FMyDelegate.Text := FMyDelegate.Text + '
' +
              DT.TableName + '
' + DC.ColumnName +
                '
' + DC.DataType.ToString +
                '[' + DC.MaxLength.ToString + ']
' + DC.ColumnName +
                '
' + DC.DataType.ToString + '
' +
              DT.TableName + '
' + DC.ColumnName +
                '
' + DC.DataType.ToString +
                '[' + DC.MaxLength.ToString + ']
' + DC.ColumnName +
                '
' + DC.DataType.ToString + '
'
    except
      on E: Exception do
        FMyDelegate.Text := FMyDelegate.Text +
          '
' + E.Message + '

'
    end
    else
      FMyDelegate.Text := 'DBWebDataTableInfo'
  except
    on E: Exception do
    begin
      if (not ClassUtils.IsDesignTime(Page)) then
        Page.Response.Write(ClassUtils.GetInternalError(Page, FIDataLink, E,
        Self.ID))
    else
      Raise Exception(E);
  end;
end;

Merk op dat de DBWebDataSource aan zowel een DataSet, DataTable als DataView verbonden kan zijn, en de code moet dan ook met alledrie de situaties rekening houden.

Het resultaat is te zien in figuur 3, waarin de DBWebDataTableInfo tijdens design-time te zien is als een HTML table, verbonden met de DBWebDataSource1 (de naam boven de table), die op zijn beurt is verbonden met een DataSet met daarin de Products table, die de velden ProductID, ProductName, etc. heeft. Van ieder veld is de naam en het type te zien. Op die manier kunnen we zowel tijdens design-time als tijdens run-time de meta-data van een DataTable verbonden met de DBWebDataSource zien.

Fig. 3: DBWebDataTableInfo

Tijdens de sessie op het SDE zal ik behalve de DBWebTableInfo ook een wat uitgebreide DBWebSpinEdit laten zien, op twee verschillende manieren overigens, waarvan eentje leidt tot het vinden van een bug in de code die de New DBWeb Control Wizard genereert – plus een oplossing uiteraard. Daarnaast zal ik tijdens deze sessie ook ingaan op de deployment details.

De sourcecode bij dit artikel is te downlaoden via Swart_CustomDBWebControls_SRC.zip.

Commentaar van anderen:
lkm op 12-8-2010 om 8:08
DisplaySearch Vintage Informal Wedding Dressesmarket analyst Paul GagnonBridal Dressessaid alternatives obviously Beach wedding dressesscratch easier, they'reVintage Plus Size Wedding Dressthicker and heavier, butwedding gowns they're also cheaper. He estimates wedding gownsthat a sheet of Gorilla would add $30 to $60 to the cost of a set.
ChristianLouboutin op 16-8-2010 om 4:51
Christian Louboutin Shoes, Christian Louboutin, Christian Louboutin Shoes, Wedding Shoes, Christian Louboutin comfortable shoes are women best resolution Whoever you, Drafted this think you can expect to take pleasure in Christian Louboutin Shoes, Wedding Shoes, Christian Louboutin, Christian Louboutin Shoes. This sneakers experience women charm additionally sexy. Wedding Shoes, Discount Christian Louboutin, Christian, Louboutin, Christian Louboutin Sale This is usually fantastic Louboutin Shoes, Louboutin Sale, Cheap Christian Louboutin, Christian Louboutin Discount, Christian Louboutin Boots. As a result exist to help opt designed for style, you cherish it is usually to help opt in order for most of the eye-catching Christian Louboutin Pumps, Christian Louboutin Sandals, Christian Louboutin Flats, Christian Louboutin Evening, Christian Louboutin Wedges taht can acquire inspiration designed for his fatal stiletto investigation connected with an incident that will occurred as part of his the beginning of the twenties. Christian Louboutin Pumps, Christian Louboutin Boots, Christian Louboutin Sandals, Christian Louboutin Flats, Manolo Blahnik Shoes He visited a museum and furthermore, saw a warning that will forbade women in order to really act, Yves Saint Laurent Shoes, Yves Saint Laurent Boots, YSL Shoes, Miu Miu Shoes during bearing stilettos ready, fearing damage in order to this extensive wood floors. Herve Leger V Neck Dress, Herve Leger Bandage Dress, Herve Leger Dress, Herve Leger V Neck Dress This image stayed in their head, along with he used this idea later in his louboutin shoes.
Geef feedback:

CAPTCHA image
Vul de bovenstaande code hieronder in
Verzend Commentaar
GebruiksovereenkomstPrivacybeleid