PDA

View Full Version : مشکل این کلاس کنترل چیه؟



SajjadKhati
سه شنبه 01 مرداد 1398, 13:46 عصر
سلام
یه کنترلی بنام TransparentControl را دارم میسازم (قبلا ساختم اما الان قابلیت های جدیدی دارم بهش اضافه میکنم)
توی نسخه ی قبل این جوری بود که اگه در سطح کنترل های خواهر و برادر این کنترل ، کنترلی به پشت این کنترل میرفت ، کاربر باید اون کنترل را میداد تا این کلاس ، قبل از رسم خودش ، اون کنترل را اول رسم کنه. این کلاس را در زیر پیوست میکنم
دارم این قابلیت را اضافه میکنم که نیازی نباشه که کاربر بخواد کنترل های پشت و کنترل های جلویِ (در سطح کنترل خواهر و برادری) کنترل TransparentControl را بهش بده و این کار را میخوام خود همین کنترل انجام بده . اما مشکلی داره که در زیر میگم .(هنوز بعضی از اعضاش کار نمیکنه و تموم نشد . فعلا از متد سازنده ای که کدش رو میذارم ، لطفا چک کنید) .
در متد سازنده ی فرم تون ، این را بنویسید لطفا (بجای مسیر فایل png ، که میدونین هر فایل مورد نظر خودتون که خواستین را بدین . فقط اندازه اش جوری باشه که دو کنترل در کد زیر ، نصف شون یا قسمتی ازشون ، روی همدیگه بیفتن) :



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_MouseCli ck);


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_MouseCli ck);


this.Controls.Add(transparentControl);
this.Controls.Add(transparentControl_2);
}

نکته ی عجیب برای من اینه که وقتی روی همین کد بالا (مخصوصا در خط this.Controls.Add(transparentControl) و همینطور در قسمت get و همینطور set برای پروپرتی BackgroundControls در کلاس زیر که پیوست کردم ، علامت breakpoint را میذارم و اگه بریک پوینت را همه را با دکمه ی F11 بزنم بره جلو ، پروپرتی BackgroundControls ، در شی transparentControl ، مقدار میگیره (اولین عضو از مقدارش برابر با شی transparentControl_2 میشه) که منم همین رو میخوام و درسته . اما هر دفعه بریک پوینت را با دکمه ی F10 بزنم بره جلو یا اصلا بریک پوینتی نذارم، با کمال تعجب میبینم که این پروپرتی (پروپرتی BackgroundControls ، در شی transparentControl) ، اون مقداری که قبلا گرفت را نداره و null میشه !!
چرا این دو اتفاق میافته؟
بسیار تعجب آوره !!



بعد اینکه میشه وقتی کسی کنترلی را 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 را اون موقع ، فراخونی کنم.
مشکلات دیگه ای هم شاید داشته باشه (فعلا نمیدونم).
خیلی ممنون

SajjadKhati
سه شنبه 01 مرداد 1398, 22:10 عصر
سلام
تقریبا جواب گرفتم.

ROSTAM2
چهارشنبه 02 مرداد 1398, 08:08 صبح
با سلام. ینی چی؟ من که نفهمیدم چی شد! تا حالا با کنترل flowlayoutpanel کار کردی ؟ هر کدوم از اشیاء رو که hide کنی غیب میشه و هرکدوم و که show کنی نمایان می شه در ابتدای کنترل اصلی!

SajjadKhati
پنج شنبه 03 مرداد 1398, 14:34 عصر
سلام
ممنون
کاری با کنترل FlowLayoutPane ندارم.

-------------------------------------------

یه کم درباره ی رویداد Invalidated و Paint (اینکه هر کدوم چند بار و دقیقا چه زمانی اجرا میشن) ، توضیح میدین؟
آیا رویداد Invalidated ، مثلا 100 بار هم که پشت سر هم متد Control.Invalidate را صداش کنیم ، فقط یکبار رویدادش اجرا میشه؟
اگه این طوره ، پس برای دفعه ی بعدی ، چه زمانی متد Control.Invalidate را صدا کنیم ، برای بار بعدی هم رویداد Invalidated اجرا میشه؟ (متوجه ی منظورم شدید؟)
چرا تعداد اجرای رویداد Invalidated و Paint با هم فرق دارن؟ آخه مگه نباید هر بار متد Control.Invalidate را فراخونی میکنیم ، به همون تعدادی که فراخونی میکنیم ، رسم (Paint فراخونی بشه) انجام بده ؟ چرا رویداد Paint اکثر اوقات دو یا چند بار اتفاق میافته؟ در این صورت (که دو یا چند بار اتفاق میافته) و ما فقط یکبار متد Control.Invalidate را فراخوانی کرده بودیم ، بقیه ی بارها ، کدوم متد باعث شد که این رویداد Paint اجرا بشه؟

خیلی ممنون

SajjadKhati
پنج شنبه 31 مرداد 1398, 20:14 عصر
سلامی مجدد
آخرین تغییراتی که دادم را فایل این کلاس را در زیر میذارم.
الان مشکلش اینه که وقتی پروپرتی TextAutoSize از کلاس TransparentControl را تغییر میدم ، متن ای که رسم میکنه ، وقتی موس را روی این کنترل میبریم ، ضخیم رسم میکنه . دلیل شو گشتم ، ولی پیدا نکردم . کسی میدونه راهنمایی کنه؟

الان این کد زیر ، اشکالی که در بالا توضیح دادم را نمایان میکنه (اول روی دکمه ی AutoSize ، کلیک راست کنید و به متن کنترل TransparentControl هم دقت کنید که خواهید دید کمی ضخیم تر میشه . اگه فرم را مینیمایز و بعد به حالت اولیه اش برگردونید ، متن ، نازک میشه. اگه دوباره این کاری که گفتم را انجام بدین یا موس را روی کنترل ببرید ، متن ، ضخیم تر میشه) :



private void Form1_Load(object sender, EventArgs e)
{
Button btnAutoSize = new Button { Bounds = new Rectangle(10, 10, 100, 35), Parent = this, Text = "AutoSize", BackColor = Color.WhiteSmoke };
btnAutoSize.MouseUp += new MouseEventHandler(this.Button3_MouseUp);




TransparentControlText text = new TransparentControlText("salam");
this.transparentControl = new TransparentControl(text, new Rectangle(new Point(100, 200), new Size(250, 100)), false);
this.Controls.Add(this.transparentControl);
}




private void Button3_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
this.transparentControl.TextAutoSize = false;
else if (e.Button == MouseButtons.Right)
this.transparentControl.TextAutoSize = true;
}



