PDA

View Full Version : سوال: چگونگی نوشتن یه سری کد مشترک در رویداد کلیک چندین لیبل



k_ce_esf
یک شنبه 22 خرداد 1390, 22:07 عصر
با سلام.
حدود 30 تا label دارم که این تعداد ممکن است در آینده اضافه هم بشه،در رویدادclick همه این label ها میخوام یک سری کد مشترک داشته باشم(مثلا در رویداد click همه ،یک تابع که تعریف کردم را صدا بزنم).
چه طوری کد بنویسم که لازم نباشه یکی یکی در رویداد click هر کدام از label ها برم و این کدهای مشترک را بنویسم؟
خیلی ممنون میشم کمکم کنید.

haghft
یک شنبه 22 خرداد 1390, 22:16 عصر
همه اون لیبل هارو انتخاب کن و بعد از قسمت event روی فیلد click کلیک کن و کدتو تو همون بنویس یا یه لیبل بساز تو رویداد click کدتو بنویس بعد بقیه لیبل هارو از toolbox نساز بلکه بجاش از این lable کپی بگیر(دکمه کنترل رو نگه دار بعد از روی lable یه drag&drop انجام بده)

k_ce_esf
یک شنبه 22 خرداد 1390, 22:53 عصر
ممنونم.بله،این راه هست اما نمیخوام این کار را بکنم.این کار برا وقتی که من میخوام در آینده label اضافه کنم عملی نیست و باید بیام دوباره در کدا دستکاری کنم.
یه راهی که خودم بهش رسیدم اینه که یک foreach بنویسم و در آن بگم برای همه کنترل های از نوع لیبل که عکس دارند(چون فقط همین lable هام هستند که image دارند) در رویداد click آن ها بگم این تابع را فراخوانی کن،در vb برای این کار یه همچین کدی داریم: handler(event name,function name);
اما نمیدونم تو c# باید برای این کار چه کدی باید بنویسم.
ممنون میشم کمکم کنید.

B.I.O.H.A.Z.A.R.D
یک شنبه 22 خرداد 1390, 23:06 عصر
سلام

