如何使用单独的Label.Caption更新来安装某些Control.OnMouseEnter事件

时间:2012-10-19 07:03:58

标签: delphi delphi-xe2

我有12个形状

Shape1
Shape2
.....
Shape12

我有12个标签

Label13
Label14
......
Label24

我想知道是否有办法编写这样的函数,鼠标在形状上输入会将相应的标签分配给不同的标签,例如Label25:

Label25 :=  
OnMouseEnter
shape1 -> label13
shape2 -> label14
...
shape12 -> label24

因此,如果鼠标输入Shape1,Label25将等于Label13,如果鼠标输入Shape2,Label25将等于Label14并继续,直到鼠标输入Shape12 Label25将等于Label24。

我知道我可以写

label25 := labelxx 

在每个鼠标输入事件上。但是认为标签和形状的名称相对应可以有一种更简单的方法,其中标签#比形状#outtime多12个。

添加建议后,我添加了

procedure TFZone1Mod7.ChangeText(sender: TObject);
var
  ShapeOrderNo: integer;
  FoundComponent: TComponent;
begin
  if TryStrToInt(copy(TShape(Sender).Name,6,MaxInt),ShapeOrderNo) then
    begin
      FoundComponent := FindComponent('label'+inttostr(ShapeOrderNo+12));
      if (FoundComponent is TLabel) then
            Label25.Caption := TLabel(FoundComponent).Caption
      else
          showmessage('not found');
    end;
  showmessage('failed try');

end;

procedure TFZone1Mod7.Shape1MouseEnter(Sender: TObject);
begin
    changetext(self);
end;

end.

但每次跑步我都会失败尝试。 我发错的信息了吗?

4 个答案:

答案 0 :(得分:6)

我不喜欢这种设计,但是,您可以对所有形状使用公共事件处理程序,并使用FindComponent函数在那里按名称查找组件。然后你可能会写这样的东西(请注意它是未经测试的,仅在浏览器中编写):

var
  ShapeOrderNo: Integer;
  FoundComponent: TComponent;
begin
  // first try to convert a text behind "Shape", what should be a shape's order 
  // and if it's convertable to integer, then...
  if TryStrToInt(Copy(TShape(Sender).Name, 6, MaxInt), ShapeOrderNo) then
  begin
    // try to find a component with the name "label" + found shape order number
    // incremented by 12
    FoundComponent := FindComponent('label' + IntToStr(ShapeOrderNo + 12));
    // if the component is found, or to be more specific, if it's TLabel, then...
    if (FoundComponent is TLabel) then
      TLabel(FoundComponent).Caption := 'Hello from ' + TShape(Sender).Name;
  end;
end;

答案 1 :(得分:2)

在您的TShape上添加一个属性。

 TMyShape= class(TShape)
 private
   FLinkLabel: TLabel;
 procedure SetLinkLabel(const Value: TLabel);
 published
   property LinkLabel: TLabel read FLinkLabel write SetLinkLabel;
 end;

 procedure TMyShape.SetLinkLabel(const Value: TLabel);
 begin
   FLinkLabel := Value;
 end;

 procedure TForm1.FormCreate(Sender: TObject);
 var
   oMyShape: TMyShape;
 begin
   oMyShape:= TMyShape.Create(self);
   oMyShape.Parent:= Self;
   oMyShape.LinkLabel:= self.Label1;
   oMyShape.OnMouseEnter:= OnShapeMouseEnter;
 end;

 procedure TForm1.OnShapeMouseEnter(Sender: TObject);
 begin
   if (sender is TMyShape) and
      ( TMyShape(Sender).LinkLabel <>Nil) then
   begin
     TMyShape(Sender).LinkLabel.Caption:= 'Hello';
   end;
 end;

我只是在表单上设置了标签,并将标签与TMyShape链接。

答案 2 :(得分:2)

如果您不在Forms Designer中进行控件管理并在运行时创建它们,我会这样做:

声明标签数组和形状数组:

const
  ShapesCount = 20;

type
  TForm1 = class(TForm)
    fLabels: array [0..ShapesCount-1] of TLabel;
    fShapes: array [0..ShapesCount-1] of TShape;

在运行时为每个形状分配Tag及其索引。

procedure TForm1.OnFormCreate;
begin
  for I := 0 to ShapesCount - 1 do  
  begin
    fShapes[I] := TShape.Create(..);
    fLabels[I] := TLabel.Create(..);
    fShapes[I].Tag := I;
    fShapes[I].OnMouseEnter := OnShapeMouseEnter;
  end;
end;

然后你可以像这样使用它:

procedure TForm1.OnShapeMouseEnter(Sender: TObject);
begin
  Assert(Sender is TShape);
  Label25.Caption := fLabels[TShape(Sender).Tag].Caption;
end;

编辑:再看一下,你可能已经有了一个Lable.Captions数组,所以你可以直接从那里获取Label25.Caption。

答案 3 :(得分:2)

如果您不想重新编写标签的创建,请使用findcomponent:

所有形状的相同处理程序

procedure TForm1.Shape1MouseEnter(Sender: TObject);
var
  ActiveShape: TShape;
  StrName: string;
  ActiveLabel: TComponent;
begin
  if Sender is TShape then
  begin
    ActiveShape := TShape(Sender);
// Only works if Shapes are named Shape1..12 and the labels Label1..12 !!
    StrName := 'Label' + copy(ActiveShape.name, 6, length(ActiveShape.name)); 
    ActiveLabel := FindComponent(StrName);
    if ActiveLabel is TLabel then
      Label25.Caption := TLabel(ActiveLabel).Caption;
  end;
end;

如果有点混乱,这将做你需要的事情:)

[编辑] 在我看来,有一种简单的方法来改善这一点并满足您对具有不同“name_number”的标签的需求:

在设计器中将每个TShape的Tag属性设置为您想要与之关联的标签号。所以将shape的标签设置为13(以保持问题)然后

procedure TForm1.Shape1MouseEnter(Sender: TObject);
var
  ActiveShape: TShape;
  StrName: string;
  ActiveLabel: TComponent;
begin
  if Sender is TShape then
  begin
    ActiveShape := TShape(Sender);
    StrName := 'Label' + IntToStr(ActiveShape.Tag); // find tag numbered label
    ActiveLabel := FindComponent(StrName);
    if ActiveLabel is TLabel then
      Label25.Caption := TLabel(ActiveLabel).Caption;
  end;
end;