PDA

View Full Version : سوال: دستیابی به خصوصیات یک کامپوننت با استفاده از رشته نام آن کامپوننت



u.2u.4u
سه شنبه 25 آبان 1389, 09:33 صبح
باسلام خدمت همه دوستان و اساتید.
فرض کنید یک کومبوباکس دارم به نام 'sharh1' و این نام را به عنوان یک رشته در کد در اختیار دارم. می خواهم به خصوصیات کومبوباکسی که این نام را دارد دست پیدا کنم مثلا اون را غیرفعال کنم. در ضمن نمی خواهم از روش بررسی تمام کامپوننت ها در یک حلقه که کدنویسی بیشتر نیاز داره و هم زمان زیاد می بره مانند تاپیک زیر استفاده کنم:
http://barnamenevis.org/forum/showthread.php?t=89427&highlight=ComponentCount
پیشنهاد شما چیه؟ برای مثال می خواهم این کومبوباکس را disable کنم.
با تشکر

devil00x
سه شنبه 25 آبان 1389, 10:19 صبح
var
strComponent :String;
strClass :String;
NewRef :TComboBox;
begin

strComponent := 'ComboBox1';
strClass := 'TComboBox';

NewRef := FindComponent(strComponent) as FindClass(strClass);

NewRef.Visible := False;



امیدوارم بدرت بخوره و مشکلت رو حل کنه!!!

u.2u.4u
سه شنبه 25 آبان 1389, 10:32 صبح
دستتون درد نکنه. اما این خط:


NewRef := FindComponent(strComponent) as FindClass(strClass);

این ارور را می ده


[DCC Error] Unit2.pas(59): E2010 Incompatible types: 'TComboBox' and 'TPersistent'

u.2u.4u
سه شنبه 25 آبان 1389, 11:33 صبح
با این کد مشکل حل شد:

NewRef := FindComponent(strComponent) as TComboBox;

حالا واقعا نمی دونم توی اون قسمتی که تغییر کرد چه مشکلی وجود داشت. باز هم تشکر می کنم.

Felony
سه شنبه 25 آبان 1389, 11:50 صبح
با این کد مشکل حل شد:

NewRef := FindComponent(strComponent) as TComboBox;

حالا واقعا نمی دونم توی اون قسمتی که تغییر کرد چه مشکلی وجود داشت. باز هم تشکر می کنم.
مقدار برگشتی تابع FindClass از نوع TPersistent هست و برای همین نمیشه به TComboBox اون رو TypeCast کرد .

در ضمن بهتره به جای استفاده از as - Cast از یک Hard - Cast امن استفاده کنید :


var
strComponent :String;
NewRef :TComboBox;
begin
strComponent := 'ComboBox1';
if FindComponent(strComponent) is TComboBox then
NewRef := TComboBox(FindComponent(strComponent));
end;

vcldeveloper
سه شنبه 25 آبان 1389, 22:03 عصر
در ضمن بهتره به جای استفاده از as - Cast از یک Hard - Cast امن استفاده کنید
در همچین سناریویی، همچین توصیه ایی نمیشه. کد شما از کد اولیه کارایی پایین تری داره، چون دارید دو بار با استفاده از FindComponent به دنبال کلاس مربوطه در بین کلاس های ریجستر شده می گردید، و یک بار هم برای مطابقت نوع کلاس، سلسله مراتب کلاس ها رو پیمایش می کنید.

در کد اولیه یک بار جستجو در بین کلاس های رجیستر شده انجام میشد، و یک بار هم پیمایش سلسله مراتب کلاس ها. بعد از اون، استفاده از NewRef بدون سربار انجام میشد. البته امنیت کد هم به خوبی حفظ میشد، چون عملگر as در صورت مطابقت نداشتن نوع کلاس پیدا شده با نوع کلاس مورد نظر، یک Exception ایجاد میکنه.

u.2u.4u
چهارشنبه 26 آبان 1389, 06:15 صبح
ببخشید یه سوال دیگه دارم: اگر مانند کد آقای devil00x یعنی

NewRef := FindComponent(strComponent) as FindClass(strClass);
نوع کلاسمون هم یک رشته نامشخص باشه که بتونیم مثلا یک تابع درست کنیم که با تمام کلاسها کار کنه شما چه پیشنهادی می کنید؟

Felony
چهارشنبه 26 آبان 1389, 07:16 صبح
در همچین سناریویی، همچین توصیه ایی نمیشه. کد شما از کد اولیه کارایی پایین تری داره، چون دارید دو بار با استفاده از FindComponent به دنبال کلاس مربوطه در بین کلاس های ریجستر شده می گردید، و یک بار هم برای مطابقت نوع کلاس، سلسله مراتب کلاس ها رو پیمایش می کنید.

در کد اولیه یک بار جستجو در بین کلاس های رجیستر شده انجام میشد، و یک بار هم پیمایش سلسله مراتب کلاس ها. بعد از اون، استفاده از NewRef بدون سربار انجام میشد. البته امنیت کد هم به خوبی حفظ میشد، چون عملگر as در صورت مطابقت نداشتن نوع کلاس پیدا شده با نوع کلاس مورد نظر، یک Exception ایجاد میکنه.
یا توجه به اینکه از نوع شئ ارسالی اطمینان داریم ( TComboBox ) حرف شما درسته ، من در کل گفتم ؛ حالا اگر کد رو به صورت زیر تغییر بدیم کارایی مشابهی خواهیم داشت ؟ :

var
strComponent: String;
Temp: TComponent;
NewRef: TComboBox;
begin
strComponent := 'ComboBox1';
Temp:= FindComponent(strComponent);
if Temp is TComboBox then
NewRef := TComboBox(Temp);
end;


ببخشید یه سوال دیگه دارم: اگر مانند کد آقای devil00x یعنی

NewRef := FindComponent(strComponent) as FindClass(strClass);
نوع کلاسمون هم یک رشته نامشخص باشه که بتونیم مثلا یک تابع درست کنیم که با تمام کلاسها کار کنه شما چه پیشنهادی می کنید؟
function FindCom(const ComponentName, ComponentClass: String): TComponent;
var
Temp: TComponent;
begin
Temp:= Form1.FindComponent(ComponentName);
if Temp.ClassNameIs(ComponentClass) then
Result:= Temp;
end;

استفاده :
var
strComponent: String;
strClass: String;
NewRef: TComponent;
begin
strComponent := 'ComboBox1';
strClass := 'TComboBox';
NewRef:= FindCom(strComponent, strClass);
ShowMessage(NewRef.Name);
end;

u.2u.4u
چهارشنبه 26 آبان 1389, 14:48 عصر
function FindCom(const ComponentName, ComponentClass: String): TComponent;

ببخشید، واقعا دستتون درد نکنه. اما یک مشکلی هست. در این تابع که شما زحمتش را کشیدید، به یک سری از خواص که خاص هستند مثلا Visible در کومبوباکس دسترسی نداریم. اگرچه می تونیم نام را به دست بیاریم. یعنی در واقع ما یک Component داریم نه یک Combo box.

vcldeveloper
چهارشنبه 26 آبان 1389, 15:53 عصر
حالا اگر کد رو به صورت زیر تغییر بدیم کارایی مشابهی خواهیم داشت ؟
بله، اون کد معادل استفاده کردن از عملگر as هست.

Felony
چهارشنبه 26 آبان 1389, 20:07 عصر
function FindCom(const ComponentName, ComponentClass: String): TComponent;

ببخشید، واقعا دستتون درد نکنه. اما یک مشکلی هست. در این تابع که شما زحمتش را کشیدید، به یک سری از خواص که خاص هستند مثلا Visible در کومبوباکس دسترسی نداریم. اگرچه می تونیم نام را به دست بیاریم. یعنی در واقع ما یک Component داریم نه یک Combo box.

خروجی اون تابع از نوع TComponent هست و طبیعی هست که فقط به متدهای یک TComponent دسترسی داشته باشید ، میتونید بعد از اتمام کار خروجی رو به نوع مورد نظر TypeCast کنید و به خصوصیاتش دسترسی داشته باشید ، مثلا :

var
Temp: TComponent;
begin
Temp:= FindCom('ComboBox1', 'TComboBox');
if Temp is TCombobox then
TComboBox(Temp).Visible:= False;
if Temp is TListBox then
TListBox(Temp).Items.Add('Test');
end;

در کل دلفی یک زبان دینامیک نیست و باید به شیوه های مختلف ( مثل کد بالا ) عملیات مورد نظرتون رو پیاده سازی کنید .