Page 1 of 2 1 2 LastLast
Results 1 to 15 of 17

Thread: RichTextBox.lines als StringCollection

  1. #1
    Rifleman Numero uno
    Join Date
    Oct 2001
    Posts
    204

    RichTextBox.lines als StringCollection

    Om .net te leren, ben ik een aantal van mijn vroegere projecten aan het omzetten.
    In een method stond een argument van type Tstrings, welke is omgezet naar type StringCollection. Nu wil ik deze method aanroepen dmv RichTextBox.lines mee te geven, maar krijg een fout: types verschillen. Dat snap ik best, maar wat is de netste, meest .net gerichte manier om dit gewoon netjes te doen?
    If it ain't broke, it doesn't have enough features yet
    The day Microsoft doesn't s uck, is the day they make vacuum-cleaners!

  2. #2
    Bedoel je zoiets?

    Code:
    procedure TWinForm1.Test(Lines: array of string);
    begin
      RichTextBox2.Lines := Lines;
    end;
    
    procedure TWinForm1.Button1_Click(sender: System.Object; e: System.EventArgs);
    begin
      Test(RichTextBox1.Lines);
    end;
    Marcel

  3. #3
    Oh, en C# vind het ook goed op deze manier:

    Code:
    		private void Test(string[] Lines)
    		{
    			richTextBox2.Lines = Lines;
    		}
    
    		private void button1_Click(object sender, System.EventArgs e)
    		{
    		  Test(richTextBox1.Lines);
    		}
    Marcel

  4. #4
    Rifleman Numero uno
    Join Date
    Oct 2001
    Posts
    204
    Ik zal het proberen, maar ik bedoelde eigenlijk dit:

    Code:
    procedure WinForm1.Test(const EenArgument: StringCollection);
    begin
      {Iets doen met EenArgument}
    end;
    
    { Aanroep }
    Test(RichTextBox1.Lines);
    En daar gaat het fout, omdat ik het verkeerde type meegeef
    If it ain't broke, it doesn't have enough features yet
    The day Microsoft doesn't s uck, is the day they make vacuum-cleaners!

  5. #5
    SillyMember Dirk Andries's Avatar
    Join Date
    May 2003
    Location
    Gent
    Posts
    7,721
    Originally posted by Pogo
    Code:
      Test(RichTextBox1.Lines);
    Dit gaat dus nooit werken, omdat, zoals je zelf al opmerkte, een array van strings niet hetzelfde is als een StringCollection.
    Wat je wel kan doen is:
    a) zoals Marcel aangaf een procedure maken die een array van String verwacht.
    b) een procedure maken die een IList interface verwacht. IList erft over van ICollection en IEnumerable en de System.Array class implementeert IList, ICollection en IEnumerable.

    Beide methoden zullen echter niet toestaan dat je de tekst van de RichTextBox wijzigt. Het 'probleem' bij deze beide manieren van aanpak is namelijk dat je met RichTextBox.Lines property niet de 'interne lijst' van lijnen (de echte tekst dus) doorgeeft, maar als het ware een kopie. Als je in de VCL de Lines property van een RichEdit doorgeeft als parameter naar een functie of procedure (als TStrings) en je wijzigt daar de inhoud van die parameter dan pas je ook de tekst aan in de RichEdit zelve, met de RichTextBox.Lines is dat niet zo: je geeft dan eigenlijk een array mee die een kopie bevat. Je zou dit kunnen oplossen door RichTextBox.Lines als reference parameter mee te geven. In VB.Net werkt dat:
    Code:
    Private Sub DoeIets(ByRef Lijst() As String)
      For I As Int32 = 0 To Lijst.Length - 1
        Lijst(I) = String.Format("{0} - {1}", I + 1, Lijst(I))
      Next
    End Sub
    
    Private Sub Button1_Click(ByVal sender As System.Object, 
               ByVal e As System.EventArgs) Handles Button1.Click
      DoeIets(RichTextBox1.Lines)
    End Sub
    In Delphi 8 lukt dit niet omdat je de property Lines niet by reference kan doorgeven (als var parameter). Waarom dat is weet ik niet: by design (om compatibiliteitsredenen met Delphi Win32?) , een bug, of gewoon de kreupele implementatie van System.Array in D8, of beiden?

    Je kan eventueel wel een .NET VCL applicatie maken (met TRichEdit en TStrings) als het gaat om een port van een bestaand programma.

    Voor .NET WinForms ga je dus een andere oplossing moeten zoeken (een functie die een array of string teruggeeft, ...).
    Vraag is hier dan: wat moet er gebeuren in de procedure die wordt aangeroepen?
    All methodologies are based on fear. -- Kent Beck.

  6. #6
    SillyMember Dirk Andries's Avatar
    Join Date
    May 2003
    Location
    Gent
    Posts
    7,721
    Als die StringCollection belangrijk is, dan is een andere mogelijkheid: class helpers.
    Code:
    TRichTextBoxHelper = class helper for RichTextBox
      public
        function get_AsStringCollection: StringCollection;
        procedure set_AsStringCollection(const Value: StringCollection);
    
        property AsStringCollection: StringCollection
          read get_AsStringCollection write set_AsStringCollection;
      end;
    en dan:
    Code:
    procedure TWinForm.Button3_Click(sender: System.Object; e: System.EventArgs);
    var
      s: StringCollection;
    begin
      s := RichTextBox1.AsStringCollection;
      Test(s);
      RichTextBox1.AsStringCollection := s;
    end;
    
    // zou hier ook een functie van kunnen maken;
    procedure TWinForm.Test(Lijst: StringCollection);
    var
      I: integer;
    begin
      for I := 0 to Pred(Lijst.Count)  do
        Lijst[I] := System.String.Format('{0} - {1}',Succ(I),Lijst[I]);
      Lijst.Add('Koekoek');
    end;
    De StringCollection class is in mijn ogen trouwens niet zo nuttig (de containerklassen in .NET zijn trouwens nogal onhandig, ook al vanwege hun niet echt consistente interface). Ik merk dat ik nogal veel gebruik maak van ArrayList en StringBuilder, en tot mijn grote verbazing in C# en VB.NET dikwijls arrays gebruik (niet echt zo in D8, vanwege de al eerder vermelde m.i. minder geslaagde implementatie en syntactische moeilijkheden).
    Misschien is het hier ook handiger met een StringBuilder op de Text property te werken?

    Je kan ook de weg van delegates/callback methods opgaan, eventueel gecombineerd met een class helper method(s) die een delegate(s)/callback method(s) ontvang(t)(en). Dit zou het voordeel kunnen bieden dat je rechtstreeks op de RichTextBox.Lines[x] items zou kunnen werken als string.
    All methodologies are based on fear. -- Kent Beck.

  7. #7
    Rifleman Numero uno
    Join Date
    Oct 2001
    Posts
    204
    Ik denk dat mijn vraag verkeerd is!?
    Dus anders: Hoe kan ik TStrings vervangen?
    Ik wil NIET zelf een array besturen (Zelf groter maken etc.), maar gewoon:
    EenStringLijst.Add('Item')
    Ik geef in mijn method RichTextBox.Lines als var parameter mee, omdat ik de uitkomst van mijn method wil tonen in een RichTextBox
    If it ain't broke, it doesn't have enough features yet
    The day Microsoft doesn't s uck, is the day they make vacuum-cleaners!

  8. #8
    SillyMember Dirk Andries's Avatar
    Join Date
    May 2003
    Location
    Gent
    Posts
    7,721
    Je kan RichTextBox.Lines niet als var parameter doorgeven, toch?
    Wat is je code?
    Of de code die je wil omzetten?
    All methodologies are based on fear. -- Kent Beck.

  9. #9
    Rifleman Numero uno
    Join Date
    Oct 2001
    Posts
    204
    Toevallig staat de code op NLDelphi:
    [link]
    http://www.nldelphi.com/forum/showth...d&pagenumber=2
    [/link]

    Het antwoord dat ik geef bevat de procedure: "GenereerCompetitie"
    Deze heeft een var by ref: "Rapport".
    In vorige Delphi's riep ik deze alsvolgt aan:
    GenereerCompetitie(StrToInt(Edit1.Text), Memo1.Lines);

    Hoe kan ik dat nu zo ".net", zo netjes en met minimale code voor elkaar krijgen, zonder helper classes en terug te schakelen naar Delphi for .Net?
    If it ain't broke, it doesn't have enough features yet
    The day Microsoft doesn't s uck, is the day they make vacuum-cleaners!

  10. #10
    Ik snap er niet zoveel meer van. Wat bedoel je met terugschakelen naar Delphi for .NET? We hebben het toch juist over Delphi voor .NET, of mis ik je nou compleet?
    Marcel

  11. #11
    SillyMember Dirk Andries's Avatar
    Join Date
    May 2003
    Location
    Gent
    Posts
    7,721
    Ik denk dat hij bedoelt: VCL.NET.

    Probleem is dat de Delphi Win32 code die hij wil omzetten niet al te kosjer is.
    De GeneerCompetitie (method van een TForm!) doet om te beginnen minstens 2 verschillende dingen en moet eigenlijk TCompetitie.Genereer zijn, en het rapport is m.i. presentatie en dat itereert dan over de Competitie (lijst van TWedstrijd?). Verder worden (door het ontbreken van domeinklassen) UI en 'logica' op een hoopje gegooid.
    Ik zou dan ook het omzetten naar .NET (en blijkbaar moet het WinForm zijn om één of andere reden) gebruiken om de Delphi Win32 code aan een refactoring te onderwerpen, of indien dat niet wenselijk is, het 'ontwerp' nog eens te herbekijken.

    Indien dat niet haalbaar is: splits minstens op tussen 'genereren van een competitie' en het maken van een rapport, bijvoorbeeld:
    Code:
    function MaakRapport(EenCompetitie: ? ): array of string;
    Gebruik in maakrapport een ArrayList, een StringCollection,...
    Je kan als returntype ook gewoon een string nemen (en dan gebruik je een bijvoorbeeld een StringBuilder).
    All methodologies are based on fear. -- Kent Beck.

  12. #12
    Rifleman Numero uno
    Join Date
    Oct 2001
    Posts
    204
    @Marcel: idd VCL.NET

    @Dirk: Nu volg ik je echt niet meer...
    De "GeneerCompetitie" bedenkt een competite en plaatst deze in een Rapport. (Het is een overkoepelende procedure die doet wat de naam beloofd, dus wat bedoel je precies met min. 2 dingen?) Daar is volgens mij niks mis mee. Het is in huidige vorm geen method van een Form en dit mag allicht zo blijven.

    TCompetite.Genereer vind ik een goed idee.

    U.I. en logika blijven volgens mij gescheiden, omdat het resultaat een TStrings lijst is. Dat ik als aanroep kies voor Memo1.lines staat daar los van. Dat is als test.
    De procedure gebruikt zelf geen U.I.

    Dat het een functie had mogen zijn, met als resultaat TStrings maakt me niet zo veel uit.

    De rede dat ik voor WinForm kies is omdat dit volgens mij gebruik maakt van de "echte" .NET classes/objecten terwijl de VCL.NET alle Delphi types omzet naar .NET en daarom hen je hier de speciale Delphi/Borland libraries voor nodig (in uses)... Maar ik heb geen idee of dit nu echt waar is. Vandaar dat ik deze code wil omzetten, als 1e leermoment met .NET

    Er is geen ontwerp. Dit is in een half uur geschreven, om de gestelde vraag te beantwoorden en ook nu dient het meer als leermoment...

    Als ik: function MaakRapport(EenCompetitie: ? ): array of string;
    gebruik, kan ik dan RichTextbox1.lines := MaakRapport(EenCompetitie: ? ); doen?
    Want dat was nl. eigenlijk m'n vraag: Wat wordt ipv TStringList en TStrings gebruikt in .NET? Is er iets vergelijkbaars, dat dezelfde "luxe" heeft? Met luxe bedoel ik methods als .add en .delete etc.?

    I.i.g thnx voor de aandacht + adviezen.
    If it ain't broke, it doesn't have enough features yet
    The day Microsoft doesn't s uck, is the day they make vacuum-cleaners!

  13. #13
    SillyMember Dirk Andries's Avatar
    Join Date
    May 2003
    Location
    Gent
    Posts
    7,721
    Met
    Code:
    Ploeg = class
    private
      FNaam: string;
    public
      function get_Naam: string;
      constructor Create(ANaam: string);
      function ToString: string; override;
      property Naam: string read get_Naam;
    end;
    
    Wedstrijd = class
    private
      FThuisPloeg, FUitPloeg: Ploeg;
    public
      function get_ThuisPloeg: Ploeg;
      function get_UitPloeg: Ploeg;
    public
      constructor Create(AThuisPloeg, AUitPloeg: Ploeg);
      function ToString: string; override;
      property ThuisPloeg: Ploeg read get_ThuisPloeg;
      property UitPloeg: Ploeg read get_UitPloeg;
    end;
    
    Competitie = class(TObject,IEnumerable)
    private
      FWedstrijden: ArrayList;
    public
      function GetEnumerator: IEnumerator;
      function get_WedstrijdCount: Int32;
      function get_Wedstrijden(index: Int32): Wedstrijd;
    public
      constructor Create;
      destructor Destroy;override;
      procedure Genereer(APloegen: array of Ploeg);
      function ToArray: System.Array;
      property Wedstrijden[index: Int32]: Wedstrijd read get_Wedstrijden;
      property WedstrijdCount: Int32 read get_WedstrijdCount;
    private
    end;
    Kan je b.v. dit:
    Code:
    procedure FormMain.FormMain_Load(sender: System.Object; e: System.EventArgs);
    type
      Ploegen = array of Ploeg;
    begin
      FCompetitie := CompetitieU.Competitie.Create;
      FCompetitie.Genereer(
        Ploegen.Create(Ploeg.Create('Vooruit Weesp'),
                       Ploeg.Create('Eendracht Breda'),
                       Ploeg.Create('Ninove Kampioen'),
                       Ploeg.Create('Wilskracht Limburg')));
      ListBox1.DataSource := FCompetitie.ToArray;
      RichTextBox1.Text := Rapport;
    end;
    All methodologies are based on fear. -- Kent Beck.

  14. #14
    SillyMember Dirk Andries's Avatar
    Join Date
    May 2003
    Location
    Gent
    Posts
    7,721
    En Rapport:
    Code:
    function FormMain.Rapport: string;
    // Kan hier ook ToArray gebruiken
    // of WedstrijdCount en Wedstrijden[Index]
    var
      SB: StringBuilder;
    begin
      SB := StringBuilder.Create;
      with FCompetitie.GetEnumerator do
        while MoveNext do SB.Append(Current.ToString + Environment.NewLine);
      Result := SB.ToString;
      SB.Free;
    end;
    Voor dit resultaat (links ListBox, rechts RichTextBox).
    Attached Thumbnails Attached Thumbnails Click image for larger version. 

Name:	competitie.jpg 
Views:	152 
Size:	43.9 KB 
ID:	1880  
    All methodologies are based on fear. -- Kent Beck.

  15. #15
    Rifleman Numero uno
    Join Date
    Oct 2001
    Posts
    204
    Ik snap wat je bedoelt. Maar is dit DE manier in .NET? Want om nu strings te maken en daar een Linebreak achter te plakken of zelf een functie ToArray te schrijven dat vind ik geen luxe maar een paar jaar terug in de tijd. Dat zoiets door een Listbox of RichTextbox wordt begrepen is knap van die dingen, maar niet echt netjes. Eerst was "lines" een soort array en die gebruikte ik dan ook meestal. Ik zie direct RichTextbox.Text vullen niet als een vooruitgang.
    Ik kan me ook moeilijk voorstellen dat er niet een bepaalde class is welke wel een bijna equivalent is van TStringList. Maar goed, ik ken .NET niet... Blijkbaar sla ik er naast.

    Ik ga kijken naar de mogelijkheden van "string of array" en evt. andere arrays...

    Thnx 4 the info.
    If it ain't broke, it doesn't have enough features yet
    The day Microsoft doesn't s uck, is the day they make vacuum-cleaners!

Page 1 of 2 1 2 LastLast

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •