هل هناك أي طريقة للحصول على كافة عناصر التحكم في عنصر تحكم حاوية؟
سؤال
ولقد حصلت على شكل مع مجموعة من الضوابط على ذلك، وكنت أرغب في تكرار عبر كافة عناصر التحكم على لوحة معينة، وتمكين / تعطيل عليها.
وحاولت هذه:
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);
}