PDA

View Full Version : مشکل رفرش در C#‎‎



BestFriend
دوشنبه 23 فروردین 1389, 19:10 عصر
با سلام من یه کدی تو سی شارپ نوشتم که text یه لیبل رو اول عوض میکنه و بعد یه for گذاشتم که با پیکسل های یه عکس کار میکنه و یه Progress Bar گذاشتم که در طی انجام عملیات پر مشه ، یه مقدار هم طول میکشه. ولی وقتی برنامه رو اجرا میکنم و روی Button کلیک میکنم text لیبل تغییری نمیکنه و Progress Bar شروع میشه به پر شدن و کار خودش رو درست انجام میده و وقتی که تیکه کد به آخرش رسید text لیبل عوض میشه.
میشه بگید چرا این طوری میشه و بگید که چه جوری میشه درستش کرد ؟ یعنی همون لحظه لیبل متنش عوض بشه و در پایان کد هم یه چیز دیگه نمایش بده
مثلا اولش بنویسه که در حال انجام عملیات و بعد از پر شدن Progress Bar بنویسه عملیات تمام شد.(یعنی تغییرات همون لحظه اعمال بشه)



lblstatus.Text = "در حال انجام عملیات ...";
Image i = p1.Image;
var od = new System.Drawing.Imaging.FrameDimension(i.FrameDimen sionsList[0]);
int fc = i.GetFrameCount(od);
Prog1.Maximum = fc;
string D = "";

for (int j = 0; j < fc; j++)
{

getframe(j, i);
D = "Dr" + j + ":";
SaveTo_Text(w, h,D);
Prog1.Value = j;


}
lblstatus.Text = "عملیات با موفقیت انجام شد ...";

با تشکر.

tefos666
دوشنبه 23 فروردین 1389, 20:31 عصر
دوست عزيز من منظورتون رو از رفرش متوجه نشدم ولي اگر حدسم درست باشه چندتا راه داري ، اولا استفاده از تايمر
Timer : همونطوري كه از اسمش معلومه با يه interval‌خاصي مياد برحسب اگه اشتباه نكنم ميلي هزارم ثانيه كاري رو انجام ميده كه درواقع مشكل عبارت رفرش اينجا حل ميشه

2 - واسه حل مشكلت از يه if استفاده كن
خود Progressbar يك min‌و max داره اول ستش كن بعد بگو اگر max برابر 100 شده تكست عوض بشه


3- احتمالا شما progressbar جنبه نمايشي داره و واسه زيبايي فرم استفاده كردين يعني بار واقع شده رو نشون نميده و كار نميكنه چون اگر از 1 تا 100 براي n بار پربشه كه كاري رو نكردين واسه استفاده صحيح يكم در مورد threat ها و خود timer در دات نت تحقيق كن ميتوني يك چيز خوب طراحي كني بايد اصطلاحا Backgroundworker باشه يعني واقعا پشت اين پرشدن درصد عملي انجام بشه مثلا كپي ويندوز رو ديدي ؟‌يا دانلود فايل ؟‌خوب اون زماني كه نشون ميده با progressbar همخوني داره اميدوارم متوجه منظورم شده باشي :لبخند:

به اينا يه نگاه بندازي چيزاي زيادي دستگيرت ميشه
http://www.csharphelp.com/2006/05/simply-use-progressbar-statusbar-timer-in-vs-net/

يا اين يكي
http://stackoverflow.com/questions/1952201/display-progress-bar-while-doing-some-work-in-c

اينم از زبون خود مايكروسافت

http://msdn.microsoft.com/en-us/library/system.componentmodel.backgroundworker.aspx

نهايتا براي پركردن progress مثل اين عمل كن


تو يه تايمر بنويس و اينتروالش رو ست كن و enable‌ اون رو true



privatevoid timer1_Tick(object sender, EventArgs e)
{
label1.Visible = !label1.Visible;
ProgressBar1.Step = 0;
ProgressBar1.Value = ProgressBar1.Value + 1;
if (ProgressBar1.Value == 100)
{
ProgressBar1.Value = 0;
}
}

كد اول باعث چشمك زدن متنتون ميشه

Saeed.Masoumi
سه شنبه 24 فروردین 1389, 00:56 صبح
Progress Bar شروع میشه به پر شدن و کار خودش رو درست انجام میده و وقتی که تیکه کد به آخرش رسید text لیبل عوض میشه.
میشه بگید چرا این طوری میشه و بگید که چه جوری میشه درستش کرد ؟
سلام
مشکل شما این است که تا زمانی که کار پیکسل خوانی پایان نیافته است فرم شما فریز میشود.
بخاطر اینکه کاری زمانبر است
راه حل استفاده از نخها و چون دارید با UI کار می کنید استفاده از Background worker بهترین گزینه است.
سرچ کنید لطفا

hosseinsinohe
سه شنبه 24 فروردین 1389, 08:32 صبح
سلام دوست عزیز
برای حل این مشکل کافی است کد خود را به شکل زیر تغییر دهید:



lblstatus.Text = "در حال انجام عملیات ...";
Application.DoEvents();
Image i = p1.Image;
var od = new System.Drawing.Imaging.FrameDimension(i.FrameDimen sionsList[0]);
int fc = i.GetFrameCount(od);
Prog1.Maximum = fc;
string D = "";

for (int j = 0; j < fc; j++)
{

getframe(j, i);
D = "Dr" + j + ":";
SaveTo_Text(w, h,D);
Prog1.Value = j;


}
lblstatus.Text = "عملیات با موفقیت انجام شد ...";
Application.DoEvents();
برای اطلاعات بیشتر به وبلاگ وحید نصیری (http://vahidnasiri.blogspot.com/2009/03/doevents.html) مراجعه کنید

BestFriend
سه شنبه 24 فروردین 1389, 17:11 عصر
ممنون از پاسخهای کاملتون در ضمن تو این کد که نوشتم Progress بر حسب انجام کار پر میشه
Prog1.Maximum = fc; که در حلقه for هم بعد از انجام هر عمل Progress پر میشه.
بازم ممنون ازتون.

Saeed.Masoumi
چهارشنبه 25 فروردین 1389, 00:18 صبح
سلام دوست عزیز
برای حل این مشکل کافی است کد خود را به شکل زیر تغییر دهید:

[code]
lblstatus.Text = "در حال انجام عملیات ...";
Application.DoEvents();
DoEvents() چه کار می کند (http://barnamenevis.org/forum/showpost.php?p=697754&postcount=5)
خطرات DoEvents() (http://barnamenevis.org/forum/showpost.php?p=697804&postcount=7)
بهترین راه استفاده از BackgroundWorker است.

hosseinsinohe
پنج شنبه 26 فروردین 1389, 11:42 صبح
DoEvents() چه کار می کند (http://barnamenevis.org/forum/showpost.php?p=697754&postcount=5)
خطرات DoEvents() (http://barnamenevis.org/forum/showpost.php?p=697804&postcount=7)
بهترین راه استفاده از BackgroundWorker است.

درسته دوست عزیز
ولی برای این مورد راه حل بدی نیست.

Saeed.Masoumi
پنج شنبه 26 فروردین 1389, 14:51 عصر
سلام
دوست عزیز حرف شما متین اما این روشها اصولا اسمشون ماستمالیه (توهین نشه خدا نکرده) سعی کنید شما که دارید وقت می ذارید و جواب می دین جواب کامل رو بدین بیشتر ثواب داره :لبخند:

hosseinsinohe
جمعه 27 فروردین 1389, 21:38 عصر
سلام
دوست عزیز حرف شما متین اما این روشها اصولا اسمشون ماستمالیه (توهین نشه خدا نکرده) سعی کنید شما که دارید وقت می ذارید و جواب می دین جواب کامل رو بدین بیشتر ثواب داره :لبخند:

خواهش میکنم
اما دقت داشته باشید در کد بالا استفاده از این کد بهترین روش می باشد.چرا که :

1. این کد درون حلقه مورد استفاده قرار نمی گیرد.
2.این کد درون Timer استفاده نمی شود.
3. و برای جمع بندی --> این کد در نهایت فقط دو بار اجرا می شود.

در مورد مشکل ذکر شده در بالا این بهترین و سریع ترین روش می باشد و لزومی به استفاده از روش های دیگر نیست.
در موارد دیگر و برای انجام عملیات های سنگین پشت پرده در سیستم بهترین روش استفاده از مطالب ذکر شده توسط شما می باشد.

ramin2nt2
شنبه 28 فروردین 1389, 00:26 صبح
سلام

داخل حلقه از دستور زیر استفاده کنید:



lblstatus.Text = "در حال انجام عملیات ...";
lblstatus.update();

hosseinsinohe
شنبه 28 فروردین 1389, 13:28 عصر
سلام

داخل حلقه از دستور زیر استفاده کنید:



lblstatus.Text = "در حال انجام عملیات ...";
lblstatus.update();



سلام
اکه کد دوستمون رو دقت داشته باشید نیازی به استفاده از حلقه نیست!!!

ramin2nt2
شنبه 28 فروردین 1389, 16:29 عصر
سلام
اکه کد دوستمون رو دقت داشته باشید نیازی به استفاده از حلقه نیست!!!

بله ، من کلمه حلقه رو اصلاح میکنم
ولی به هر حال با استفاده از update میشه، تغییرات رو در همون لحظه اعمال کرد.
بدون توجه به queue
ولی این روش مشکلاتی هم داره که دوستان واقف هستند

---------------------------------
در ضمن به خاطر اینکه نگارش فارسی بنده خیلی بد هست از دوستان عذر خواهی میکنم