روش جناب haghft (http://barnamenevis.org/member.php?38205-haghft) رو تا حالا امتحان نکردم، ولی خودم اینکارو میکنم (همیشه) کد مورد نظرم رو بصورت یه تابع تعریف میکنم:

private void نام تابع ()
{
// things to do
}

بعد توی مثلاً رویداد کلیک هر لیبل مینویسم:

label1.Click += new EventHandler(نام تابع);

امیدوارم به کارتون بیاد

k_ce_esf
یک شنبه 22 خرداد 1390, 23:25 عصر
خیلی ممنونم.این روشتون هم درسته اما به هر حال این جا هم باید برم در رویداد کلیک هر کدوم از labelها و این کد را بنویسم،همان طور که در جواب قبلی گفتم ،نمیخوام این کار را بکنم.یه کار تقریبا مثل روشی که تو جواب قبل گفتم را میخوام انجام بدم.
ممنون میشم کمکم کنید.

haghft
یک شنبه 22 خرداد 1390, 23:56 عصر
خب قسمت دوم کد جناب B.I.O.H.A.Z.A.R.D (http://barnamenevis.org/member.php?110603-B.I.O.H.A.Z.A.R.D) هم همون معادل C# هست.ولی میتونی به جاش اینو بنویسی تو همون foreach که میگی:
lable1_Click(new object(),new EventArgs());

Directx
دوشنبه 23 خرداد 1390, 00:02 صبح
دوست عزیز چرا به خودتون این همه زحمت می دید بهتر نیست که یه کلاس تعریف کنید که از لیبل ارث می بره و رویداد ها و خاصیت های دلخواهتون رو بهش بدید و هر موقع لازم داشتین لیبل خودتونو به فرم اضافه کنید

haghft
دوشنبه 23 خرداد 1390, 00:15 صبح
این کدو امتحان کردم جواب داد:
foreach (Control ctrl in Controls)
{
if (ctrl is Label && (ctrl as Label).Image != null )
{
MessageBox.Show(ctrl.Name);
}
}

2ndesigner
دوشنبه 23 خرداد 1390, 00:55 صبح
//سازنده
public Form1()
{
InitializeComponent();
label1.Click+=new EventHandler(label_Click);
label2.Click+=new EventHandler(label_Click);
label3.Click+=new EventHandler(label_Click);
}
public void label_Click(object sender, EventArgs e)
{
//یک لیبل تعریف می کنیم برابر لیبلی که کلیک شده
Label lbl = (Label)sender;
//
//با این کار خاصیت رنگ پس زمینه لیبلی که کلیک شده آبی می شه
lbl.BackColor = Color.Blue;
}

haghft
دوشنبه 23 خرداد 1390, 09:36 صبح
این روشی که دوستمون 2ndesigner گفتن همون روش اولی هست که من گفتم ولی باز با این روش ایشون هر دفعه باید eventhandler جدید بنویسه.اون روش آخری که گفتم خودم تست کردم خیلی خوب همون جور که دوستمون میخوان جواب میده.

naeeme
دوشنبه 23 خرداد 1390, 10:42 صبح
دوست عزیز چرا به خودتون این همه زحمت می دید بهتر نیست که یه کلاس تعریف کنید که از لیبل ارث می بره و رویداد ها و خاصیت های دلخواهتون رو بهش بدید و هر موقع لازم داشتین لیبل خودتونو به فرم اضافه کنید

درست ترین روش، روشی هست که دوستمون Directx گفتن!
یک لیبل اختصاصی تعریف کنید که این عملیات رو براتون انجام بده. دیگه اینقدر زحمت کد نوشتن هم به خودتون نمیدید


ممنونم.بله،این راه هست اما نمیخوام این کار را بکنم.این کار برا وقتی که من میخوام در آینده label اضافه کنم عملی نیست و باید بیام دوباره در کدا دستکاری کنم.
یه راهی که خودم بهش رسیدم اینه که یک foreach بنویسم و در آن بگم برای همه کنترل های از نوع لیبل که عکس دارند(چون فقط همین lable هام هستند که image دارند) در رویداد click آن ها بگم این تابع را فراخوانی کن،در vb برای این کار یه همچین کدی داریم: handler(event name,function name);
اما نمیدونم تو c# باید برای این کار چه کدی باید بنویسم.
ممنون میشم کمکم کنید.
این کار اصلا جالب نیست چون زمان زیادی رو در برنامه هدر میده

haghft
دوشنبه 23 خرداد 1390, 10:53 صبح
منم با روش DirectX موافقم خیلی روش ساده و جمع و جوریه کار راه اندازم هست.

k_ce_esf
دوشنبه 23 خرداد 1390, 11:43 صبح
ممنون از همه دوستان به خاطر جواب هاشون.
روشي كه haghft فرمودند همان است كه مدنظر است و براي عوض كردن text جواب ميده،منتها من ميخوام يك تابع را فراخواني كنم،من با توجه به همه راهنمايي ها اين كار را انجام دادم:

Label lbl1 = (Label)sender;
foreach (Control control1 in this.Controls)
{
if (control1 is Label && (control1 as Label).Image != null)

lbl1.Click += new EventHandler(date_time()); //esme tabe date_time e

}
اروري كه ميده روي خط lbl1.Click += new EventHandler(date_time()); است و ميگه:Method name expected
اولا چرا اين ارور را ميده و كد درست چيه و ثانيا من كدام قسمت برنامه بايد اين كد ها را بنويسم،با توجه به اين كه ميخوام براي رويداد كليك چندين ليبل كار كند؟
بازم ممنون ميشم اگه كمكم كنيد.

Directx
دوشنبه 23 خرداد 1390, 11:58 صبح
روش اصولی

این کلاس رو به پروژه اضافه کنید و پروژه یک با build کنید و از قسمت tools لیبل رو به فرم اضافه کنید.



class CostomLabel:Label
{
public CostomLabel()
{
this.Click += new EventHandler(CostomLabel_Click(/*اسم تابعی که با کلیک اون تابع باید انجام بشه. می تونید جند تا تابع اضافه کنید */));
}

void CostomLabel_Click(object sender, EventArgs e)
{
//هر کاری می خوایید اینجا انجام بدید مثلا
this.Text = "DirextX";
}
}
}

gwbasic
دوشنبه 23 خرداد 1390, 13:08 عصر
ممنون از همه دوستان به خاطر جواب هاشون.
روشي كه haghft فرمودند همان است كه مدنظر است و براي عوض كردن text جواب ميده،منتها من ميخوام يك تابع را فراخواني كنم،من با توجه به همه راهنمايي ها اين كار را انجام دادم:

Label lbl1 = (Label)sender;
foreach (Control control1 in this.Controls)
{
if (control1 is Label && (control1 as Label).Image != null)

lbl1.Click += new EventHandler(date_time()); //esme tabe date_time e

}
اروري كه ميده روي خط lbl1.Click += new EventHandler(date_time()); است و ميگه:Method name expected
اولا چرا اين ارور را ميده و كد درست چيه و ثانيا من كدام قسمت برنامه بايد اين كد ها را بنويسم،با توجه به اين كه ميخوام براي رويداد كليك چندين ليبل كار كند؟
بازم ممنون ميشم اگه كمكم كنيد.
پرانتز رو بردار مشکلت حل می شه ولی چرا از روش اصولی استفاده نمی کنی کدم که Directx برات گذاشته
اگه شما می خوای بروش خودت بری پس بهتره اصلا سوال نکنی چون ارزشی برای کسی که وقت می زاره جوابتو می ده قائل نیستی :عصبانی:

haghft
دوشنبه 23 خرداد 1390, 13:25 عصر
ممنون از همه دوستان به خاطر جواب هاشون.
روشي كه haghft فرمودند همان است كه مدنظر است و براي عوض كردن text جواب ميده،منتها من ميخوام يك تابع را فراخواني كنم،من با توجه به همه راهنمايي ها اين كار را انجام دادم:

Label lbl1 = (Label)sender;
foreach (Control control1 in this.Controls)
{
if (control1 is Label && (control1 as Label).Image != null)

lbl1.Click += new EventHandler(date_time); //esme tabe date_time e

}
اروري كه ميده روي خط lbl1.Click += new EventHandler(date_time()); است و ميگه:Method name expected
اولا چرا اين ارور را ميده و كد درست چيه و ثانيا من كدام قسمت برنامه بايد اين كد ها را بنويسم،با توجه به اين كه ميخوام براي رويداد كليك چندين ليبل كار كند؟
بازم ممنون ميشم اگه كمكم كنيد.
به جای
lbl1.Click += new EventHandler(date_time); //esme tabe date_time e
میتونی از
lable1_Click(new object(),new EventArgs());
استفاده کنی در همون یک رویداد کلیک همه چیزو بنویسی ولی با این حال باز روش DirectX بهتره!

k_ce_esf
دوشنبه 23 خرداد 1390, 15:46 عصر
از بابت جواب همه دوستان تشكر،من همه راه ها را كه فرموديد امتحان كردم،مسلما دنبال بهترين روشم و براي همين مزاحم دوستان ميشم،روش DirectX بهترين روشه،كاملا واضحه و قبول دارم،خيلي ممنون از ايشان،اين روش را هم امتحان كردم منتها يه مشكلي هست كه به راه حلش نرسيدم و به همين دليل روش هاي ديگه را هم امتحان كرد،مشكل اين جاست كه اين تابعي كه من ميخوام ازش در رويداد كليك هر ليبل استفاده كنم تابع ساده اي نيست، اين تابع درواقع يه search است كه درش از sqlcommand,data reader,data grid,... استفاده شده،اين تابع را كجا بايد تعريف كنم؟ CostomLabel_Click چه كاري انجام ميده؟كدهايي كه مربوط به اين تابع است را بايد درش بنويسم؟با توجه به تابعي كه من دارم و اينكه درش از كامپوننت هاي مختلف استفاده كردم،ميشه اين كار را انجام داد؟چه طوري؟
فرموديد بنويسم :



this.Click += new EventHandler(CostomLabel_Click(/*اسم تابعی که با کلیک اون تابع باید انجام بشه. می تونید چند تا تابع اضافه کنید */)); }
منظور از اسم آن تابع چيه؟كجا بايد تابع مورد نظرم را تعريف كنم كه اين جا صدا بزنم؟


