Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Object-Pascal / Delphi-Language (https://www.delphipraxis.net/32-object-pascal-delphi-language/)
-   -   Delphi Zelle teilen (https://www.delphipraxis.net/105254-zelle-teilen.html)

SaFu 18. Dez 2007 20:10


Zelle teilen
 
Liste der Anhänge anzeigen (Anzahl: 1)
Hi und zwar habe ich mal ne kompizeirte frage hoffe das geht mit dem StringGrid

undzwar habe ich eine StringGrid jetzt soll irgend eine zelle mit der Rechten Maustaste angeklickt werden können, dort soll ein PopupMenü aufgehen in dem drinsteht zelle teilen.
Wenn ich diesen Eintrag anklicke soll sich die ausgewählte zelle in zwei teilen sodas man oben und unten in die zellen was schreiben kann. so wie auf dem bild

geht das ????

Namenloser 18. Dez 2007 20:13

Re: Zelle teilen
 
Geht imho nicht.
(Ausfühliche Antwort :stupid: )

Die Muhkuh 18. Dez 2007 20:17

Re: Zelle teilen
 
Mit OwnerDraw dürfte es gehen ;-)

taaktaak 18. Dez 2007 20:19

Re: Zelle teilen
 
Moin, Moin,
vielleicht aus der entgegengesetzten Richtung ansetzen: In der Standarddarstellung werden 2 Zeilen zu einer optischen Zeile verbunden. Nach dem Befehl "Zelle teilen", wird die optische "Verbindung" der Zelle im OnDraw aufgehoben und du kannst die "obere" und "untere" Zeile ganz normal benutzen - ist nur so 'ne spontane Idee...
Gruß Ralph

SaFu 18. Dez 2007 20:20

Re: Zelle teilen
 
Vielleicht sollte ich sagen das ich noch diesen code habe der was drüber zeichnet könnte es dadurch schwerder werden

Delphi-Quellcode:
procedure TForm7.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var Celltext :string;
    Farbe :boolean;
    Textformat :cardinal;
    n :integer;
begin
  Textformat:= DT_SINGLELINE;
   with (Sender as TStringGrid) do

    begin
     Celltext:= Cells[ACol, ARow];
     Farbe:= True; //Standardeinstellung der Zellen ist einfarbig

      if (Cells[ACol,ARow] = 'fa') or (Cells[ACol,ARow] = 'FA')then
        begin
          Canvas.Brush.Color:= ClRed; //Zellenfarbe
          Canvas.Font.Color:= ClWhite; //Schriftfarbe
          Canvas.Font.Style:= Canvas.Font.Style + [fsBold]; //Text fett
        end;

     if (Cells[ACol,ARow] = 'np') or (Cells[ACol,ARow] = 'NP')then
        begin
          Canvas.Brush.Color:= ClBlue; //Zellenfarbe
          Canvas.Font.Color:= ClWhite; //Schriftfarbe
          Canvas.Font.Style:= Canvas.Font.Style + [fsBold]; //Text fett
        end;

     if (Cells[ACol,ARow] = 'aa') or (Cells[ACol,ARow] = 'AA')then
       begin
        Canvas.Brush.Color:= ClGreen; //Zellenfarbe
        Canvas.Font.Color:= ClWhite; //Schriftfarbe
        Canvas.Font.Style:= Canvas.Font.Style + [fsBold]; //Text fett
       end;

    if (Farbe) then
       begin
        //Hintergrund überschreiben
        SetBkMode(StringGrid1.Canvas.Handle, OPAQUE);
        Canvas.FillRect(Rect)
       end;

    if (ACol = 1) or (ACol = 0) then
       begin
        //Text wird zentriert
        Textformat:= Textformat or DT_CENTER or DT_VCENTER ;
        Canvas.Font.Style:= Canvas.Font.Style + [fsBold]; //Text fett
       end;

    if (ACol > 1) then  //Zentrieren für alle Zellen
       begin
        //Text wird zentriert
        Textformat:= Textformat or DT_CENTER or DT_VCENTER;
       end;
  //Hier wird nun der Text ausgegeben
  DrawText(Canvas.Handle, PChar(Celltext), Length(celltext), Rect,Textformat);
end;
begin //Linien zwischen Zellen erzeugen
 n:=0 ;
 repeat
  n:=n+4;
   if (ARow = n) and (ACol >= StringGrid1.FixedCols) then
    begin
     StringGrid1.Canvas.Pen.Color := clBlack; // Linienfarbe
     StringGrid1.Canvas.Pen.Width := 2; // Stärkt der Linie
     StringGrid1.Canvas.MoveTo(Rect.Left,Rect.Bottom);
     StringGrid1.Canvas.LineTo(Rect.Right,Rect.Bottom);
    end;
  until n= 24;
 end;
end;

Namenloser 18. Dez 2007 20:22

Re: Zelle teilen
 
Geht es darum, dei Zelle nur "optisch" zu teilen, sodass sie sich weiterhin so verhält wie eine Zelle?
Oder soll die wirklich in zwei Zellen geteilt werden wie z.B. bei Excel? Ich hatte zweiteres verstanden. das erste soltle mit OwenrDraw möglich sein.

SaFu 18. Dez 2007 20:26

Re: Zelle teilen
 
Sie soll sich eigentlich so verhalten wie eine normalle zelle Sie darf aber nicht größer werden, sondern nur teilen so das man oben und unten was reinschreiben kann, also muss auch gleichzeitig die schriftart kleiner werden

SaFu 27. Dez 2007 12:22

Re: Zelle teilen
 
HI

kann mir vielleicht irgenwie einen ansatz geben hab jetzt mal die letzten Tag mal versucht das hinzubekommen ab ich bin am verzeweifeln

Real_Thunder 27. Dez 2007 13:08

Re: Zelle teilen
 
Moin hier mal in stichworten:

- die zelle mit mousetocell merken in der du den befehl gibst.

- stringgrid um eine spalte erweitern

- den inhalt aller felder nach der zelle einen weiter schieben, evt auch die breite etc...

- die spaltenbreite in der die zu teilene zelle ist halbieren, das selbe mit der spalte rechts daneben.

- im oncelldraw event der stringgrid das rect der beiden spalten addieren.
(bis auf die zelle die "geteilt" werden soll)
(rect.right := rect.right*2) oder ähnlich


So das sollte als ansatz dienen

SaFu 29. Dez 2007 19:04

Re: Zelle teilen
 
Hi nochmal ich

also hab jetzt mal den anfang gemacht das ging ja schon :-D

Delphi-Quellcode:
 procedure TForm7.StringGrid1MouseDown(Sender: TObject; Button: TMouseButton;
  Shift: TShiftState; X, Y: Integer);
var col, row: integer;
begin
 StringGrid1.MouseToCell(x, y, col, row);
end;
aber wieso die zelle verschieben und die spalte um 1 erweitern ich möchte doch nur die ausgewählte zelle in zwei teilen so das ich oben und unten was schreiben kann.

s-off 3. Jan 2008 13:55

Re: Zelle teilen
 
Hallo,

wie bereits meine Vor'redner' geschrieben haben, wird eine absolute horizontale Splittung einer Zelle nicht möglich sein.
Der Ansatz von Real_Thunder geht in die Richtung einer vertikalen Teilung, was allerdings ebensowenig funktioniert.

Eine optische Aufteilung ist möglich, und genau da würde ich ansetzen:
  • Erzeuge eine neue Klasse, abgeleitet von TStringGrid und definiere die OnDrawCell-Eigenschaft neu. Die Reaktion auf das Event, also den Inhalt der DrawCell-Methode, erläutere ich später.
  • Erzeuge eine neue Klasse, nenne sie z.B. TCellValue, abgeleitet von TObject, und gebe dieser zwei Felder - sUpperValue und sLowerValue; beide als String. Diese repräsentieren hinterher den Inhalt Deiner Zelle; den oberen und den unteren Teil.
  • Im OnClick-Event des PopupMenü-Items, welches die Teilung vornehmen soll, rufst Du eine Methode auf, welche die optische Teilung der Zelle letztendlich durchführt.
  • Diese erzeugt eine Instanz von TCellValue und weist sie der Zelle zu (als Objekt - TStringGrid.Objects). Anschliessend ruft sie die Repaint-Methode Deines Grids auf, welche wiederrum das hinter OnDrawCell steckende Event auslöst und Deine(!) DrawCell-Methode aufruft.
  • Nun also der Inhalt Deiner DrawCell-Methode (dafür hast Du im ersten Schritt die OnDrawCell-Eigenschaft neu definiert): in dieser prüfst Du, ob die Zelle, die gerade neu gezeichnet wird, ein Objekt (TCellValue) besitzt. Ist dieses nicht der Fall, dann einfach die Zelle zeichnen. Ist dieses aber der Fall, dann wird die Zelle optisch geteilt. Dazu ziehst Du auf dem Canvas einfach eine horizontale Linie im Rect der Zelle (halbe Höhe, gesamte Breite).
  • Da sich die Zelle nun aber nur wie eine einzelne Zelle verhält, nicht wie zwei, kannst Du die Unterscheidung, ob Du in den oberen oder den unteren Teil schreiben willst, nur durch einen Mausklick treffen; entweder Du klickst über der Linie, oder darunter.
    Du merkst Dir also, ob beim Aufruf des Zell-Editors über-, oder unterhalb der Linie geklickt wurde.
  • Nun schreibt der Anwender den Text in die Zelle. Ist er damit fertig, gehts weiter. Je nachdem, ob ober- oder unterhalb der Trennlinie geklickt woreden ist, editierst Du sUpperValue oder sLowerValue aus dem Objekt der Zelle (TCellValue).
  • Abschliessend malst Du den nun editierten Inhalt von Deinem TCellValue-Objekt auf das Canvas des Grids - den oberen Teil über die Linie, und den unteren Teil darunter; hierbei musst Du dann natürlich die Schriftgröße entsprechend anpassen und darfst keinen Zeilenumbruch zulassen.

Soviel zur Theorie - viel Erfolg bei der Umsetzung :zwinker:

Edit: Rechtschreibung


Alle Zeitangaben in WEZ +1. Es ist jetzt 23:33 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz