Delphi-PRAXiS
Seite 1 von 2  1 2      

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   TMyRadioButton.GetChecked wird nie aufgerufen (https://www.delphipraxis.net/156500-tmyradiobutton-getchecked-wird-nie-aufgerufen.html)

stahli 4. Dez 2010 12:16

TMyRadioButton.GetChecked wird nie aufgerufen
 
Hallo zusammen,

ich möchte einen eigenen RadioBotton erstellen, der Checked selbständig ermittelt (unabhängig von einer Gruppe etc).
Dazu wollte ich GetChecked und SetChecked überschreiben.
GetChecked wird aber nie aufgerufen!?

Delphi-Quellcode:
unit fMyRadioButton;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;

type
  TMyRadioButton = class(TRadioButton)
  private
    class var XXX: Boolean;
  protected
    function GetChecked: Boolean; override;
    procedure SetChecked(Value: Boolean); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
  end;

  TForm1 = class(TForm)
    procedure FormCreate(Sender: TObject);
  private
  public
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyRadioButton }

constructor TMyRadioButton.Create(AOwner: TComponent);
begin
  inherited;
end;

destructor TMyRadioButton.Destroy;
begin
  inherited;
end;

function TMyRadioButton.GetChecked: Boolean; // HIER KLEMMT ES
begin
  Result := XXX; // GetChecked wird nie aufgerufen
//  ich könnte testweise auch Result := True setzen um mein Anliegen zu verdeutlichen
end;

procedure TMyRadioButton.SetChecked(Value: Boolean);
begin
  XXX := not XXX;
  Invalidate;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
  MyRadioButton: TMyRadioButton;
begin
  for I := 1 to 10 do
  begin
    MyRadioButton := TMyRadioButton.Create(Self);
    MyRadioButton.Top := 20 * I;
    MyRadioButton.Left := 20;
    MyRadioButton.Caption := 'MyRadioButton ' + IntToStr(I);
    MyRadioButton.Parent := Self;
    MyRadioButton.XXX := True; // XXX wird auf Wahr gesetzt
  end;
end;

end.


Es soll also FChecked ignoriert und auf eine beliebige andere Bedingung geprüft werden.
Wenn der Wert durch Click geändert wird sollen keine anderen Schalter beeinflusst werden (daher kein inherited).

Es werden aber alle Buttons als "not Checked" gezeichnet.

SetChecked wird bei Click aufgerufen, nie aber GetChecked.

Kann ich irgendwie beim Zeichnen der Komponente meine eigene Bedingung abprüfen? Bei den Vorfahren blicke ich diesbezüglich nicht ausreichend durch :(

DeddyH 4. Dez 2010 14:00

AW: TMyRadioButton.GetChecked wird nie aufgerufen
 
Der Getter wird ja auch nur dann aufgerufen, wenn auf die entsprechende Eigenschaft lesend zugegriffen wird. Frag doch in Deinem Programm mal ab, ob der Radiobutton checked ist, dann solltest Du auch im Getter landen.

stahli 4. Dez 2010 14:21

AW: TMyRadioButton.GetChecked wird nie aufgerufen
 
Hmm, das soll ja beim Zeichnen erfolgen :!:

Ich bin davon ausgegangen, dass der Getter beim Zeichnen des Button abgefragt wird (dass also die Zeichenroutine entsprechend GetChecked entscheidet, ob sie den Knopf ausfüllt oder nicht).
Ich will quasi unabhängig vom FChecked selbst entscheiden, ob der Button "leer" oder "gefüllt" gezeichnet wird.
Ich kann aber absolut nicht nachvollziehen, wo und wie TRadioButton bzw. TButtonControl sich eigentlich zeichnen und wie und wo dabei Checked/UnCheckerd ausgewertet wird...:?:

Es geht also nur um das "korrekte" ZEICHNEN des Buttons.

Nach Möglichkeit will ich FChecked auch nicht "intern" manipulieren sondern dieses komplett ignorieren (und im Getter und Setter z.B. andere Variablen nutzen).

Bummi 4. Dez 2010 14:28

AW: TMyRadioButton.GetChecked wird nie aufgerufen
 
ich weiß nicht was Du genau vorhast, so verhält es sich wich checkboxen, ich meinte das als Intention bei Dir herausgelesen zu haben

Delphi-Quellcode:
unit Unit1;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls;


type
  TMyRadioButton = class(TRadioButton)
  private
    Fchecked: Boolean;
  protected
    function GetChecked: Boolean; override;
    procedure SetChecked(Value: Boolean); override;
  public
    constructor Create(AOwner: TComponent); override;
    destructor Destroy; override;
  published
  end;

  TForm1 = class(TForm)
    RadioButton1: TRadioButton;
    procedure FormCreate(Sender: TObject);
  private
    { Private-Deklarationen }
  public
    { Public-Deklarationen }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

{ TMyRadioButton }
{ TMyRadioButton }

constructor TMyRadioButton.Create(AOwner: TComponent);
begin
  inherited;
end;

destructor TMyRadioButton.Destroy;
begin
  inherited;
end;

function TMyRadioButton.GetChecked: Boolean; // HIER KLEMMT ES
begin
  inherited;
  Result := Fchecked;
end;

procedure TMyRadioButton.SetChecked(Value: Boolean);
begin
begin
  FChecked := not Fchecked;
  begin
    SendMessage(Handle, BM_SETCHECK, Integer(FChecked), 0);
    if Value then
    begin
      inherited Changed;
      if not ClicksDisabled then Click;
    end;
  end;
end;
end;



procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
  MyRadioButton: TMyRadioButton;
begin
  for I := 1 to 10 do
  begin
    MyRadioButton := TMyRadioButton.Create(Self);
    MyRadioButton.Top := 20 * I;
    MyRadioButton.Left := 20;
    MyRadioButton.Caption := 'MyRadioButton ' + IntToStr(I);
    MyRadioButton.Parent := Self;
    MyRadioButton.Checked := True; // XXX wird auf Wahr gesetzt
  end;
end;
end.

stahli 4. Dez 2010 15:08

AW: TMyRadioButton.GetChecked wird nie aufgerufen
 
Danke Bummi, aber das bringt mich noch nicht weiter.

Ich versuche es nochmal anders zu erklären:
Wenn der TMyRadioButton sich zeichnet soll er anhand einer von mir definierten Funktion Checked/UnChecked dargestellt werden.
Die Funktion kann z.B. auch einfach immer True zurückliefern.
Alle TMyRadioButtons sollen also jetzt Checked gemalt werden.

Als entsprechende Funktion habe ich (naheliegender Weise) den Checked-Getter vorgesehen, dieser wird aber beim Zeichnen des Buttons offenbar nicht ausgewertet... :?::?::?:

...

Ok, ich habe es habe es jetzt anders gelöst, aber eine Lösung nach obigem Muster wäre mir lieber.
Meine Notlösung:

Delphi-Quellcode:
function TodRadioButton.GetChecked: Boolean;
begin
  inherited;
end;

procedure TodRadioButton.SetChecked(Value: Boolean);
begin
  inherited;
  if Value then
    SetData; // entsprechender Wert wird geschrieben
end;

procedure TodRadioButton.WMPaint(var Message: TWMPaint);
begin
  GetData;
  if (CheckValue <> '') and (CheckValue = odCtrl.PropValue) then
    Checked := True; // Manipulation von FChecked
  inherited;
end;

Hier sieht man auch, was ich genau will und mache:
In CheckValue wird einem TodRadioGroup ein "Sollwert" zugewiesen. Weiterhin wird dem Botton eine Komponente zugeweisen, dessen Eigenschaft PropValue mit CheckValue verglichen wird.
Das Ergebnis ja/nein soll im TodRadioButton dargestellt werden.
Wird ein solcher Button angeklickt, weist er seinen Sollwert an odCtrl.PropValue zu.

Die Gruppierung der RadioButtons und die gegenseitige (de-)Aktivierung ist für mich eher störend.
Meine Buttons sollen sich nur auf ihren Sollwert konzentrieren und andere Schalter völlig ignorieren.

Die notwendigen (und eigentlich einfachen) Änderungen wollte ich durch Ersetzen der Getter und Setter erreichen. Der Getter wird aber beim Zeichnen der Buttons überhaupt nicht benutzt!?
Ich kann nicht mal erkennen, wo der Button überheupt gezeichnet wird. Das muss wohl irgendwas im Windows selbst sein.
Im TPanel kann ich erkennen, wo was warum gemalt wird, beim TRadioButton nicht.

Die Notlösung geht als Notlösung, aber sehr zufrieden bin ich damit noch nicht.

Bummi 4. Dez 2010 15:18

AW: TMyRadioButton.GetChecked wird nie aufgerufen
 
wenn Du im Setter statt
FChecked := not Fchecked;
Deine Property SollCheckvaue an FChecked übergibst sollte es das tun was Du möchtest?
Aber ich gebe zu, so ganz habe ich auch noch nicht verstanden wo Du hin willst.

stahli 4. Dez 2010 15:37

AW: TMyRadioButton.GetChecked wird nie aufgerufen
 
CheckValue und odCtrl.PropValue sind Strings.
Man könnte quasi auch
Delphi-Quellcode:
CheckValue = Edit1.Text
verwenden.

Wenn da eine übereinstimmung ist, soll der Schalter gecheckt gezeichnet werden, sonst ungecheckt.

Ich bin davon ausgegangen, dass der aktuelle Zustand beim Zeichnen des TRadioButton über GetChecked ermittelt wird - sollte man doch eigentlich erwarten.
Delphi-Quellcode:
procedure TRadioButton.Paint;
begin
  if Checked{WobeiHierGetCheckedVerwendetWerdenSollte} then
    MaleMitPunkt
  else
    MaleOhnePunkt;
end;
So läuft das aber nicht.
Wie es aber genau läuft, verstehe ich aber nicht (und kann das daher auch nicht für meine Zwecke anpassen). :(

Aber ich kann ja noch nicht mal mein Problem verständlich erklären :roll:

DeddyH 4. Dez 2010 15:39

AW: TMyRadioButton.GetChecked wird nie aufgerufen
 
Ich bin gerade zu faul, einen Blick in die Sourcen zu werfen, aber wenn nicht auf den Getter, sondern direkt auf die private Variable zugegriffen wird, dann geht Dein Gedankengang ins Leere.

Bummi 4. Dez 2010 16:00

AW: TMyRadioButton.GetChecked wird nie aufgerufen
 
Du kannst die beiden Komponenten Edit und Checkbox einander bekannt machen (2 Klassen ableiten), wenn sie sich kennen ruft das Edit im Change den Setter der Checklistbox auf, diese Vergleicht Soll mit ist und setzt Fchecked + das was ich Dir schon geschickt hatte. Wenn Die Checkbox geklickt wird und sie das Edit kennt ruft schreibt den Text in das Edit.
Damit es nicht zu einem Endlosloop kommt, die Handlungen nur ausführen wenn FChecked sich geändert hat.

Aber gegf. ist es ohnehin sinnvoller statt der Checkbox hier ein GraphicControl selbst zu schreiben.
Das Edit müßte auch nicht Abgeleitet werden wenn Du 2 Properties in die neue Checkbox(wie auch immer implementiert) packst Soll und Vergleich, die dann den Setter aufrufen, der dies überprüft, es würde dann langen im OnChange Vergleich zu schreiben.

stahli 4. Dez 2010 16:31

AW: TMyRadioButton.GetChecked wird nie aufgerufen
 
Ach Mann, ich hätte nicht von einer Edit anfangen sollen. Ich wollte nur darauf hinweisen, dass es sich um eine Texteigenschaft einer bestimmten Komponente handelt.

Immer wenn TodRadioButton gezeichnet wird, sollen halt beide Texte verglichen werden. Das ist ja kein großes Problem.
TRadioButton zeichnet sich aber auf irgendwelchen abstrusen Wegen, ohne GetChecked abzufragen.

Ein GraphicControl zu nutzen habe ich auch überlegt, aber dann ist meine o.g. Notlösung doch erst mal einfacher.
Ich habe schon mehrere Standardkomponenten für meine Zwecke angepasst und würde auch immer ganz gern vom "korrekten" Vorfahren ableiten.

Einige StandardControls sind schon ziemlich verzwickt und uneinheitlich aufgebaut. Auch die "mißbrauchten Ereignisse" (z.B. OnClick statt OnChange usw.) sind ziemlich unschön.
Mehr Einheitlichkeit und Überschreibbarkeit für Ableitungen wäre da schon wünschenswert.

PS: Bummi, nun mach aber doch mal Wochende :wink:


Alle Zeitangaben in WEZ +1. Es ist jetzt 17:48 Uhr.
Seite 1 von 2  1 2      

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