PDA

View Full Version : رنگ پس زمینه فرم



alireza_tavakol
سه شنبه 10 مهر 1386, 01:24 صبح
دوستان بازم سلام
اشتباه نکنید منم همونی که همش سوال می پرسه بدون این که اول سرچ کنه
دوستان سوال ام شب من اینه که چه طوری می تونم توی یک فرم رنگ BackColor تغییر بدم البته یه نکته داره
اونم اینه که نمی خواهم همه جای فرم من یک رنگ باشه مثلا میخواهم مثل پرچم سه رنگ فلسطین باشه
لطفا کسی ننویسه از عکس زمینه استفاده کن

PC2st
سه شنبه 10 مهر 1386, 04:01 صبح
از رویداد Paint فرم استفاده کنید، مثلا:


private void Form1_Paint(object sender, PaintEventArgs e)
{
int
width = e.ClipRectangle.Width / 3,
height = e.ClipRectangle.Height;

e.Graphics.FillRectangle(Brushes.Red, new Rectangle(0, 0, width, height));
e.Graphics.FillRectangle(Brushes.White, new Rectangle(width, 0, width, height));
e.Graphics.FillRectangle(Brushes.Green, new Rectangle(2 * width, 0, width, height));
}

رویداد Paint زمانی اجرا میشه که لازم باشه محتویات فرم نمایش داده بشه... همچنین به کمک خاصیت e.Graphics میتونی به شیئ Graphics دسترسی داشته باشی تا انواع اشکال رو رسم کنی. بجای استفاده از رویداد Paint، میتونستی متد OnPaint رو آورلود کنی... یعنی:


protected override void OnPaint(PaintEventArgs e)
{
//Paint your graphics here...
}

alireza_tavakol
سه شنبه 10 مهر 1386, 16:55 عصر
چون من میخواهم بعد از فشار دادن یه دکمه توی فرمم این عملیات رو انجام بدم یه مشکل پیش میاید اونم اینکه به کلاس Graphics حافظه تصویری از طرف کارت گرافکی اختصاص داده نمی شود بنابراین پس از این که یه پنجره روی فرم من قرار بگیر تصویر پس زمینه فرم من پاک میشود
پس لطفا یه کلاس دیگه ای برای تنظیم رنگ زمینه معرفی کنید

emad_67
سه شنبه 10 مهر 1386, 17:33 عصر
بنابراین پس از این که یه پنجره روی فرم من قرار بگیر تصویر پس زمینه فرم من پاک میشود

این قسمت از کد رو به


int
width = e.ClipRectangle.Width / 3,
height = e.ClipRectangle.Height;



این تبدیل کن


int width = Width / 3,height =Height;

تا ویندوز مجبور بشه کل فرم رو مجددا ترسیم کنه.

Mahdi.Kiani
سه شنبه 10 مهر 1386, 17:39 عصر
چون من میخواهم بعد از فشار دادن یه دکمه توی فرمم این عملیات رو انجام بدم یه مشکل پیش میاید اونم اینکه به کلاس Graphics حافظه تصویری از طرف کارت گرافکی اختصاص داده نمی شود بنابراین پس از این که یه پنجره روی فرم من قرار بگیر تصویر پس زمینه فرم من پاک میشود
پس لطفا یه کلاس دیگه ای برای تنظیم رنگ زمینه معرفی کنید

شما توی کلاس یه متغیر از نوع Bool تعریف کن مثلا به نام DrawBack و همینطور که میدونید پیش فرض اون مقدار false هست

حالا توی رویداد paint مربوط به فرم بنویس




private void Form1_Paint(object sender, PaintEventArgs e)
{
if (DrwaBack)
{
Graphics g = e.Graphics;
System.Drawing.Drawing2D.LinearGradientBrush gbrush = new LinearGradientBrush(this.ClientRectangle, Color.Red, Color.Blue, LinearGradientMode.Vertical);
g.FillRectangle(gbrush, this.ClientRectangle);
}
}



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




DrwaBack = true;
this.Invalidate();


حالا تا وقتی که دکمه را نزنی background تغییر نمیکنه و با زدن دکمه backGround به صورت gradient در میاد
البته من از 2 رنگ استفاده کردم
شما میتونین رویداد paint را خودتون customize کنید

با این کار مشکلتون حل میشه
البته من از این جور حل کزدن مسائل خوشم نمیاد و به اونا میگم روشهای ماست مالی ولی خوب شاید به درد شما بخوره
مطمئنا راه های دیگه ها هست ولی بهترین مکان برای این جور کارها همون رویداد paint هر کنترلی هست
پس سعی کنید همیشه این جور اعمال را در همین رویداد انجام بدین و اگه خواستین از جای دیگه هم انجام بدین یه جوری ربطش بدین به همین رویداد

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

وقتی background را اینطوری رنگ آمیزی میکنی با resize کردن فرم background به صورت بریده یریده در میاد و در حین resize کردن فرمت حالت پرش پیدا میکنه
برای جلوگیری از این عمل کد زیر را در constructor فرم بعد از initializeComponent قرار بدین




SetStyle(ControlStyles.AllPaintingInWmPaint |
ControlStyles.ResizeRedraw |
ControlStyles.DoubleBuffer, true);

PC2st
سه شنبه 10 مهر 1386, 21:54 عصر
night_fall2 نکات مفیدی رو ارائه دادند... در پی ادامه صحبتهای ایشان: همچنین اگر بجای متد OnPaint، متد OnPaintBackground رو آوردلود کنیم، پرش ناشی از رنگ آمیزی هم از بین میره و در اینصورت، تنها تنظیم کردن ResizeRedraw روی true کفایت میکنه (برای ترسیم در حین تغییر سایز).


اونم اینکه به کلاس Graphics حافظه تصویری از طرف کارت گرافکی اختصاص داده نمی شود
متد CreateGraphics را روی شیئ this صدا بزنید، این متد شیئ Graphics مربوط به فرم جاری را برگشت میده.

alireza_tavakol
چهارشنبه 11 مهر 1386, 00:48 صبح
البته من از این جور حل کزدن مسائل خوشم نمیاد و به اونا میگم روشهای ماست مالی ولی خوب شاید به درد شما بخوره
همیشه یکی از روش های پاسخ گویی به مسئله تغییر دادن صورت مسئله است
البته دست شما درد نکنه از قدیم و ندیم گفتن
کاجی بهتر از هیچی

alireza_tavakol
چهارشنبه 11 مهر 1386, 00:56 صبح
حال به نظر دوستان عزیز در صورت این تغییرات بروی کد های برنامه و با در نظر گرفتن فرم گرافیکی بسیار بزرگ و حجیم و داشتن تعداد نرم های زیاد از همین نوع در هنگام اجرا برای کاربر نهایی مشکلی به وجو د نمی آورد مثلا سرعت پایین در هنگام اجرای برنامه

PC2st
چهارشنبه 11 مهر 1386, 17:37 عصر
حال به نظر دوستان عزیز در صورت این تغییرات بروی کد های برنامه و با در نظر گرفتن فرم گرافیکی بسیار بزرگ و حجیم و داشتن تعداد نرم های زیاد از همین نوع در هنگام اجرا برای کاربر نهایی مشکلی به وجو د نمی آورد مثلا سرعت پایین در هنگام اجرای برنامه
قرار دادن عکس (image) برای Background فرم، هم روی لود شدن و هم در زمان رسم شدن (Painting) فرم تاثیر میگذاره، اما تاثیرش زیاد قابل توجه نیست...
اگر عکس (image) رو در متد OnPaintBackground رسم کنید آن عکس با سرعت مناسبی روی فرم رسم میشه و چون رسم کردن عکس سرعت بیشتری به نسبت رسم خط و خطوط میگیره، پس اگر بازهم احتیاج به افزایش سرعت دارید، از آن SetStyle ای که night_fall2 در پست شماره 5 ارائه کردند، استفاده کنید.

Nima_NF
چهارشنبه 11 مهر 1386, 23:35 عصر
.
پس اگر بازهم احتیاج به افزایش سرعت دارید، از آن SetStyle ای که night_fall2 در پست شماره 5 ارائه کردند، استفاده کنید.

در این مورد اشتباه می کنید, همواره وقتی می خواهید از پرش تصویر رها شوید در صورت امکان به جای استفاده از DoubleBuffer ، از روش های مختلف refresh و رسم مجدد در مواقع لزوم استفاده کنید، زیرا تکنیک DoubleBuffer (دو بافره) برای افزایش سرعت نیست ، بلکه با کپی کردن تمامی اشکال قسمت مورد نظر فرم در حافظه و سپس لود کردن آن و ترسیم آن به صورت عکس بر روی فرم باعث از بین بردن پرش (flicker) می شود ، اما نکته منفی آن همان طور که واضح است کاهش سرعت و استفاده بیشتر حافظه می باشد. که البته ممکن است در بسیاری از موارد چندان احساس نشود.

PC2st
پنج شنبه 12 مهر 1386, 05:28 صبح
بله شما درست می فرمایید و من به این مورد دقت نکرده بودم... :-)
بهرحال بیشتر منظورم قرار دادن AllPaintingInWmPaint روی true بود، تا عملیات رسم با نادیده گرفتن پیام WM_ERASEBKGND صورت بگیره تا تصویر با سرعت بیشتری روی فرم رسم شود.

اما نکته منفی آن همان طور که واضح است کاهش سرعت
هر چند که وقتی بازه زمانی رو چک میکنم، وقتی OptimizedDoubleBuffer روی true باشه، بازه زمانی زیاد میشه، اما وقتیOptimizedDoubleBuffer رو بهمراه AllPaintingInWmPaint روی true تنظیم کنم، OptimizedDoubleBuffer باعث کاهش بازه زمانی میشه، دلیلشو خودمم نمیدونم!