[c#] Overerven System.Data.DataRow wil niet?

Pagina: 1
Acties:

  • reyan
  • Registratie: November 2003
  • Laatst online: 17-12-2021
Waarschijnlijk een stom probleem omwille van mijn gebrekkige kennis van C#...

Ik heb een System.Data.DataTable waarmee ik een ListView wil vullen. Dat werkt eigenlijk al perfect. Maar ik zou graag wat extra zaken toevoegen aan de DataColumns en DataRows in de DataTable (zoals uit te voeren acties, kleuren, alignments...). Voor het DataColumn object was dit eenvoudig. Ik heb gewoon een nieuwe class gemaakt die erft van DataColumn en wat extra zaken kan opslaan. Een simpel voorbeeldje ervan staat hieronder:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class AdvancedDataColumn : System.Data.DataColumn
{
    private System.Windows.Forms.HorizontalAlignment ha =
        System.Windows.Forms.HorizontalAlignment.Left;

    public System.Windows.Forms.HorizontalAlignment HorizontalAlignment
    {
        get
        {
            return this.ha;
        }
        set
        {
            this.ha = value;
        }
    }
}

Werkt perfect!

En nu wou ik hetzelfde doen voor DataRow:

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class AdvancedDataRow : System.Data.DataRow
{
    private System.Drawing.Color bc =
        System.Drawing.SystemColors.Window;

    public System.Drawing.Color BackColor
    {
        get
        {
            return this.bc;
        }
        set
        {
            this.bc = value;
        }
    }
}


En dat geeft vreemd genoeg een compileerfout:

No overload for method 'DataRow' takes '0' arguments

Het is zoals ik eerder reeds zei waarschijnlijk iets stoms, maar ik zie het probleem niet. Ik doe toch maar gewoon hetzelfde als ik voor DataColumn heb gedaan? Wat moet ik doen om deze overerving toch te laten werken?

  • MrBucket
  • Registratie: Juli 2003
  • Laatst online: 29-10-2022
De DataRow kent geen default constructor (dwz. eentje zonder argumenten). Normaalgesproken, als je overerft roep je in de constructor van je afgeleide klasse impliciet de default constructor aan van de base class, tenzij je expliciet een andere constructor aanroept:
C#:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
public class A{
  public A(){ /* Default constructor */ }
  public A(int i) { /* Constructor #2 */ }
}

public class B: A{
  public B(string s){
    /* Impliciete aanroep naar de default constructor van A, voordat deze code wordt uitgevoerd */
  }

  public B(int i): base(i){
    /* Expliciete constructor chaining, roept A(int i) aan. */
  }

}


Nu is het zo dat de DataRow geen default constructor kent die impliciet aangeroepen kan worden door de afgeleide constructor. Wel kent de DataRow een static constructor (waar je niks aan hebt als je nieuwe DataRows wilt maken), en een internal constructor met de volgende signature:
C#:
1
protected internal DataRow(DataRowBuilder builder);


Je zult in de constructor van je afgeleide DataRow class dus deze constructor moeten aanroepen d.m.v. de ': base'-constructie.

[ Voor 7% gewijzigd door MrBucket op 09-01-2006 16:24 ]


  • reyan
  • Registratie: November 2003
  • Laatst online: 17-12-2021
Bedankt voor je toelichting... Je moet het toch maar weten :)

Ik heb in de AdvancedDataRow nu een constructor aangemaakt zoals je zei (althans dat is toch wat ik begrepen heb uit je uitleg):

code:
1
2
3
public AdvancedDataRow(System.Data.DataRowBuilder builder) : base(builder)
{
}


En de class compileert nu inderdaad zonder problemen. Echter het gebruik ervan lukt me niet... Waar ik normaal iets in de aard van
code:
1
System.Data.DataRow dr = dt.NewRow();
doe om nieuwe rijen toe te voegen (waarbij dt natuurlijk de DataTable is), lukt het me niet om dit aan te passen naar mijn AdvancedDataRow class. Even simpel
code:
1
AdvancedDataRow dr = dt.NewRow();
ervan maken lukt natuurlijk niet omdat NewRow een System.Data.DataRow object geeft ipv mijn AdvancedDataRow...

Met DataColumn was het allemaal nogal wat makkelijker... Class aanmaken, overerven, DataColumn veranderen naar AdvancedDataColumn en het boeltje werkte al :)

  • reyan
  • Registratie: November 2003
  • Laatst online: 17-12-2021
De aanhouder wint zeggen ze... Ik heb het opgelost gekregen.

Ik was ervan overtuigd dat de oplossing van MrBucket de juiste was. Maar het is slechts een deel van de oplossing. Omdat je een nieuwe rij niet op de klassieke manier kan maken, maar met DataTable's NewRow() method moet werken lag het eigenlijk voor de hand dat daar ook aan gesleuteld moest worden. Immers, NewRow() geeft een DataRow object terug en we willen net ons AdvancedDataRow object gebruiken. Dus? Een nieuwe class waarin we overerven van DataTable:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
public class AdvancedDataTable : System.Data.DataTable
{
    protected override Type GetRowType()
    {
        return typeof(AdvancedDataRow);
    }

    protected override System.Data.DataRow
        NewRowFromBuilder(System.Data.DataRowBuilder builder)
    {
        return new AdvancedDataRow(builder);
    }
}
Hier doen we niets anders dan de NewRow method oevrriden opdat de AdvancedDataRow zou gebruikt worden.

En dat werkt :)