هل هناك أي طريقة للحصول على كافة عناصر التحكم في عنصر تحكم حاوية؟

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

سؤال

ولقد حصلت على شكل مع مجموعة من الضوابط على ذلك، وكنت أرغب في تكرار عبر كافة عناصر التحكم على لوحة معينة، وتمكين / تعطيل عليها.

وحاولت هذه:

var component: TComponent;
begin
  for component in myPanel do
    (component as TControl).Enabled := Value;
end;

ولكن هذا لم يفعل شيئا. تبين جميع المكونات في جمع مكونات النموذج، وليس وجوه آبائهم. لذلك لا أحد يعرف إذا كان هناك أي طريقة للحصول على جميع الضوابط داخل السيطرة؟ (وبالاضافة الى الحل القبيح من هذا القبيل، وهو ما انتهى بي الأمر إلى القيام به):

var component: TComponent;
begin
  for component in myPanel do
    if (component is TControl) and (TControl(component).parent = myPanel) then
      TControl(component).Enabled := Value;
end;

وشخص من فضلك قل لي هناك طريقة أفضل ...

هل كانت مفيدة؟

المحلول

أنت تبحث عن مجموعة TWinControl.Controls والخاصية ControlCount المرفقة. هذه هي لأطفال الفوري عنصر التحكم. للحصول على أحفاد الخ، واستخدام تقنيات العودية القياسية.

وأنت لا تريد حقا مجموعة Components (وهو ما يتكرر حلقة for-in فوق) لأنه له علاقة، بشكل عام، مع العلاقة بين الوالدين والطفل شيئا. مكونات يمكن أن تمتلك الأشياء التي ليس لها علاقة الطفل، ويمكن التحكم يكون الأطفال الذين لا يملكونها.

لاحظ أيضا أن تعطيل عنصر تحكم تعطيل ضمنيا جميع أبنائها، أيضا. لا يمكنك التفاعل مع الأطفال من التحكم معطل. نظام التشغيل لا يرسل رسائل إدخال لهم. لجعلها <م> نظرة المعوقين، على الرغم من أنك سوف تحتاج إلى تعطيل كل منها على حدة. وهذا هو، لجعل زر ورمادي النص، فإنه لا يكفي لتعطيل الأم، على الرغم من أن زر سوف لن تستجيب لنقرات الماوس. تحتاج إلى تعطيل الزر نفسه لجعلها ترسم نفسها "disabledly."

نصائح أخرى

إذا قمت بتعطيل لوحة، آل تسيطر عليه معاقا جدا.

وحل تكراري مع أساليب مجهول:

type
  TControlProc = reference to procedure (const AControl: TControl);

procedure TForm6.ModifyControl(const AControl: TControl; 
  const ARef: TControlProc);
var
  i : Integer;
begin
  if AControl=nil then
    Exit;
  if AControl is TWinControl then begin
    for i := 0 to TWinControl(AControl).ControlCount-1 do
      ModifyControl(TWinControl(AControl).Controls[i], ARef);
  end;
   ARef(AControl);
end;

procedure TForm6.Button1Click(Sender: TObject);
begin
  ModifyControl(Panel1,
    procedure (const AControl: TControl)
    begin
      AControl.Enabled := not Panel1.Enabled;
    end
  );
end;

وهنا هو وسيلة دلفي 2007:

procedure TForm6.ModifyControl(const AControl: TControl; const value: Boolean);
var
  i: Integer;
begin
  if AControl=nil then Exit;
  if AControl is TWinControl then begin
    for i := 0 to TWinControl(AControl).ControlCount-1 do
      ModifyControl(TWinControl(AControl).Controls[i], value);
  end;
  Acontrol.Enabled := value;
end;

procedure TForm6.Button1Click(Sender: TObject); 
begin 
  ModifyControl(Panel1, true);  // true or false
end;

وببساطة

Panel.Enabled := Value;

وأنا أعرف هذا المنصب قديمة بعض الشيء ولكن جئت هنا بناء على البحث عن المعلومات نفسها. وفيما يلي بعض التعليمات البرمجية C ++ التي عملت بها لأي شخص مهتم.

// DEV-NOTE:  GUIForm flattens the VCL controls
// VCL controls are nested.  I.E. Controls on a
// Panel would have the Panel as a parent and if
// that Panel is on a TForm, TForm's control count
// does not account for the nested controls on the
// Panel.
//
// GUIControl is passed a Form pointer and an index
// value, the index value will walk the controls on the
// form and any child controls counting up to the idx
// value passed in.  In this way, every control has a
// unique index value
//
// You can use this to iterate over every single control
// on a form.  Here is example code:
//
// int count = 0;
// TForm *pTForm = some_form
// TControl *pCtrl = 0;
// do
// {
//      pCtrl = GUIControl(pTForm, count++);
//
// }while(pCtrl);

TControl *GUIControl(TForm *F, int idx)
{
    TControl *rval = 0;
    int RunCount = 0;

    for(int i=0; i<F->ControlCount && !rval; i++)
    {
        TControl *pCtl = F->Controls[i];

        if(RunCount == idx )
            rval = pCtl;
        else
            rval = GUIChildControl( pCtl, RunCount, idx);

        RunCount++;
    }

    return(rval);
}

TControl *GUIChildControl(TControl *C, int &runcount, int idx)
{
    TControl *rval = 0;
    TWinControl *pC = dynamic_cast<TWinControl *>(C);
    if(pC)
    {
        for(int i=0; i<pC->ControlCount && !rval; i++)
        {
            TControl *pCtrl = pC->Controls[i];
            runcount++;

            if( runcount == idx)
                rval = pCtrl;
            else
            {
                TWinControl *pCC = dynamic_cast<TWinControl *>(pCtrl);

                if(pCC)
                {
                    if( pCC->ControlCount )
                        rval = GUIChildControl(pCtrl, runcount, idx);
                }
            }
        }
    }

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