1

我有一个包含列表框的表单。该表单也是一个框架的父级,该框架包含一个在其上绘制面板的滚动框。当用户从列表框中选择 x 个项目并单击面板时,面板会细分为 x 个较小的面板(例如,如果用户从列表框中选择 3 个项目,然后单击框架上的单个面板,它将划分本身分成 3 个较小的面板)。

我们事先为每个面板设置了一个限制,即可以为面板选择多少项目(例如,用户将限制设置为 2,然后选择 3 个项目并尝试单击面板,显示警告说您不能这样做)当显示警告时,我想将项目返回到列表框中,以便用户可以从中选择(因为不允许完成该操作)。

我编写了这段代码来完成我想要的,问题是这些对象在事件发生时对我不可用(我尝试将父表单添加到 Implementation uses 子句并使用 fmSeatingAssignments.UndoSelection 调用它,但很快发现我需要的对象的实例超出范围)。

procedure TfmSeatAssignments.UndoSelection;
Var
 I: Integer;
begin
 for I := 0 to FVehicleLayout.SelStudents.Count - 1 do
 begin
  ListBox1.Items.Add(FVehicleLayout.SelStudents[I]);
 end;
 For I := 0 to ListBox1.Count - 1 do
 begin
  ListBox1.Selected[I] := False;
 end;
 FVehicleLayout.SelStudents.Clear;
end; 

FVehicleLayout 是框架并包含一个 Stringlist,它接收选定的项目(然后从列表框中删除)。我想在以下代码中的对话框关闭后调用上述代码,该对话框位于框架上:

procedure TFrameVehicleLayout.ClickEvent(Sender: TObject);
var
 I,Row,Side: Integer;
begin
TooManyOstrichs := False;
If SelStudents.Count > 0 then
begin
 Side := -1;
 For I:=0 to High(Bus.BusSide) do
 begin
 If Bus.BusSide[I].LookupPanel(TPanel(Sender), Row) Then
 begin
  Side := I;
  break;
 end;
end;
If Side = 0 then
begin
 If SelStudents.Count > VehicleLayout.fDSSeats then
 begin
  vsiMessageDlg('The number of selected students exceeds the amount allowed ' +
               'per row for this bus side. Please try again.',
              mtWarning, [mbok], mbok, Self.Handle);

  //Call fmSeatAssignments.UndoSelection
  exit;
 end;
end;
if side <> -1 then
begin
  TRow(Bus.BusSide[Side].Rows[Row]).Occupants.Assign(SelStudents);
  TRow(Bus.BusSide[Side].Rows[Row]).FreePanels;
  TRow(Bus.BusSide[Side].Rows[Row]).BuildPanelArray;
  ShowLayout;
  SelStudents.Clear;
 end;
end;
end;

任何有关如何将 SelStudents 字符串列表中的项目返回到列表框中的帮助将不胜感激。如果其中任何一个令人困惑或不够清楚,请告诉我,我将制作一个演示程序并发布完整代码。提前感谢您能给我的任何帮助。

4

1 回答 1

1

您需要的唯一外部参考是列表框。您可以在创建框架时在框架上声明一个字段并将其设置为表单的列表框,当然您需要UndoSelection使用此解决方案将方法移动到框架。

或者,如果您不想移动该方法,您可以在框架上声明和发布一个事件,并在创建时为其分配一个父窗体的过程。可能看起来像这样:

type
  TFrameVehicleLayout = class(TFrame)
  private
    FOnUndoSelection: TNotifyEvent;
  public
    property OnUndoSelection: TNotifyEvent read FOnUndoSelection write FOnUndoSelection;
  end;

procedure TFrameVehicleLayout.ClickEvent(Sender: TObject);
..
begin
  ..
  if Assigned(OnUndoSelection) then
    OnUndoSelection(Self);
  ..

以下列形式分配财产:

type
  TfmSeatAssignments = class(TForm)
    ..
  private
    procedure OnFrameUndoSelection(Sender: TObject);
  public
    ..


var
  F: TFrameVehicleLayout;
begin
  F := TFrameVehicleLayout.Create(Self);
  F.OnUndoSelection := OnFrameUndoSelection;
  ..


您还可以获取框架的父窗体(`GetParentForm¯)并迭代控件,直到找到一个列表框。或者可能将用户消息发布到它理解的表单。可能还有其他解决方案。

于 2013-06-21T20:49:57.467 回答