2016-03-28 4 views
-2

Delphi XE6Erstellen einer FMX TRadioGroup aus VCL-Code?

Ich versuche, eine FMX TRadioGroup mit Code aus der VCL zu erstellen. Alles über das Steuerelement scheint gut zu funktionieren, mit Ausnahme der folgenden Probleme

1.) Es scheint, dass der Fokus auf dem Steuerelement verloren geht und der RadioButton (aktueller Index) nicht angezeigt, geklickt, wenn ich auf ein anderes Steuerelement klicke, insbesondere ein anderes TTestRadioGroup-Steuerelement.

2.) In FMX-Steuerelementen möchte ich meine Schaltflächen neu anordnen, wenn eine Größenänderung auftritt, jedoch scheint es, als ob die Größenänderungsmethode nicht funktioniert, wenn Sie sie überschreiben.

thanx

unit TestComponents; 

interface 

uses {$IFDEF MSWINDOWS}Windows, {$ENDIF} 
System.Classes, FMX.Edit, System.UITypes, System.Character, FMX.DateTimeCtrls, 
System.SysUtils, FMX.Types, System.DateUtils, System.SysConst, FMX.Controls, 
FMX.Pickers, FMX.Platform, FMX.Text, math, FMX.Consts, FMX.Forms, FMX.StdCtrls; 

type 

TTestRadioGroup = class; 

TTestGroupButton = class(TRadioButton) 
    private 
    protected 
    public 
    constructor InternalCreate(RadioGroup: TTestRadioGroup); 
    destructor Destroy; override; 
    end; 

    TTestRadioGroup = class(TGroupBox) 
    private 
    FButtons: TList; 
    FItems: TStrings; 
    FItemIndex: Integer; 
    FColumns: Integer; 
    FUpdating: Boolean; 
    FButtonLeftMargin: Integer; //radio buttons left margin 
    FButtonTopMargin: Integer; //radio buttons starting Y postition 
    FButtonSpacing: Integer; //space between radio buttons 
    FButtonWidth: Integer; //width of the radio buttons 
    FColumnSpacing: Integer; //space between radio button columns 
    function GetButtons(Index: Integer): TRadioButton; 
    procedure SetButtonLeftMargin(Value: Integer); 
    procedure SetButtonTopMargin(Value: Integer); 
    procedure SetButtonSpacing(Value: Integer); 
    procedure SetButtonWidth(Value: Integer); 
    procedure SetColumnSpacing(Value: Integer); 
    procedure SetColumns(Value: Integer); 
    procedure SetItemIndex(Value: Integer); 
    procedure SetItems(Value: TStrings); 
    procedure ItemsChange(Sender: TObject); 
    procedure SetButtonCount(Value: Integer); 
    procedure ButtonClick(Sender: TObject); 
    procedure UpdateButtons; //updates buttons list from Items list 
    procedure ArrangeButtons; //rearranges buttons on Groupbox based on new properties 
    protected 
    public 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy; override; 
    procedure Resize; override; 
    property Buttons[Index: Integer]: TRadioButton read GetButtons; 
    published 
    property ItemIndex: Integer read FItemIndex write SetItemIndex default -1; 
    property Items: TStrings read FItems write SetItems; 
    property Columns: Integer read FColumns write SetColumns default 1; 
    property ButtonLeftMargin: Integer read FButtonLeftMargin write SetButtonLeftMargin default 10; 
    property ButtonTopMargin: Integer read FButtonTopMargin write SetButtonTopMargin default 50; 
    property ButtonSpacing: Integer read FButtonSpacing write SetButtonSpacing default 20; 
    property ButtonWidth: Integer read FButtonWidth write SetButtonWidth default 50; 
    property ColumnSpacing: Integer read FColumnSpacing write SetColumnSpacing default 100; 
    end; 


procedure Register; 

implementation 

procedure Register; 
begin 
RegisterComponents('Test', [TTestRadioGroup, TTestGroupButton]); 
end; 


{ TTestGroupButton } 

constructor TTestGroupButton.InternalCreate(RadioGroup: TTestRadioGroup); 
begin 
    inherited Create(RadioGroup); 
    RadioGroup.FButtons.Add(Self); 
    Visible := False; 
    Enabled := RadioGroup.Enabled; 
    OnClick := RadioGroup.ButtonClick; 
    Parent := RadioGroup; 
    Stored:= False; 
