Delphi 在框架上发生事件时触发事件以在窗体上激发

Delphi 在框架上发生事件时触发事件以在窗体上激发,delphi,Delphi,我有一个包含列表框的表单。该表单也是一个框架的父级,该框架包含一个用于绘制面板的滚动框。当用户从列表框中选择x个项目并单击一个面板时,面板会细分为x个较小的面板(例如,如果用户从列表框中选择3个项目,然后单击框架上的单个面板,则会将其自身划分为3个较小的面板) 我们事先为每个面板设置了一个限制,限制可以为面板选择多少项(例如,用户将限制设置为2项,然后选择3项,并尝试单击一个面板,显示一条警告,说明您不能这样做),当警告显示时,我想将项目返回列表框,以便用户可以从中进行选择(操作无法完成,因为它

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

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

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

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;
过程TFrameVehicleLayout.ClickEvent(发送者:ToObject);
变量
一、 行、边:整数;
开始
TooManyOstrichs:=假;
如果Self.Count>0,则
开始
边:=-1;
对于I:=0至高(母线侧)do
开始
如果Bus.BusSide[I].LookupPanel(TPanel(发送方),世界其他地区),则
开始
边:=I;
打破
结束;
结束;
如果Side=0,则
开始
如果SelStudents.Count>VehicleLayout.fdssets,则
开始
vsiMessageDlg('所选学生的数量超过了允许的数量'+
“此公共汽车侧的每行。请重试。”,
mtWarning,[mbok],mbok,Self.Handle);
//调用fmSeatAssignments.UndoSelection
出口
结束;
结束;
如果边-1那么
开始
TRow(总线。总线侧[侧]。行[行])。占用者。分配(学生);
TRow(总线。总线侧[Side]。行[Row])。自由面板;
TRow(Bus.BusSide[Side].Rows[Row]).BuildPanelArray;
展示布局;
学生们,清楚;
结束;
结束;
结束;

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

您需要的唯一外部参考是列表框。您可以创建框架时,在框架上创建一个字段并将其设置为表单的列表框,当然需要使用此解决方案将
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')并迭代控件,直到找到列表框。或者可能会将用户消息发布到它理解的表单。可能还有其他解决方案。

您需要的唯一外部引用是列表框。您可以在框架上声明一个字段,并在创建框架时将其设置为表单的列表框,当然您需要移动
撤消选择使用此解决方案对框架进行剖切
方法

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

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')和迭代控件,直到找到列表框。或者可能会将用户消息发布到它能理解的表单中。可能还有其他解决方案。

您需要的唯一外部引用是listbox。在框架上声明一个字段,并在创建框架时将其设置为表单的listbox,当然,将UndeSelection方法移动到框架中。I如果您不喜欢,请获取框架的父窗体并迭代控件,直到找到一个列表框。可能还有其他解决方案。我可以使用您的建议来实现这一点。请将其作为答案发布,以便我可以给予您信任。非常感谢。不客气!我尝试对该评论给出答案。唯一的外部参考你需要的是列表框。在框架上声明一个字段,并在创建框架时将其设置为表单的列表框,当然要将取消选择方法移到框架上。如果你不喜欢,请获取框架的父表单并迭代控件,直到找到列表框。可能还有其他解决方案。我可以使用你的建议来解决问题谢谢你,不客气!我试着回答你的评论。塞塔克,非常感谢你的帮助。你所有的建议都非常有用。这澄清了我的许多问题。我感谢你抽出时间与我分享你的知识。塞塔克爵士交咨会,非常感谢你的帮助。你所有的建议都非常有用。这澄清了我的许多问题。我感谢你抽出时间与我分享你的知识。