PDA

View Full Version : آموزش: استفاده های گوناگون از متد AddObject در TStringList



a_mosavian
یک شنبه 07 فروردین 1390, 15:36 عصر
کلاس TStringList یکی از پرکاربردترین کلاس های دلفی است. با متد Add برای افزودن یک رشته به این لیست آشنایید اما این لیست قابلیت های دیگری مانند افزودن مقادیر دوگانه (Key Value) و اختصاص یک شی به هر کدام از رشته ها دارد که در جاهایی کار را ساده تر می کند.
مثلا فرض کنید یک ListBox دارید که می خواهید هر گاه یک آیتم از آن برگزیده شد، یک دکمه خاصی Enable شود. کافیست هنگام افزودن رشته به لیست از دستوری شبیه دستور زیر بهره بگیرید:
ListBox1.Items.AddObject('Show Button1', Button1);
و در قسمت رویداد OnClick رویدادی بنویسید که هر گاه آن ایتم در لیست باکس انتخاب شده بود:
TButton(ListBox1.Items.Objects
[ListBox1.ItemIndex]).Enabled:=True;
در واقع حتی می توان پا را فراتر گداشت و بجای مرتبط کردن یک شی به آیتم های StringList، یک عدد کاردینال یا Integer را بدان مربوط ساخت
ListBox1.Items.AddObject('ItemIndex1', TObject(1));
در واقع آنچه که بعنوان متغیر شی در آن ذخیره می شود، آدرس پوینتر آن است که خود عددی 32 بیتی در برنامه های 32 بیتی است! حال ما عدد 1 را به عنوان پوینتر به این تابع قالب می کنیم. اما از آنجایی که خود می دانیم چه کرده ایم و باید آن را چگونه بهره بگیریم، خطای Access Violation رخ نخواهد داد. برای بازگردانی عدد مرتبط شده با این آیتم، از دستوری به مانند دستور زیر:
X:=Integer(ListBox1.Items.Objects[ItemIndex]);
حال اگر بخواهیم هر موردی که کاربر برگزید، ترجمه آن در یک برچسب متنی به کاربر نمایش داده شود! کار سخت تر می شود چون رشته ها عدد نیستند و نمی توان آن را بعنوان پوینتر به دلفی انداخت! یک راه این است که آدرس پوینتری یک رشته را به آن بدهیم و دوباره بازگردانی کنیم. اما راه ساده تری بدون درگیر شده با وادی سخت و پیچیده و پرخطای پوینتر وجود دارد. کد زیر را ببینید خودتان در می یابید

const
LatinNumbers: array[1..5] of String =('unus' ,'duo', 'tres', 'quattuor', 'quinque');
var
X: string;
begin
ComboBox1.Items.AddObject('One', TObject(1));
ComboBox1.Items.AddObject('Two', TObject(2));
ComboBox1.Items.AddObject('Three', TObject(3));
ComboBox1.Items.AddObject('Four', TObject(4));
ComboBox1.Items.AddObject('Five', TObject(5));
// some codes to let user to choice an item
X:=LatinNumbers[Integer(ComboBox1.Items.Objects[ComboBox1.ItemIndex])];
end;

AliReza Vafakhah
یک شنبه 07 فروردین 1390, 22:47 عصر
تو این دو سه سال عمرم تو سایت هنوز چنین پستی با این جمله بندی زیبا و شیوا ندیده بودم و البته نکات زیبا. دست گلت درست.

mbshareat
دوشنبه 08 فروردین 1390, 00:09 صبح
سلام علیکم
ببخشید که من خیلی پرتم ولی به نظر شما این کد :

TButton(ListBox1.Items.Objects[ListBox1.ItemIndex]).Enabled:=True;
بهتر نیست با دستور Case ListBox1.ItemIndex Of جایگزین بشه؟
چه نیازی هست که حتما از AddObject استفاده بشه؟

a_mosavian
دوشنبه 08 فروردین 1390, 02:36 صبح
سلام علیکم
ببخشید که من خیلی پرتم ولی به نظر شما این کد :

TButton(ListBox1.Items.Objects
[ListBox1.ItemIndex]).Enabled:=True;
بهتر نیست با دستور Case ListBox1.ItemIndex Of جایگزین بشه؟
چه نیازی هست که حتما از AddObject استفاده بشه؟
برنامه نویسی بدون بهره گیری از دستورات شرطی یه هنر هست! من اگه بخوام با if و case برنامه بنویسم هم نوشتن کدم چند برابر بیشتر میشه هم سرعت اجرای برنامه م چند برابر کمتر میشه! تازه با همین روش ها یه جوری کد می نویسم که کمترین میزان تغییر رو برای توسعه های آینده می خواد. به همون کد آخرم نگاه کن! برای افزودن مورد ششم تنها یک کلمه و یک خط اضافه میشه. حالا اگه با case بنویسم 2 خط. تو این مثال ساده ممکنه به چشم نیاد اما هنگامی که داری برنامه واقعی می نویسی همین بی دقتی می کوبندت زمین!!
گاه تنها تفاوت یک برنامه نویس خوب و بد در بکار گرفتن و یا نگرفتن دستورات شرطیست!

vcldeveloper
دوشنبه 08 فروردین 1390, 04:55 صبح
بهتر نیست با دستور Case ListBox1.ItemIndex Of جایگزین بشه؟
چه نیازی هست که حتما از AddObject استفاده بشه؟
وقتی داده های ListBox شما در زمان اجرا در حال تغییر باشه (مثلا توسط کاربر) شما هیچ وقت در زمان نوشتن کد نمی دونید که باید چه تعداد گزینه برای case بنویسید.


من اگه بخوام با if و case برنامه بنویسم هم نوشتن کدم چند برابر بیشتر میشه هم سرعت اجرای برنامه م چند برابر کمتر میشه!
توی این مورد خاص، اگر تعداد گزینه های موجود در ListBox محدود بود، کد شما و case تفاوت چندانی از نظر سرعت نخواهند داشت. البته سایر بحث ها، مثل وجود نقاط تغییر متعدد در کد، یا طولانی شدن کد نوشته شده، و غیره صحیح هست.