J'écris un programme constitué de panneaux créés dynamiquement qui contiennent chacun quelques composants, y compris des boutons Supprimer et Ajouter un panneau. Chaque panneau affiche 20 pixels fois le numéro de panneau sous l'autre, OnClick pour ajouter doit ajouter un autre panneau à la fin de l'ensemble et OnClick pour supprimer doit détruire son parent, puis déplacer tous les autres panneaux dans l'espace supprimé. La méthode que j'ai déjà essayée impliquait l'utilisation d'un tableau mais malheureusement j'ai eu EAccessViolation lors d'une boucle dans un tableau où j'ai supprimé un objet au milieu de celui-ci. Désolé si cela est évident ou a déjà été répondu auparavant, mais je viens de commencer à enseigner moi-même OO plus tôt cette semaine, donc je ne connais pas toutes les terminologies ou s'il y a un tableau de classe qui fera ces choses pour moi.Composant de bouton affectant le panneau parent dans Delphi
Répondre
Vous feriez peut-être mieux de le faire en utilisant soigneusement la propriété Align.
Si j'ai trois panneaux avec des alignements comme indiqué ici:
|-----------------------|
| |
| alTop |
| |
|-----------------------|
|-----------------------|
| |
| alTop |
| |
|-----------------------|
|-----------------------|
| |
| alTop |
| |
|-----------------------|
Et supprimer le second, puis le troisième sautera automatiquement sa place. Il suffit de placer les trois panneaux à l'intérieur d'un autre contrôle parent (c'est-à-dire, un autre panneau) pour définir ce que «top» signifie lorsque nous disons «alTop».
Si vous voulez animer l'effet, vous devrez être légèrement plus fantaisiste. Est-ce votre objectif? Si oui, je suis sûr que nous pouvons trouver quelque chose.
Edition - J'ai écrit un code qui peut vous donner quelques idées:
unit Main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ExtCtrls;
type
TWhere = (wAtBeginning, wAtEnd);
type
TfrmMain = class(TForm)
panCtrl: TPanel;
panHost: TPanel;
btnAddPan: TBitBtn;
btnDelPan: TBitBtn;
lbAddWhere: TListBox;
lbDelWhere: TListBox;
procedure btnAddPanClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure btnDelPanClick(Sender: TObject);
private
function GetPanel(HostPanel: TPanel; Where: TWhere): TPanel;
function BottomOfLastPanel(HostPanel: TPanel): integer;
procedure AddPanel(HostPanel: TPanel; AddWhere: TWhere);
procedure DelPanel(HostPanel: TPanel; DelWhere: TWhere);
procedure DelThisPanel(Sender: TObject);
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
procedure TfrmMain.AddPanel(HostPanel: TPanel; AddWhere: TWhere);
var
pnl: TPanel;
btn: TBitBtn;
begin
pnl := TPanel.Create(HostPanel);
with pnl do begin
case AddWhere of
wAtBeginning: Top := 0;
wAtEnd: Top := BottomOfLastPanel(HostPanel);
end;
Align := alTop;
Parent := HostPanel;
Caption := DateTimeToStr(Now);
end;
btn := TBitBtn.Create(pnl);
with btn do begin
Parent := pnl;
Left := 0;
Top := 0;
Width := 100;
Height := 30;
Align := alLeft;
Caption := 'Delete this panel';
OnClick := DelThisPanel;
end;
end;
function TfrmMain.BottomOfLastPanel(HostPanel: TPanel): integer;
begin
//scan through all panels contained inside the host panel
//return the bottom of the lowest one (highest "top" value)
Result := 0;
if Assigned(GetPanel(HostPanel,wAtEnd)) then begin
Result := GetPanel(HostPanel,wAtEnd).Top + GetPanel(HostPanel,wAtEnd).Height;
end;
end;
procedure TfrmMain.btnAddPanClick(Sender: TObject);
begin
case lbAddWhere.ItemIndex of
0: AddPanel(panHost,wAtBeginning);
1: AddPanel(panHost,wAtEnd);
end;
end;
procedure TfrmMain.btnDelPanClick(Sender: TObject);
begin
case lbDelWhere.ItemIndex of
0: DelPanel(panHost,wAtBeginning);
1: DelPanel(panHost,wAtEnd);
end;
end;
procedure TfrmMain.DelPanel(HostPanel: TPanel; DelWhere: TWhere);
var
pnlToDelete: TPanel;
begin
case DelWhere of
wAtBeginning: pnlToDelete := GetPanel(HostPanel,wAtBeginning);
wAtEnd: pnlToDelete := GetPanel(HostPanel,wAtEnd);
end;
if Assigned(pnlToDelete) then begin
FreeAndNil(pnlToDelete);
end;
end;
procedure TfrmMain.DelThisPanel(Sender: TObject);
var
parentPnl: TPanel;
begin
//delete the parent panel of this button
if Sender is TBitBtn then begin
if (Sender as TBitBtn).Parent is TPanel then begin
parentPnl := (Sender as TBitBtn).Parent as TPanel;
parentPnl.Parent := nil;
FreeAndNil(parentPnl);
end;
end;
end;
procedure TfrmMain.FormShow(Sender: TObject);
begin
lbAddWhere.ItemIndex := 1;
lbDelWhere.ItemIndex := 1;
end;
function TfrmMain.GetPanel(HostPanel: TPanel; Where: TWhere): TPanel;
var
i: integer;
begin
Result := nil;
for i := 0 to panHost.ControlCount - 1 do begin
if panHost.Controls[i] is TPanel then begin
Result := (panHost.Controls[i] as TPanel);
if Where = wAtBeginning then begin
Break;
end;
end;
end;
end;
end.
Et voici le code pour le DFM:
object frmMain: TfrmMain
Left = 0
Top = 0
Caption = 'Add/Delete Panel Demo'
ClientHeight = 520
ClientWidth = 637
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
object panCtrl: TPanel
Left = 0
Top = 0
Width = 305
Height = 520
Align = alLeft
TabOrder = 0
object btnAddPan: TBitBtn
Left = 8
Top = 8
Width = 125
Height = 75
Caption = 'Add panel'
TabOrder = 0
OnClick = btnAddPanClick
end
object btnDelPan: TBitBtn
Left = 8
Top = 89
Width = 125
Height = 75
Caption = 'Remove panel'
TabOrder = 1
OnClick = btnDelPanClick
end
object lbAddWhere: TListBox
Left = 139
Top = 8
Width = 150
Height = 75
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Tahoma'
Font.Style = []
ItemHeight = 16
Items.Strings = (
'Add to the top'
'Add to the bottom')
ParentFont = False
TabOrder = 2
end
object lbDelWhere: TListBox
Left = 139
Top = 89
Width = 150
Height = 75
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Tahoma'
Font.Style = []
ItemHeight = 16
Items.Strings = (
'Delete from the top'
'Delete from the bottom')
ParentFont = False
TabOrder = 3
end
end
object panHost: TPanel
Left = 305
Top = 0
Width = 332
Height = 520
Align = alClient
TabOrder = 1
ExplicitLeft = 392
ExplicitTop = 264
ExplicitWidth = 185
ExplicitHeight = 41
end
end
Vous pouvez utiliser votre stratégie de tableau si vous utilisez un tableau dynamique et supprimez réellement les éléments lorsque vous supprimez des panneaux. Alternativement, vous pouvez toujours vérifier si l'élément est assigné avec si assigné (tableau [I]). Cependant, il serait préférable de remplacer votre solution de tableau par une solution utilisant TComponentList, ce qui facilitera l'ajout et la suppression de panneaux dans la liste et est conçu pour ce type de situation.
- 1. Déterminer le composant parent
- 2. Le meilleur composant de reporting pour Delphi?
- 3. Empêchez le composant COM Delphi d'afficher MessageBox()
- 4. Quel composant Delphi contient le plus d'événements?
- 5. Composant Delphi non peint
- 6. Comment modifier le DataContext d'un bouton au parent DataContext parent?
- 7. Column.DbType affectant le comportement d'exécution
- 8. Le panneau de mise à jour des enfants appelle le prerender sur le panneau de mise à jour parent dans le scénario imbriqué
- 9. Composant de dialogue de connexion ODBC Delphi?
- 10. JavaScript onKeyPress affectant le problème
- 11. Exécuter l'action pour le bouton non coché automatiquement dans Delphi
- 12. Trouver le bouton du formulaire Parent de l'image en javascript
- 13. Changer les images en cliquant sur le composant TImage - Delphi
- 14. icônes dynamiques avec le composant d'arbre virtuel pour delphi
- 15. quel est le meilleur composant ftp gratuit pour delphi
- 16. Suppression d'un espace affectant le rang?
- 17. apache mod_rewrite affectant les fichiers dans le sous-dossier
- 18. Problème de rafraîchissement de composant personnalisé avec Delphi
- 19. bouton Tkinter lier et parent deatroy
- 20. Utilisation d'un composant ASP RadioButton pour déclencher la fonctionnalité de panneau de diapositives JQuery
- 21. Panneau de contrôle sur le contenu dans le formulaire
- 22. Direct 3D affectant le type de données double
- 23. Un composant Delphi pour les documents de signature numérique?
- 24. Rotation affectant la barre de navigation imprévisiblement
- 25. Comment faire un bouton en profondeur dans un panneau Swing imbriqué obtenir le "focus du clavier"?
- 26. Composant NHibernate avec une relation un-à-plusieurs du parent
- 27. Clonage d'un composant TStringGrid
- 28. Comment mettre en page un composant dans un panneau de défilement vertical uniquement?
- 29. Obtention d'événements dans un bouton dans un panneau utilisé comme cellule de table
- 30. Étiquette multiligne dans le composant RadioButton (AS3)
Cela ressemble à une solution que je vais devoir expérimenter. Un rapide google pour "Align Delphi" m'a renvoyé à ce fil: http://stackoverflow.com/questions/1259849/delphi-how-to-programmatically-adjust-ordinary-ordering-of-components-with-align Il me faudra un moment pour les parcourir et les comprendre aussi. Merci. – BookOfGreg
FYI, votre exemple donne également une erreur EAccessViolation lorsque vous supprimez un objet. Y a-t-il une sorte d'erreur quelque part? Je ne peux pas en trouver un ... – BookOfGreg
Hmm Je ne reçois aucune violation d'accès quand j'ajoute ou supprime ... indépendamment de l'ordre dans lequel je le fais. Pouvez-vous me donner les étapes exactes pour reproduire l'erreur? Est-ce à chaque fois que vous supprimez un panneau, ou seulement le dernier, le premier, ou quoi? Merci... – JosephStyons