مكون الزر الذي يؤثر على اللوحة الأم في دلفي

StackOverflow https://stackoverflow.com/questions/1600625

  •  05-07-2019
  •  | 
  •  

سؤال

أنا أكتب برنامجًا يتكون من لوحات تم إنشاؤها ديناميكيًا تحتوي كل منها على بعض المكونات، بما في ذلك أزرار لوحة الحذف والإضافة.تعرض كل لوحة 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 التي سوف تجعل من الأسهل لإضافة وحذف الألواح إلى قائمة ويهدف فقط لهذا النوع من الحالات.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top