Speed Racer (22-08-19)
سلام
یه کنترلی بنام TransparentControl را دارم میسازم (قبلا ساختم اما الان قابلیت های جدیدی دارم بهش اضافه میکنم)
توی نسخه ی قبل این جوری بود که اگه در سطح کنترل های خواهر و برادر این کنترل ، کنترلی به پشت این کنترل میرفت ، کاربر باید اون کنترل را میداد تا این کلاس ، قبل از رسم خودش ، اون کنترل را اول رسم کنه. این کلاس را در زیر پیوست میکنم
دارم این قابلیت را اضافه میکنم که نیازی نباشه که کاربر بخواد کنترل های پشت و کنترل های جلویِ (در سطح کنترل خواهر و برادری) کنترل TransparentControl را بهش بده و این کار را میخوام خود همین کنترل انجام بده . اما مشکلی داره که در زیر میگم .(هنوز بعضی از اعضاش کار نمیکنه و تموم نشد . فعلا از متد سازنده ای که کدش رو میذارم ، لطفا چک کنید) .
در متد سازنده ی فرم تون ، این را بنویسید لطفا (بجای مسیر فایل png ، که میدونین هر فایل مورد نظر خودتون که خواستین را بدین . فقط اندازه اش جوری باشه که دو کنترل در کد زیر ، نصف شون یا قسمتی ازشون ، روی همدیگه بیفتن) :
نکته ی عجیب برای من اینه که وقتی روی همین کد بالا (مخصوصا در خط this.Controls.Add(transparentControl) و همینطور در قسمت get و همینطور set برای پروپرتی BackgroundControls در کلاس زیر که پیوست کردم ، علامت breakpoint را میذارم و اگه بریک پوینت را همه را با دکمه ی F11 بزنم بره جلو ، پروپرتی BackgroundControls ، در شی transparentControl ، مقدار میگیره (اولین عضو از مقدارش برابر با شی transparentControl_2 میشه) که منم همین رو میخوام و درسته . اما هر دفعه بریک پوینت را با دکمه ی F10 بزنم بره جلو یا اصلا بریک پوینتی نذارم، با کمال تعجب میبینم که این پروپرتی (پروپرتی BackgroundControls ، در شی transparentControl) ، اون مقداری که قبلا گرفت را نداره و null میشه !!کد:private TransparentControl transparentControl; private TransparentControl transparentControl_2; public Form1() { Bitmap bitmap = new Bitmap(@"E:\Project\Visual Studio\C#.Net\Saved Project\0 Important Project\Poshtibangir Tolo\PoshtibangirTolo\bin\Debug\Icon\PanelToolBar\Close\Close.png"); TransparentControlBitmap controlBitmap = new TransparentControlBitmap(bitmap, new Bitmap(bitmap.Width, bitmap.Height), new Bitmap(bitmap.Width, bitmap.Height), new Bitmap(bitmap.Width, bitmap.Height)); controlBitmap.GraphicInterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; controlBitmap.SetColor(bitmap, ExportBitmapFor.MouseEnterBitmap, Color.DeepSkyBlue); controlBitmap.SetColor(bitmap, ExportBitmapFor.MouseDownBitmap, Color.Blue); controlBitmap.SetColor(bitmap, ExportBitmapFor.ControlDisabledBitmap, Color.Yellow); this.transparentControl = new TransparentControl(controlBitmap, new Point(200, 10)); this.transparentControl.Name = "Close"; this.transparentControl.MouseClick += new MouseEventHandler(this.TransparentControl_MouseClick); Bitmap bitmap_2 = new Bitmap(@"E:\Project\Visual Studio\C#.Net\Saved Project\0 Important Project\Poshtibangir Tolo\PoshtibangirTolo\bin\Debug\Icon\PanelToolBar\Setting\Setting.png"); TransparentControlBitmap controlBitmap_2 = new TransparentControlBitmap(bitmap_2); controlBitmap_2.MouseEnterBitmap = TransparentControlBitmap.SetColor(bitmap_2, Color.DeepSkyBlue); controlBitmap_2.MouseDownBitmap = TransparentControlBitmap.SetColor(bitmap_2, Color.Blue); controlBitmap_2.ControlDisabledBitmap = TransparentControlBitmap.SetColor(bitmap_2, Color.Yellow); this.transparentControl_2 = new TransparentControl(controlBitmap_2, new Point(210, 20)); this.transparentControl_2.Name = "Setting"; this.transparentControl_2.MouseClick += new MouseEventHandler(this.TransparentControl_MouseClick); this.Controls.Add(transparentControl); this.Controls.Add(transparentControl_2); }
چرا این دو اتفاق میافته؟
بسیار تعجب آوره !!
بعد اینکه میشه وقتی کسی کنترلی را BringToFront کرد ، ما بتونیم رویدادی ازش بدست بیاریم؟ یعنی رویدادی برای BringToFront ظاهرا وجود نداره . داره؟ اگه روشی برای این کار هست یا کاریش میشه کرد (از طریق api ویندوز و هر روش دیگه ای) ، میگین؟ منظورم کد نیست . در صورت وجود ، لطفارفرنس بدین ، خودم بررسی میکنم.
----------------------------------------------------------------
روند کلی کنترل TransparentControl رو اینجوری کردم که هر کنترلی در سطح خواهر و برادر کنترل TransparentControl مون (که والد یکسان دارن) ، به کنترل والدش اضافه شد یا تغییر باند داد (بجز کنترلِ جاری TransparentControl) ، به رویداد Parent_ControlAddedAndRemoved و SiblingControls_BoundsChanged متصل شون کردم . توی این رویدادها هم که هر دو یک کار را میکنن ، اول چک میکنم که کنترلی که این رویدادها براشون اتفاق افتاد ، آیا با کنترلِ جاری TransparentControl ، محیط مشترک (همون Rectangle.Intersect) دارن یا نه؟ اگه داشتن ، چک میکنم که آیا این کنترلِ اضافه شده ، یه بار در کلِ کنترل های پشتی اش هست؟ اگه بود ، اون کنترل رو به اعضای آرایه ی (پروپرتی) BackgroundControls اش اضافه میکنم . اگه در کنترل پشتی اش نبود ، در کل کنترل های جلویی اش چک میکنم که وجود داره یا نه و اگه اونجا وجود داشت ، اون کنترل رو به اعضای آرایه ی (پروپرتی) ForegroundControls اش اضافه میکنم .
بعد هم اعضای پروپرتی BackgroundControls رو قبل از Invalidate کردنِ کنترل جاری TransparentControl ام invalidate میکنم (فقط اون بخشی شون را که با کنترل TransparentControl ام مشترک هستند ، invalidate میکنم) (تا قبل از کنترل جاری TransparentControl ام رسم بشن) و همین کار را بعد از invalidate کردنِ کنترل جاری TransparentControl ام برای پروپرتی ForegroundControls انجام میدم (این را هم بخش مشترک شون را invalidate میکنم) ( تا بعد از کنترل جاری TransparentControl ام رسم بشن)
البته این قسمت از کدها فعلا یه مشکلی داره که باید وقتی متد OnParentChanged اجرا میشه هم ، این عملیات را یه بار انجام بدم یعنی رویداد Parent_ControlAddedAndRemoved را اون موقع ، فراخونی کنم.
مشکلات دیگه ای هم شاید داشته باشه (فعلا نمیدونم).
خیلی ممنون
دانلود فایل پیوست TransparentControl
(چون نمیذاشت توی اینجا فایلی پیوست کنم ، در سایت دیگه گذاشتم)
آخرین ویرایش توسط SajjadKhati در تاریخ 23-07-19 انجام شده است
دانلود فیلم آموزش برنامه نویسی Visual Studio C#.Net
فیلم آموزش کامل Autoplay Media Studio
وقتی انسان ، حیوان هست ، پس قیمت میتونی براش بذاری ولی وقتی انسان حَیّ مُتِاَلِّه هست که قیمت نداره ، بها داره. "دکتر حسن عباسی"
Speed Racer (22-08-19)
سلام سجاد جان،
من کد شما رو داخل یه پروژه قرار دادم و اجرا کردم ولی مقدار BackgroundControls همیشه خالی بود. در متد Set این خاصیت هم Breakpoint گذاشتم ولی هرگز برنامه در این نقطه متوقف نشد! علاوه بر اون رویداد OnMouseEnter به همین دلیل خطا میده.
در مورد بخش دوم سوالت، منظورت رو از رویداد BringToFront متوجه نشدم!
فکر کنم لازم باشه بیش تر شرح بدی یا خود پروژه رو بذاری. این جوری شاید بشه بهتر راهنمایی کرد.
شاد باشی
آرمین
'چو ایران نباشد، تن من مباد
Dim Armin As Iranian
If Iran.Enabled = False Then Armin.Enabled = False
AMD>INTEL (23-07-19), M A H R A D (27-07-19), SajjadKhati (23-07-19), Speed Racer (22-08-19)
سلام
خیلی ممنون استاد آرمین.
کد (پست اول) را بجای متد سازنده ، توی رویداد Load گذاشتم ، درست شد (و پروپرتی BackgroundControls در شی transparentControl در کد بالا ، که انتظار داشتم ، بدون بریک پوینت ای مقدار گرفت)
حالا دلیل اش را نمیدونم.
نمیدونم هم میشه داخل کلاس TransparentControl هم کدی نوشت که این محدودیت برداشته بشه.
منظورم متد Control.BringToFront هست . یه رویدادی میخوام که کسی برای کنترلش این متد را فراخونی میکنه ، اون رویداد را فراخونی کنیم . البته احتمالا بشه در اینجا یه چیزایی در این باره پیدا کرد . اما هنوز کامل چک نکردم :
WM_WINDOWPOSCHANGED message - Windows applications | Microsoft Docs
دانلود فیلم آموزش برنامه نویسی Visual Studio C#.Net
فیلم آموزش کامل Autoplay Media Studio
وقتی انسان ، حیوان هست ، پس قیمت میتونی براش بذاری ولی وقتی انسان حَیّ مُتِاَلِّه هست که قیمت نداره ، بها داره. "دکتر حسن عباسی"
Speed Racer (22-08-19)
خواهش می کنم سجاد جان!
در مورد این بخش، هنوز واسه من عجیبه که چنین رفتاری رو مشاهده می کنی! کلا یه تقدم و تاخر در اجرای constructor فرم و رویداد Load فرم وجود داره ولی همون طور که گفتم شاید بهتر باشه کل پروژه ات رو پیوست کنی (csproj به همراه sln) تا دقیق تر بررسی کرد.کد (پست اول) را بجای متد سازنده ، توی رویداد Load گذاشتم ، درست شد (و پروپرتی BackgroundControls در شی transparentControl در کد بالا ، که انتظار داشتم ، بدون بریک پوینت ای مقدار گرفت)
حالا دلیل اش را نمیدونم.
منظورت رو از محدودیت متوجه نمیشم.نمیدونم هم میشه داخل کلاس TransparentControl هم کدی نوشت که این محدودیت برداشته بشه.
الان متوجه شدم. کلا اگر یه کنترل رو BringToFront کنی، رویداد Layout در container اون تحریک میشه. مثلا اگر بخوای label1 رو در form1 جلو تر از سایر کنترل ها قرار بدی، رویداد Layout در form1 فراخوانی میشه. اون پیوندی هم که گذاشتی نمی دونم چقدر می تونه کمکت کنه ولی غالب WinAPI ها به شکل Managed در دات نت وجود داره و فکر کنم اون موردی که شما قرار دادی بیش تر به درد تشخیص تغییر موقعیت یه پنجره بخوره.منظورم متد Control.BringToFront هست . یه رویدادی میخوام که کسی برای کنترلش این متد را فراخونی میکنه ، اون رویداد را فراخونی کنیم . البته احتمالا بشه در اینجا یه چیزایی در این باره پیدا کرد
شاد باشی
آرمین
آخرین ویرایش توسط ravegoat در تاریخ 24-07-19 انجام شده است علت: نگارشی
'چو ایران نباشد، تن من مباد
Dim Armin As Iranian
If Iran.Enabled = False Then Armin.Enabled = False
AMD>INTEL (27-07-19), M A H R A D (27-07-19), SajjadKhati (24-07-19), Speed Racer (22-08-19)
برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط ravegoat برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
خیلی ممنون
تقدم و تاخر اش را میدونم . ولی دلیل اش نسبت به کد خودم را متوجه نمیشم . نمیدونم چطور میشه که اون کد را توی متد سازنده که مینویسم ، اون پروپرتی BackgroundControls ام برای شی transparentControl (در اون کد) ، null میشه اما اون کد رو توی رویداد Load (که با تاخیر نسبت به متد سازنده اجرا میشه) که میذارم ، مشکلی نداره.
فرقی نداره پروژه ی sln را بدم یا نه . کلا کدش همون قدر به اضافه ی اون کلاس کنترل هست که پیوست کردم.
----------------------------------------------
الان یه مشکل دیگه داره . یه تغییراتی در این کلاس دادم که در زیر لینک دانلودش را میذارم :
دانلود فایل پیوست TransparentControl
با با اونکه پروپرتی BackgroundControls (شامل تمامی کنترل هایی که زیر کنترل جاری هست) را اول invalidate میکنم و بعد کنترل جاری را invalidate میکنم و بعد پروپرتی ForegroundControls (شامل تمامی کنترل هایی که جلوی کنترل جاری هست) را invalidate میکنم ، ولی برعکس رسم میکنه . یعنی کنترل های BackgroundControls را سر آخر رسم میکنه که باعث میشه جلو بیان .
در رویداد Load فرم هم همون کد پست اول را لطفا بنویسید (بجای مسیر فایل ها ، یه فایل png ای که بخشی اش transparent باشه ، بدید یا بیت مپی بدید که بخشی اش transparent باشه . اندازه ی بیت مپ هاتون جوری باشه که در کد زیر ، بخشی از هر دو شی از کنترل های transparentControl و transparentControl_2 روی هم بیفتن . در مثال زیر ، اندازه های شی بیت مپ ، 24 در 24 هستن ) :
هسته ی مرکزی کدهای کنترل کلاس TransparentControl که به این بخش مربوط میشه ، رویداد AllParents_Invalidated هست.کد:private TransparentControl transparentControl; private TransparentControl transparentControl_2; private void Form1_Load(object sender, EventArgs e) { Bitmap bitmap = new Bitmap(@"E:\Project\Visual Studio\C#.Net\Saved Project\0 Important Project\Poshtibangir Tolo\PoshtibangirTolo\bin\Debug\Icon\PanelToolBar\Close\Close.png"); bitmap = TransparentControlBitmap.SetColor(bitmap, Color.Red); TransparentControlBitmap controlBitmap = new TransparentControlBitmap(bitmap, new Bitmap(bitmap.Width, bitmap.Height), new Bitmap(bitmap.Width, bitmap.Height), new Bitmap(bitmap.Width, bitmap.Height)); controlBitmap.GraphicInterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; controlBitmap.SetColor(bitmap, ExportBitmapFor.MouseEnterBitmap, Color.DeepSkyBlue); controlBitmap.SetColor(bitmap, ExportBitmapFor.MouseDownBitmap, Color.Blue); controlBitmap.SetColor(bitmap, ExportBitmapFor.ControlDisabledBitmap, Color.Yellow); this.transparentControl = new TransparentControl(controlBitmap, new Point(200, 10)); this.transparentControl.Name = "Close"; this.transparentControl.MouseClick += new MouseEventHandler(this.TransparentControl_MouseClick); Bitmap bitmap_2 = new Bitmap(@"E:\Project\Visual Studio\C#.Net\Saved Project\0 Important Project\Poshtibangir Tolo\PoshtibangirTolo\bin\Debug\Icon\PanelToolBar\Setting\Setting.png"); TransparentControlBitmap controlBitmap_2 = new TransparentControlBitmap(bitmap_2); controlBitmap_2.MouseEnterBitmap = TransparentControlBitmap.SetColor(bitmap_2, Color.DeepSkyBlue); controlBitmap_2.MouseDownBitmap = TransparentControlBitmap.SetColor(bitmap_2, Color.Blue); controlBitmap_2.ControlDisabledBitmap = TransparentControlBitmap.SetColor(bitmap_2, Color.Yellow); this.transparentControl_2 = new TransparentControl(controlBitmap_2, new Point(210, 20)); this.transparentControl_2.Name = "Setting"; this.transparentControl_2.MouseClick += new MouseEventHandler(this.TransparentControl_MouseClick); this.Controls.Add(transparentControl); this.Controls.Add(transparentControl_2); }
چرا این جوری هه؟
من که به ترتیب invalidate میکنم ولی این چرا BackgroundControls را سر آخر رسم میکنه؟
برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط ravegoat برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
خیلی ممنون
آخرین ویرایش توسط SajjadKhati در تاریخ 24-07-19 انجام شده است
دانلود فیلم آموزش برنامه نویسی Visual Studio C#.Net
فیلم آموزش کامل Autoplay Media Studio
وقتی انسان ، حیوان هست ، پس قیمت میتونی براش بذاری ولی وقتی انسان حَیّ مُتِاَلِّه هست که قیمت نداره ، بها داره. "دکتر حسن عباسی"
Speed Racer (22-08-19)
الان متوجه سوال اولت شدم:
این مورد رو خیلی دقیق نمی دونم ولی وقتی فرم ساخته میشه الزاما نشون داده نمیشه ولی وقتی رویداد لود فرخوانی میشه حتما فرم به نمایش در اومده. وقتی تو کد مربوطه رو در constructor میذاری، اشاره گر مربوط به پنجره (handleNextControl) در کد زیر نا معتبره چون اصلا پنجره ای وجود نداره. پنجره زمانی معنا داره که فرم به نمایش در بیاد. در نتیجه در کد زیر مقدار false بر میگیرده و پیرو اون، خاصیت BackgroundControls مقدار دهی نمیشه:
اگر دقیق ترش رو میخوای باید ببینی در لایه ی پایین تابع ویندوزی GetWindow چه اتفاقی میافته.کد:handleNextControl = TransparentControl.GetWindow(handleNextControl, searchStyle); if (handleNextControl == IntPtr.Zero) return false;
در مورد سوال دوم ت بازم باید بگم متوجه نشدم. وقتی invalidate می کنی، کنترل پاک نمیشه بلکه در رویداد paint بعدی فرم، دوباره رسم میشه! اینکه میگی من invalidate می کنم ولی سر آخر رسم میشه اصلا برام واضح نیست. مگه invalidate کنی نباید رسم بشه؟! لطفا بیش تر شرح بده احتمالا بد متوجه شدم.
شاد باشی
آرمینبرای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
'چو ایران نباشد، تن من مباد
Dim Armin As Iranian
If Iran.Enabled = False Then Armin.Enabled = False
AMD>INTEL (27-07-19), M A H R A D (27-07-19), SajjadKhati (24-07-19), Speed Racer (22-08-19)
برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط ravegoat برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
خیلی ممنون استاد آرمین.
بله .
من فکر میکردم توی متد سازنده که کنترل مونو به کنترل کانتینری اضافه میکنیم ، پنجره تشکیل میشه.
نمیدونم برای کنترل های عادی دات نت مثل button و ... پس چجوری این قضیه ی رسم کنترل های زیرین و جلویی را پس مدیریت میکنن که توی متد سازنده هم ازشون شی بسازی ، مشکل مدیریت رسم کنترل های جلو و عقب شون را ندارن.
-----------------------------------
نگفتم invalidate کنیم ، پاک میشه . میدونم invalidate میکنیم ، رسم رایج را نامعتبر میکنه و باعث میشه رویداد paint اون کنترل ، (نه الزاما همون لحظه) اجرا بشه.
کد داخل تابع AllParents_Invalidated را لطفا ببینید.
نگفتم invalidate می کنم ولی سر آخر رسم میشه .
2 تا شی کنترل TransparentControl را پشت و جلوی هم میذارم (کد پست اول یا پنجم)
گفتم داخل اون تابع ، 3 تا کنترل را invalidate میکنم . اول ، تمامی کنترل های موجود در آرایه ی BackgroundControls (که شامل کنترل هایی هست که در پشت کنترل جاری TransparentControl مون هست)، بعدش کنترلِ جاری TransparentControl و بعدش مامی کنترل های موجود در آرایه ی ForegroundControls (که شامل کنترل هایی هست که در جلویِ کنترل جاری TransparentControl مون هست) را invalidate میکنم.
بریک پوینت که میذارم ، همه ی این موارد ، به همین ترتیب اجرا و invalidate میشن اما سر آخر علاوه بر این ترتیب 3 تایی که درست اجرا شدن ، دوباره اون کنترل های پروپرتی BackgroundControls مجددا رسم میشن که رسم مجدد اینها باعث میشه کنترل های پشتی ، به عنوان کنترل جلویی نمایش داده بشن . کد پست 5 را اجرا کنید ، مشخص هه.
نمیدونم این رسم آخریِ کنترل های پروپرتی BackgroundControls ، از کجا نشات میگیره.
آخرین ویرایش توسط SajjadKhati در تاریخ 24-07-19 انجام شده است
دانلود فیلم آموزش برنامه نویسی Visual Studio C#.Net
فیلم آموزش کامل Autoplay Media Studio
وقتی انسان ، حیوان هست ، پس قیمت میتونی براش بذاری ولی وقتی انسان حَیّ مُتِاَلِّه هست که قیمت نداره ، بها داره. "دکتر حسن عباسی"
Speed Racer (22-08-19)
خواهش می کنم سجاد جان،برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید ارسالی توسط SajjadKhati برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
البته بازم میگم بنده استاد نیستم...
احتمالا وقتی در دات نت constructor به خط آخرش میرسه، CLR توابع گرافیکی رو اجرا می کنه که پنجره رسم بشه و بعد از اونه که ویندوز فرم رو به عنوان یه پنجره میشناسه. در سطح سی شارپ ما به دستورات بین آخرین خط Constructor و اولین خط رویداد Form_Load دسترسی نداریم ولی این قضیه تداخلی با مدیریت ترسیم کنترل ها روی فرم نداره. هر کنترلی داخل container یه z-order داره و هر container ی داخل فرم هم یک z-order مختص به خودش رو داره. ترتیب پیش فرض در z-order به ترتیب اضافه شدن اون کنترل داخل container بر می گرده. اگر نگاهی به تابع InitializeComponent در یه فرم بندازیم، کنترل ها به ترتیبی رسم میشن که داخل InitializeComponent به فرم اضافه شدن. به عبارتی پس از InitializeComponent، توابع JIT به هر کنترل یه z-order تخصیص میدن و در نهایت CLR به کارت گرافیک هندسه ی ترسیم رو ارسال می کنه.
-----------------------------------
سوال دوم ت رو هم الان متوجه شدم. وقتی یه کنترل رو invalid کنیم، تا زمانی که فرم idle نشه، اون کنترل paint نمیشه. حالا این که فرم کی idle میشه رو نمی دونم ولی اینجا فعلا اهمیتی نداره. ولی نکته اینه که اگر دو تا کنترل رو به ترتیب invalid کنیم، الزاما در زمان idle بودن فرم به همون ترتیب رسم نمیشن! در کدی که قرار دادی، transparetControl_2 اول و بعدش transparetControl1 نا معتبر میشه که درسته. ولی در ادامه اول transparetControl1 و بعدش transparetControl_2 رسم میشه. اگر بخوای بلافاصله یه کنترل رو رسم کنی می تونی از دستورات Update و Refresh استفاده کنی ولی شاید باز هم به هدف ت نرسی. اگر هدف اینه وقتی کاربر روی کنترل پشتی با اشاره گر ماوس وایستاد، اون کنترل بیاد جلو، فکر کنم در کد اولی که گذاشته بودی این اتفاق می افتاد. یه جورایی واسم گنگه که دقیقا میخوای چیکار کنی چون متوجه نشدم چرا یه نسخه ی جدید تر از کد اول قرار دادی! مشکل کد اول چی بوده؟!
شاد باشی
آرمین برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
'چو ایران نباشد، تن من مباد
Dim Armin As Iranian
If Iran.Enabled = False Then Armin.Enabled = False
AMD>INTEL (27-07-19), M A H R A D (27-07-19), SajjadKhati (25-07-19), Speed Racer (22-08-19)
خیلی ممنون استاد آرمین.
نکته ی مهم اینه که وقتی کنترلی را Invalidate میکنیم ، زمانی اجرا میشه که پیام (رویداد و هر کدی) توی صف برای پردازش نباشه. اگه باشه ، اول اونا را اجرا میکنه و بعد نوبت به Invalidate اون کنترل میرسه (که اول اون کنترل را ، نامعتبر ، و بعد رسم اش میکنه) . پس اشکال کار من توی این سه خط ، در تابع AllParents_Invalidated بود :
پس باید هر کدوم از این خط ها که میخواد اجرا بشه (و Invalidate کنترل مورد نظر را در پی داره) ، باید زمانی اجرا بشه که مطمئن بشیم اون خط قبلی ، رسم اش تمام شد (نه صرفا با فراخونی Invalidate ، رسم میشه همونطور که قبلا توضیح دادین) و بعد خط بعدی شو اجرا کنیم.کد:if (this.Equals(TransparentControl.TranspControlEventDoingFlag) == true) { this.InvalidateForeOrBackgroundControls(this.BackgroundControls, this.BackgroundControlInvalidateRegiones); this.Invalidate(); this.InvalidateForeOrBackgroundControls(this.ForegroundControls, this.ForeGroundControlInvalidateRegiones); }
این 3 خط را این طور ویرایش کردم که خط اول را همونجا گذاشتم باشه . بعدش تایمری را استارت کردم و خط دوم (this.Invalidate) را توی تایمر گذاشتم باشه (چون اگه اشتباه نکنم ، تایمر هم مثل Invalidate ، زمانی اجرا میشه که پیام (رویداد و هر کدی) توی صف برای پردازش نباشه. پس در این صورت ، مطمئنیم که اول ، خط اول ، رسم اش تمام شد و بعد نوبت تایمر مون میرسه .
اما خط سوم را دیگه نمیشه توی تایمر گذاشت چون دو تایمر ممکنه زمان اجراشون (طی مدت زمانی که میگذره یا به هر دلیل دیگه) ، تداخل پیدا کنن . بنابراین کد سوم را توی متد OnPaint (بعد از کدهای رسم مربوط به کنترل TransparentControl ، میذاریم) و حالا مطمئن هستیم که بعد از رسم کنترل TransparentControl ، عملیات Invalidate مربوط به کنترل های جلویی انجام میشه.
این کار (کد بالا که آخرین تغییرات کلاسش را در زیر هم پیوست میکنم) را انجام دادم . در این صورت (با این تغییراتی که گفتم) ، اگه دو کنترلِ TransparentControl را جلو و عقب هم بذاریم ، جواب میده و کنترل های جلو و عقب ، درست رسم میشه (البته بجز یه اشکال کوچیک که اگه اول ، موس را روی کنترل پشتی ببریم (موس را دیگه از اون کنترل ، خارج نکنیم) و از همونجا ، موس را روی کنترلِ جلویی ببریم ، ترتیب رسم ، باز به هم میریزه که با خارج کردن موس از همین کنترلِ جلویی ، دوباره درست میشه . حالت های دیگه ، مشکل خاصی انگار نبود) .
اما در حالتی که پشت کنترلِ TransparentControl مون ، یه کنترل دیگه مثل Button باشه ، با اونکه کنترل TransparentControl مون جلو هست ، ولی پشت اش رسم میشه.
برای تست این قضیه ، کد زیر را در رویداد Form_Load بنویسین (همونطور که میدونین ، بجای مسیر فایل ها ، یه فایل png ای که بخشی اش transparent باشه ، بدید یا بیت مپی بدید که بخشی اش transparent باشه . اندازه ی بیت مپ هاتون جوری باشه که در کد زیر ، بخشی از هر دو شی از کنترل های transparentControl و button روی هم بیفتن . در مثال زیر ، اندازه های شی بیت مپ ، 24 در 24 هستن) :
الان این مشکل از کجاست که با اونکه شی transparentControl ، در جلوی کنترل button قرار داره (وقتی موس را روی کنترل transparentControl میبریم) ، اما جلوش رسم نمیشه؟کد:private TransparentControl transparentControl; private void Form1_Load(object sender, EventArgs e) { Bitmap bitmap = new Bitmap(@"E:\Project\Visual Studio\C#.Net\Saved Project\0 Important Project\Poshtibangir Tolo\PoshtibangirTolo\bin\Debug\Icon\PanelToolBar\Close\Close.png"); bitmap = TransparentControlBitmap.SetColor(bitmap, Color.Red); TransparentControlBitmap controlBitmap = new TransparentControlBitmap(bitmap, new Bitmap(bitmap.Width, bitmap.Height), new Bitmap(bitmap.Width, bitmap.Height), new Bitmap(bitmap.Width, bitmap.Height)); controlBitmap.GraphicInterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High; controlBitmap.SetColor(bitmap, ExportBitmapFor.MouseEnterBitmap, Color.DeepSkyBlue); controlBitmap.SetColor(bitmap, ExportBitmapFor.MouseDownBitmap, Color.Blue); controlBitmap.SetColor(bitmap, ExportBitmapFor.ControlDisabledBitmap, Color.Yellow); this.transparentControl = new TransparentControl(controlBitmap, new Point(200, 10)); this.transparentControl.Text = "Close"; this.Controls.Add(transparentControl); Button button = new Button() { BackColor = Color.GreenYellow, Bounds = new Rectangle(210, 20, 80, 35), Text = "Back Button", Parent = this }; button.BringToFront(); }
فایل پیوستی شامل آخرین تغییرات را هم بی زحمت از اینجا دانلود کنید.
خیلی ممنون برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
دانلود فیلم آموزش برنامه نویسی Visual Studio C#.Net
فیلم آموزش کامل Autoplay Media Studio
وقتی انسان ، حیوان هست ، پس قیمت میتونی براش بذاری ولی وقتی انسان حَیّ مُتِاَلِّه هست که قیمت نداره ، بها داره. "دکتر حسن عباسی"
ravegoat (29-07-19), Speed Racer (22-08-19)
سلامی مجدد
چقدر پارانویید میزنم برای مشاهده این لینک/عکس می بایست عضو شوید ! برای عضویت اینجا کلیک کنید
کد (در پست بالا) مشکلی نداره .
بخاطر اینکه در خط آخر ، اونو جلو آوردم ( کد button.BringToFront ) ، بود . حواسم نبود .
خیلی ممنون
دانلود فیلم آموزش برنامه نویسی Visual Studio C#.Net
فیلم آموزش کامل Autoplay Media Studio
وقتی انسان ، حیوان هست ، پس قیمت میتونی براش بذاری ولی وقتی انسان حَیّ مُتِاَلِّه هست که قیمت نداره ، بها داره. "دکتر حسن عباسی"
ravegoat (29-07-19), Speed Racer (22-08-19)
1 کاربر در حال مشاهده این موضوع. (0 عضو و 1 میهمان)
Bookmarks