end; 

destructor TTestGroupButton.Destroy; 
begin 
    TTestRadioGroup(Owner).FButtons.Remove(Self); 
    inherited Destroy; 
end; 

{ TTestRadioGroup } 

constructor TTestRadioGroup.Create(AOwner: TComponent); 
begin 
    inherited Create(AOwner); 
    FButtons := TList.Create; 
    FItems := TStringList.Create; 
    TStringList(FItems).OnChange := ItemsChange; 
    FItemIndex := -1; 
    FColumns := 1; 
    FButtonLeftMargin:= 10; 
    FButtonTopMargin:= 50; 
    FButtonSpacing:= 20; 
    fButtonWidth:= 50; 
    FColumnSpacing:= 20; 
end; 

destructor TTestRadioGroup.Destroy; 
begin 
    SetButtonCount(0); 
    TStringList(FItems).OnChange := nil; 
    FItems.Free; 
    FButtons.Free; 
    inherited Destroy; 
end; 

procedure TTestRadioGroup.ArrangeButtons; 
const 
MAXBTNSPERCOL = 100; 
var 
I, X,Y: Integer ; 
BtnCount, BtnsPerCol: Integer; 
begin 
    if (FButtons.Count <> 0) then 
    begin 
    try 
    BtnCount:= 0; //initialize local button count 
    BtnsPerCol:= 0; //initialize local buttons per column 
    if FColumns > 1 then 
     BtnsPerCol:= FButtons.Count DIV fColumns //get # of btn per col 
    else 
     BtnsPerCol:= MAXBTNSPERCOL; 
     X:= FButtonLeftMargin; //set the intial X position 
     Y:= FButtonTopMargin; //set the initial Y position 

     for I := 0 to FButtons.Count - 1 do 
     begin 
     if BtnCount <= BtnsPerCol then 
     begin 
     TTestGroupButton(FButtons[I]).Position.X:= X; 
     TTestGroupButton(FButtons[I]).Position.Y:= Y; 
     Y:= Y + FButtonSpacing; 
     end //if btnCount 
     else 
     begin 
     Y:= FButtonTopMargin; 
     X:= X + FButtonWidth + FColumnSpacing; 
     TTestGroupButton(FButtons[I]).Position.X:= X; 
     TTestGroupButton(FButtons[I]).Position.Y:= Y; 
     end; //else 
     if BtnCount = BtnsPerCol then 
     begin 
     Y:= FButtonTopMargin; 
     X:= X + FButtonWidth + FColumnSpacing; 
     TTestGroupButton(FButtons[I]).Position.X:= X; 
     TTestGroupButton(FButtons[I]).Position.Y:= Y; 
     BtnCount:= 0; 
     Y:= Y + FButtonSpacing; 
     end; 
     TTestGroupButton(FButtons[I]).Visible := True; 
     inc(BtnCount); 
    end; 

    finally 
    end; 
    end; 
end; 

procedure TTestRadioGroup.UpdateButtons; 
var 
    I: Integer; 
begin 
    SetButtonCount(FItems.Count); 
    for I := 0 to FButtons.Count - 1 do 
    begin 
    TRadioButton(FButtons[I]).Width := FButtonWidth; 
    TRadioButton(FButtons[I]).Text := FItems[I]; 
    TRadioButton(FButtons[I]).StyleLookup:= 'radiobuttonstyle'; 
    end; 
    if FItemIndex >= 0 then 
    begin 
    FUpdating := True; 
    TRadioButton(FButtons[FItemIndex]).isChecked := True; 
    FUpdating := False; 
    end; 
    ArrangeButtons; 
    Repaint; 
end; 

procedure TRunitRadioGroup.Resize; 
begin 
inherited; 
ArrangeButtons; 
// Repaint; 
end; 

procedure TTestRadioGroup.ButtonClick(Sender: TObject); 
begin 
    if not FUpdating then 
    begin 
    FItemIndex := FButtons.IndexOf(Sender); 
    Change; 
    Click; 
    end; 
end; 


procedure TTestRadioGroup.ItemsChange(Sender: TObject); 
begin 
    if FItemIndex >= FItems.Count then 
     FItemIndex := FItems.Count - 1; 
    UpdateButtons; 
end; 

