مكون الزر الذي يؤثر على اللوحة الأم في دلفي
سؤال
أنا أكتب برنامجًا يتكون من لوحات تم إنشاؤها ديناميكيًا تحتوي كل منها على بعض المكونات، بما في ذلك أزرار لوحة الحذف والإضافة.تعرض كل لوحة 20 بكسل ضعف رقم اللوحة الموجودة أسفل بعضها البعض، ويجب على OnClick للإضافة إضافة لوحة أخرى إلى نهاية المجموعة، ويجب على OnClick للحذف تدمير اللوحة الأم ثم نقل جميع اللوحات الأخرى لأعلى إلى المساحة التي يحذفها.الطريقة التي جربتها بالفعل تتضمن استخدام مصفوفة ولكن لسوء الحظ حصلت على EAccessViolation عند المرور عبر مصفوفة حيث قمت بحذف كائن في منتصفها.
آسف إذا كان هذا واضحًا أو تمت الإجابة عليه من قبل ولكني بدأت للتو في تعليم نفسي OO في وقت سابق من هذا الأسبوع لذلك لا أعرف كل المصطلحات أو إذا كان هناك فصل دراسي مثل مصفوفة ستفعل هذه الأشياء من أجلي.
المحلول
قد يكون من الأفضل لك القيام بذلك من خلال الاستخدام الدقيق لخاصية Align.
إذا كان لدي ثلاث لوحات بمحاذاة كما هو موضح هنا:
|-----------------------|
| |
| alTop |
| |
|-----------------------|
|-----------------------|
| |
| alTop |
| |
|-----------------------|
|-----------------------|
| |
| alTop |
| |
|-----------------------|
وأنا أحذف الثانية، ثم الثالثة سوف تظهر تلقائيا في مكانها.
ما عليك سوى وضع اللوحات الثلاث داخل وحدة تحكم أبوية أخرى (أي لوحة أخرى) لتحديد معنى كلمة "top" عندما نقول "alTop".
إذا كنت تريد تحريك التأثير، فيجب أن تكون أكثر روعة قليلاً.هل هذا هو هدفك؟إذا كان الأمر كذلك، فأنا متأكد من أننا يمكن أن نتوصل إلى شيء ما.
تحرير - كتبت بعض التعليمات البرمجية التي قد تعطيك بعض الأفكار:
unit Main;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, Buttons, ExtCtrls;
type
TWhere = (wAtBeginning, wAtEnd);
type
TfrmMain = class(TForm)
panCtrl: TPanel;
panHost: TPanel;
btnAddPan: TBitBtn;
btnDelPan: TBitBtn;
lbAddWhere: TListBox;
lbDelWhere: TListBox;
procedure btnAddPanClick(Sender: TObject);
procedure FormShow(Sender: TObject);
procedure btnDelPanClick(Sender: TObject);
private
function GetPanel(HostPanel: TPanel; Where: TWhere): TPanel;
function BottomOfLastPanel(HostPanel: TPanel): integer;
procedure AddPanel(HostPanel: TPanel; AddWhere: TWhere);
procedure DelPanel(HostPanel: TPanel; DelWhere: TWhere);
procedure DelThisPanel(Sender: TObject);
end;
var
frmMain: TfrmMain;
implementation
{$R *.dfm}
procedure TfrmMain.AddPanel(HostPanel: TPanel; AddWhere: TWhere);
var
pnl: TPanel;
btn: TBitBtn;
begin
pnl := TPanel.Create(HostPanel);
with pnl do begin
case AddWhere of
wAtBeginning: Top := 0;
wAtEnd: Top := BottomOfLastPanel(HostPanel);
end;
Align := alTop;
Parent := HostPanel;
Caption := DateTimeToStr(Now);
end;
btn := TBitBtn.Create(pnl);
with btn do begin
Parent := pnl;
Left := 0;
Top := 0;
Width := 100;
Height := 30;
Align := alLeft;
Caption := 'Delete this panel';
OnClick := DelThisPanel;
end;
end;
function TfrmMain.BottomOfLastPanel(HostPanel: TPanel): integer;
begin
//scan through all panels contained inside the host panel
//return the bottom of the lowest one (highest "top" value)
Result := 0;
if Assigned(GetPanel(HostPanel,wAtEnd)) then begin
Result := GetPanel(HostPanel,wAtEnd).Top + GetPanel(HostPanel,wAtEnd).Height;
end;
end;
procedure TfrmMain.btnAddPanClick(Sender: TObject);
begin
case lbAddWhere.ItemIndex of
0: AddPanel(panHost,wAtBeginning);
1: AddPanel(panHost,wAtEnd);
end;
end;
procedure TfrmMain.btnDelPanClick(Sender: TObject);
begin
case lbDelWhere.ItemIndex of
0: DelPanel(panHost,wAtBeginning);
1: DelPanel(panHost,wAtEnd);
end;
end;
procedure TfrmMain.DelPanel(HostPanel: TPanel; DelWhere: TWhere);
var
pnlToDelete: TPanel;
begin
case DelWhere of
wAtBeginning: pnlToDelete := GetPanel(HostPanel,wAtBeginning);
wAtEnd: pnlToDelete := GetPanel(HostPanel,wAtEnd);
end;
if Assigned(pnlToDelete) then begin
FreeAndNil(pnlToDelete);
end;
end;
procedure TfrmMain.DelThisPanel(Sender: TObject);
var
parentPnl: TPanel;
begin
//delete the parent panel of this button
if Sender is TBitBtn then begin
if (Sender as TBitBtn).Parent is TPanel then begin
parentPnl := (Sender as TBitBtn).Parent as TPanel;
parentPnl.Parent := nil;
FreeAndNil(parentPnl);
end;
end;
end;
procedure TfrmMain.FormShow(Sender: TObject);
begin
lbAddWhere.ItemIndex := 1;
lbDelWhere.ItemIndex := 1;
end;
function TfrmMain.GetPanel(HostPanel: TPanel; Where: TWhere): TPanel;
var
i: integer;
begin
Result := nil;
for i := 0 to panHost.ControlCount - 1 do begin
if panHost.Controls[i] is TPanel then begin
Result := (panHost.Controls[i] as TPanel);
if Where = wAtBeginning then begin
Break;
end;
end;
end;
end;
end.
وهنا هو رمز سوق دبي المالي:
object frmMain: TfrmMain
Left = 0
Top = 0
Caption = 'Add / Delete Panel Demo'
ClientHeight = 520
ClientWidth = 637
Color = clBtnFace
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -11
Font.Name = 'Tahoma'
Font.Style = []
OldCreateOrder = False
OnShow = FormShow
PixelsPerInch = 96
TextHeight = 13
object panCtrl: TPanel
Left = 0
Top = 0
Width = 305
Height = 520
Align = alLeft
TabOrder = 0
object btnAddPan: TBitBtn
Left = 8
Top = 8
Width = 125
Height = 75
Caption = 'Add panel'
TabOrder = 0
OnClick = btnAddPanClick
end
object btnDelPan: TBitBtn
Left = 8
Top = 89
Width = 125
Height = 75
Caption = 'Remove panel'
TabOrder = 1
OnClick = btnDelPanClick
end
object lbAddWhere: TListBox
Left = 139
Top = 8
Width = 150
Height = 75
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Tahoma'
Font.Style = []
ItemHeight = 16
Items.Strings = (
'Add to the top'
'Add to the bottom')
ParentFont = False
TabOrder = 2
end
object lbDelWhere: TListBox
Left = 139
Top = 89
Width = 150
Height = 75
Font.Charset = DEFAULT_CHARSET
Font.Color = clWindowText
Font.Height = -13
Font.Name = 'Tahoma'
Font.Style = []
ItemHeight = 16
Items.Strings = (
'Delete from the top'
'Delete from the bottom')
ParentFont = False
TabOrder = 3
end
end
object panHost: TPanel
Left = 305
Top = 0
Width = 332
Height = 520
Align = alClient
TabOrder = 1
ExplicitLeft = 392
ExplicitTop = 264
ExplicitWidth = 185
ExplicitHeight = 41
end
end
نصائح أخرى
ويمكنك استخدام استراتيجية مجموعة الخاص بك إذا كنت تستخدم صفيف حيوية وفعلا حذف العناصر كما كنت إزالة لوحات. بدلا من ذلك، يمكنك دائما التحقق لمعرفة ما إذا تم تعيين عنصر مع إذا المخصصة (صفيف [I]).
ولكن، هل سيكون أفضل حالا استبدال حل مجموعة الخاص بك مع الحل باستخدام TComponentList التي سوف تجعل من الأسهل لإضافة وحذف الألواح إلى قائمة ويهدف فقط لهذا النوع من الحالات.