دانلود آخرین تغییرات فایل TransparentControl :

https://8pic.ir/uploads/TransparentControl_bc65d.rar

با تشکر

SajjadKhati
جمعه 01 شهریور 1398, 10:18 صبح
سلامی مجدد
انگار حدودا ، بهتر پیدا کردم که مشکل از کجاست (اما هنوز دقیق متوجه نشدم) .
مشکل انگار از کدهای تغییر سایز در TransparentControl هست . ربطی به TransparentControlText نداره.
مثلا کدهای زیر ، مشکلی ندارن (این کد ، رویداد Button3_MouseUp در کد بالاست که تغییر کرده) (برای آپدیت و رسم ، بعد از کلیک روی دکمه ، موس را روی کنترل TransparentControl ببرید) :




private void Button3_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
this.transparentControl.TransparentControlText.Tex t = "salam";
else if (e.Button == MouseButtons.Right)
this.transparentControl.TransparentControlText.Tex t = "khobi?";
}


یا



private void Button3_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
this.transparentControl.TransparentControlText.Tex tFont = this.Font;
else if (e.Button == MouseButtons.Right)
this.transparentControl.TransparentControlText.Tex t = "khobi?";
}

اما این کد مشکل داره :



private void Button3_MouseUp(object sender, MouseEventArgs e)
{
if (e.Button == MouseButtons.Left)
this.transparentControl.Size = new Size(250, 100);
else if (e.Button == MouseButtons.Right)
this.transparentControl.Size = new Size(180, 70);
}

حالا داخل کلاس TransparentControlText مشکل خودش را نشون میده چون داخل رویداد TransparentControl_TextAutoSizeChanged ، کدِ this.TransparentControl.Size = fontSize.ToSize() را بکار بردم.