Question

J'ai un composant personnalisé de type TSpeedButton qui a deux propriétés supplémentaires définies:

CommentHeading: string;
CommentText: string;

Je CommentHeading ensemble au moment de la conception.

Lorsque le bouton de vitesse est pressé une note de service est représenté avec un bouton au-dessous pour enregistrer son contenu. La procédure qui gère ceci:

procedure CustomSpeedButton1Click(Sender: TObject);
begin
   Receiver := CustomSpeedButton1.Name; // possibly used to save the memo text back to this speedbuttons property after comments are submitted
   ViewComments(CustomSpeedButton1.CommentTitle,CustomSpeedButton1.CommentText);
end;

Et la procédure de ViewComments lui-même:

procedure ViewComments(comment_caption:string; comment_text:string);
begin
  label15.Hide; // label showing editing in progress, hidden until user begins typing
  Button1.Enabled     := false; // the button for saving the memo text, hidden until user begins typing
  CommentsBox.Visible := true; // pop up the comment box at the bottom of the form
  CommentsBox.Caption := 'Comments: ' + comment_caption;
  CommentsMemo.Text   := comment_text; // if there are existing comments assign them to memo
end;

Le contenu du mémo doivent être affectées à la propriété CommentText du SpeedButton personnalisé.

Ce que je pensais au départ était que je pouvais passer le nom du composant à une variable lorsque la coutume SpeedButton obtient pressé puis récupérer ce nom lorsque le bouton d'enregistrement sur le mémo est pressé et l'utiliser pour attribuer le texte du mémo aux speedbuttons propriété CommentText. Mais je compris que pour ce faire, je dois utiliser une sorte de déclaration de case..of qui vérifiait pour chaque nom possible de speedbutton puis attribuez-lui la valeur mémo à ses propriétés et cela semble juste ridiculement ennuyeux.

Y at-il un moyen plus facile d'attribuer le texte du mémo à l'speedbutton qui a ouvert la note de service pour commencer?

Était-ce utile?

La solution

En fin de compte, vous vous demandez comment dire la fonction ViewComments qui propriétés du bouton, il travaille avec.

Comprenez-vous ce que le paramètre Sender fait en cas de OnClick? Il dit la gestionnaire d'événements qui l'événement de l'objet est en cours de traitement. Il est au service précisément le rôle que vous êtes à la recherche d'apporter à la fonction ViewComments.

C'est ce que Mason voulait en venir dans sa réponse. Plutôt que de passer toutes les valeurs de propriété, passer l'objet lui-même :

procedure ViewComments(CommentButton: TCustomSpeedButton);

appelez ensuite de tous les gestionnaires d'événements de vos boutons:

procedure TForm1.CustomSpeedButton1Click(Sender: TObject);
begin
  ViewComments(CustomSpeedButton1);
end;

procedure TForm1.CustomSpeedButton2Click(Sender: TObject);
begin
  ViewComments(CustomSpeedButton2);
end;

Pas de chaînes, aucune déclaration de case, pas lookups.

Cela devrait répondre à votre question, mais vous pouvez le faire encore mieux. Rappelez-vous ce que je dit sur le paramètre Sender? Quand quelqu'un clique sur le premier bouton, le paramètre Sender de ce gestionnaire de OnClick sera le bouton, afin que nous puissions réécrire le premier gestionnaire d'événements comme celui-ci:

procedure TForm1.CustomSpeedButton1Click(Sender: TObject);
begin
  ViewComments(Sender as TCustomSpeedButton);
end;

Et vous pouvez réécrire le deuxième gestionnaire d'événements comme celui-ci:

procedure TForm1.CustomSpeedButton2Click(Sender: TObject);
begin
  ViewComments(Sender as TCustomSpeedButton);
end;

Hmm. Ils sont les mêmes. Avoir deux fonctions identiques est inutile, donc se débarrasser d'un et l'autre renomme il ne semble pas spécifique bouton:

procedure TForm1.CommentButtonClick(Sender: TObject);
begin
  ViewComments(Sender as TCustomSpeedButton);
end;

Définissez ensuite les propriétés OnClick de à la fois pour faire référence à celui d'un gestionnaire d'événements. Vous ne pouvez pas le faire simplement en double-cliquant sur la propriété dans l'inspecteur d'objets. Vous aurez besoin de taper le nom vous, choisissez dans la liste déroulante, ou céder la propriété d'événement au moment de l'exécution:

CustomSpeedButton1.OnClick := CommentButtonClick;
CustomSpeedButton2.OnClick := CommentButtonClick;

Je voudrais aussi vous encourager à utiliser des noms plus significatifs pour vos commandes. Ce Label15 est particulièrement flagrants. Comment pouvez-vous rappeler que le quinzième étiquette est celle qui indique que le montage est en cours? Appelez-EditInProgressLabel, par exemple.

Autres conseils

Puisque vous êtes déjà passer des variables supplémentaires autour, pourquoi ne pas passer juste le SpeedButton lui-même? Ensuite, vous aurez pas besoin de regarder la référence.

Un petit changement à votre code devrait faire l'affaire:

procedure TForm1.CustomSpeedButton1Click(Sender: TObject);
var
  btn: TCustomSpeedButton;
begin
   btn := Sender as TCustomSpeedButton;
   Receiver := btn.Name; 
   ViewComments(btn.CommentTitle, btn.CommentText);
end;

et après la modification du commentaire:

procedure TForm1.StoreComments(comment: string);
var
  btn: TCustomSpeedButton;
begin
  btn := FindComponent(Receiver) as TCustomSpeedButton;
  btn.CommentText := comment;
end;

Vous pouvez également mémoriser le bouton lui-même au lieu de simplement son nom.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top