2013-06-21 108 views
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這些項目的任何幫助的StringList回列表框,將不勝感激。如果其中任何一個令人困惑或不夠清楚,請告訴我,我將製作演示程序併發布完整代碼。預先感謝您提供的任何幫助。

+0

您需要的唯一外部參考是列表框。在框架上聲明一個字段,並在創建框架時將其設置爲窗體的列表框,當然將UndeSelection方法移動到框架上。如果你不喜歡這樣,獲取框架的父窗體並迭代控件,直到找到一個列表框。可能還有其他的解決方案.. –

+0

我能夠使用你的建議,讓這個工作。請發帖作爲答案,我可以給你信用。非常感謝。 – CodeMonkey

+0

不客氣!我試圖找出那個評論的答案。 –

回答

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¯)的父窗體直到找到一個迭代控制列表框。或者可能會將用戶消息發佈到它瞭解的表單。也可能有其他解決方案。

+1

Sertac,非常感謝您的幫助。所有的建議都非常有用。這清除了我有很多問題。感謝您花時間與我分享您的知識。 – CodeMonkey