procedure TTestRadioGroup.SetColumns(Value: Integer); 
begin 
    if Value < 1 then Value := 1; 
    if Value > 16 then Value := 16; 
    if FColumns <> Value then 
    begin 
    FColumns := Value; 
    ArrangeButtons; 
    Repaint; 
    end; 
end; 

procedure TTestRadioGroup.SetItemIndex(Value: Integer); 
begin 
if Value < -1 then Value := -1; 
if Value >= FButtons.Count then Value := FButtons.Count - 1; 
if FItemIndex <> Value then 
    begin 
     if FItemIndex >= 0 then 
     TRadioButton(FButtons[FItemIndex]).isChecked := False; 
     FItemIndex := Value; 
     if FItemIndex >= 0 then 
     TRadioButton(FButtons[FItemIndex]).isChecked := True; 
    end; 
end; 

procedure TTestRadioGroup.SetItems(Value: TStrings); 
begin 
    FItems.Assign(Value); 
end; 

procedure TTestRadioGroup.SetButtonCount(Value: Integer); 
begin 
    while FButtons.Count < Value do 
    TTestGroupButton.InternalCreate(Self); 
    while FButtons.Count > Value do 
    TTestGroupButton(FButtons.Last).Free; 
end; 

procedure TTestRadioGroup.SetButtonLeftMargin(Value: Integer); 
begin 
if FButtonLeftMargin <> Value then 
    FButtonLeftMargin:= Value; 
    ArrangeButtons; 
end; 

procedure TTestRadioGroup.SetButtonTopMargin(Value: Integer); 
begin 
if FButtonTopMargin <> Value then 
    FButtonTopMargin:= Value; 
    ArrangeButtons; 
end; 

procedure TTestRadioGroup.SetButtonSpacing(Value: Integer); 
begin 
if FButtonSpacing <> Value then 
    FButtonSpacing:= Value; 
    ArrangeButtons; 
end; 

procedure TTestRadioGroup.SetButtonWidth(Value: Integer); 
var I: Integer; 
begin 
if FButtonWidth <> Value then 
begin 
    FButtonWidth:= Value; 
    for I := 0 to FButtons.Count - 1 do 
    TRadioButton(FButtons[I]).Width := FButtonWidth; 
    ArrangeButtons; 
end; 
end; 

procedure TTestRadioGroup.SetColumnSpacing(Value: Integer); 
begin 
if FColumnSpacing <> Value then 
    FColumnSpacing:= Value; 
    ArrangeButtons; 
end; 

function TTestRadioGroup.GetButtons(Index: Integer): TRadioButton; 
begin 
    Result := TRadioButton(FButtons[Index]); 
end; 

end. 
+1

VCL und FMX sind verschiedene Frameworks, und sie sind nicht zusammen verwendet werden, entworfen. Davon abgesehen erstellen Sie kein VCL-Projekt oder verwenden VCL-Code. Sie erstellen ein FMX-Projekt nur mit FMX-Code. In diesem Code ist keine VCL enthalten. Sie sollten das aus Ihrer Frage entfernen. –

+0

Es gibt zwei Fragen hier, Sie sollten sie trennen. Nur einmal kann die Antwort akzeptiert werden! – Dsm

+0

@DSM - OK, fertig! – JakeSays

Antwort

0

Es stellt sich heraus, dass es die Gruppierung war, die das Problem verursacht wurde:

protected 
    procedure SetName(const NewName: TComponentName); override; 


procedure TTestRadioGroup.SetName(const NewName: TComponentName); 
var rg: TRadioButton; 
begin 
    inherited; 
    for rg in FButtons do 
    rg.GroupName := Newname; 
end; 

procedure TTestRadioGroup.SetButtonCount(Value: Integer); 
var rg: TTestGroupButton; 
begin 
    while FButtons.Count < Value do begin 
    rg := TTestGroupButton.InternalCreate(Self); 
    rg.GroupName := self.Name; 
    end; 
    while FButtons.Count > Value do 
    TTestGroupButton(FButtons.Last).Free; 
end; 
0

denke ich, dass der Grund, warum Sie den Fokus verlieren, weil das Optionsfeld OnClick-Ereignis der Gruppe Button Ereignis, das wiederum ruft das Click-Ereignis Radio Gruppenrufe, die, glaube ich, geben Sie die Gruppe Knopf Fokus.