در مورد راهنمايي كه gwbasic فرمودند،خيلي ممنونم اما پرانتز را برداشتم،باز هم جواب نداد و اين ارور را داد:


No overload for 'date_time' matches delegate 'System.EventHandler' (http://barnamenevis.member.php?25140-gwbasic)



در مورد راهنمايي كه haghft فرمودند،خيلي ممنونم ،امتحان كردم اما اولا اين كه اگه فقط من اين دوتا خط را به جاي هم بنويسم،از كجا ميتونه بفهمه كه آن تابع مورد نظري كه ميخوام با كليك روي هر ليبل اجرا بشه كدومه؟اگر بعد از اين خط تابع را هم فراخواني كنم،نتيجه مشابهي دارد
ثانيا فرموديد در همون يه رويداد كليك همه چيز را بنويس،منظورتون از اين جمله را متوجه نشدم،يك بار در رويداد كليك مربوط به فرم اين كدها را نوشتم،كه در اين صورت چه اسم تابع را بعد از خطي كه فرموديد نوشتم و چه ننوشتم،نه ارور مي داد و نه هيچ كاري برام انجام ميداد.
در رويداد كليك اولين ليبل هم اين كدها را نوشتم كه در اين صورت ارور زير را داد:

An unhandled exception of type 'System.StackOverflowException' occurred in paziresh.exe



خيلي روي همه روش ها كار كردم اما هر كاري ميكنم نتيجه نميده،:گریه:خواهش ميكنم كمكم كنيد.

Directx
دوشنبه 23 خرداد 1390, 16:54 عصر
دوست عزیز شما به کد زیر خوب دقت کنید.
class CostomLabel:Label
{
public CostomLabel()
{
this.Click += new EventHandler(CostomLabel_Click);
}

void CostomLabel_Click(object sender, EventArgs e)
{
//هر کاری می خوایید اینجا انجام بدید مثلا
this.Text = "DirextX";
}
}
}

اگه خوب دقت کنید تابع click پایین (CostomLabel_Click)به رویداد کلیک لیبل اضافه می شه نوشتنش هم کار خیلی ساده ای یعنی بعد از علامت =+ فقط کافیه که دو بار کلید tab رو فشار بدید تا خود vs تابع مورد نیاز رو ایجاد کنه الان شما اگه این لیبل رو به فرمتون اضافه کنید با کلیک رو اون کدهای تابع پایین اجرا میشه (در اینجا text ش به direxX تغییر پیدا می کنه اگر بخواهید که علاوه بر کاری که تو این تابع انجام دادید کار دیگه ای انجام بشه که برای هر لیبل منحصر به فرد باشه بعد از افزودن به فرم دوبار کلیک کنید و اعمال مورد نظرتون رو توش بنویسید روش های دوستان هم خیلی مفیده ولی برای مورد شما راه حل به این صورته و راه حل های دوستان که افزودن تابع به رویداد click در runtime رو در حداقل در این مورد اصلا درست نمی بینم

k_ce_esf
دوشنبه 23 خرداد 1390, 22:27 عصر
بار هم خیلی ممنون از جوابتون،لطف میکنید جواب میدید،تشکر
کاری که من میخوام بکنم برای همه لیبل هام مشترکه،یه search است که در آن ازsqlcommand,data reader,data grid,... استفاده کردم،در واقع تنها تفاوت این لیبل ها اینه که در هر کدوم از این لیبل ها یک text گذاشتم،که این text با توجه به مقداری که در combo box من در فرم اصلی داره و search بر اساس اون انجام میشه،پر میشن.
باید این کامپوننت ها را به صورت دستی توی همینcostom_label_click تعریف کنم و کدهاشو بنویسم؟
اگه این طوره تکلیف design فرمم چی میشه ؟چون در design این فرم محل قرار گرفتن data grid خیلی مهمه ،ضمن این که مقدار text هر label با توجه به مقداری که در combo box فرم اصلی هست تغییر میکنه،تنها یک data grid در فرمم میخوام داشته باشم،یک sqlcommand میخوام داشته باشم و یه همچین شرایطی،تابع من به سادگی تابعی که شما فرمودید در مثالتون برای عوض کردن text نیست و این شرایط را داره.
با این اوصاف چه کار باید کنم؟باز هم همین راه حل عملی است؟
بازم ممنون میشم کمکم کنید

k_ce_esf
سه شنبه 24 خرداد 1390, 23:05 عصر
با تشکر از همه دوستان،بالاخره امروز مشکلم حل شد بعد از امتحان چندین روش،نتیجه ای که گرفتم بعد از این همه امتحان را این جا می گذارم،شاید به دردتان بخوره.
در مورد روش کلاس که Directx فرمودند،بهترین روشه اما برای کار من زیاد پاسخ گو نیست،چون همان طوری که گفتم تابعی که من میخوام با کلیک روی هر لیبل انجام شه ،یه search است که درش باید از datagrid,sqlcommand,data reader,...استفاده میشه و در ضمن من فقط میخوام در فرم اصلیم از یه reader,command,grid استفاده کنم،میشهpropperty هایی در کلاس ایجاد کرد که از هرکدوم از این کامپوننت هایی که میخوام(reader,...)ارث بری کنه را در کلاس ایجاد کرد ، بعد توی فرم اصلی هم این کامپوننت ها (data grid , sql command,data reader,..)را در جای مناسب قرار داد و لی مشکل اینه که هم به سادگی نوشته نمیشند و هم اینکه باگ گیری روش برای غیر حرفه ای ها(مثل من) مشکله

با توجه به همه راه حل ها من این کار را انجام دادم:

private void frmround_Load(object sender, EventArgs e)
{
foreach (Control control1 in this.Controls)
{
if (control1 is Label && (control1 as Label).Image != null)
{
control1.Click += new EventHandler(label_click);

}
}
}




private void label_click(object sender, EventArgs e)
{
Label lbl;
lbl = (Label)sender;
int i12;
i12 = Convert.ToInt32(lbl.Tag);
date_time(i12);//date_time name tabee mane

}


در مورد سرعت که دوستان فرمودند،بله سرعتش پایینه،اما فقط برای اولین لیبل،به خاطر این که در حافظه نیست، که این هم راه حل داره،استفاده از روش های cashing
امیدوارم به دردتون بخوره

Sajjad1364
چهارشنبه 25 خرداد 1390, 10:44 صبح
میتونید بجای:
control1.Click += new EventHandler(label_click);

بنویسید
control1.Click += label_click;

که مختصر و کوتاهتره.