PDA

View Full Version : ساخت کادر و نوشتن متن در آن با رویداد paint فرم



arastoahmadi
سه شنبه 30 اردیبهشت 1399, 09:24 صبح
با سلام دوستان من میخام با رویداد paint فرم یه کادر مستطیلی طراحی کنم و داخل فرمم یه تکست باکس بزارم و کاربر زمانی که داخل تکست باکس متنی رو تایپ میکنه اندازه کادر طراحی شده براساس طول ، سایز و قالب بندی رشته تغییر پیداکند و متن داخل باکس نمایش داده شود دوستان ممنون میشم راهنمایی بفرمایید

the king
سه شنبه 30 اردیبهشت 1399, 13:34 عصر
با سلام دوستان من میخام با رویداد paint فرم یه کادر مستطیلی طراحی کنم و داخل فرمم یه تکست باکس بزارم و کاربر زمانی که داخل تکست باکس متنی رو تایپ میکنه اندازه کادر طراحی شده براساس طول ، سایز و قالب بندی رشته تغییر پیداکند و متن داخل باکس نمایش داده شود دوستان ممنون میشم راهنمایی بفرمایید

با Graphics.MeasureString و TextRenderer.MeasureText ابعاد متن رو محاسبه می کنند. یک وقت هست که طول کادر ثابت ئه و باید صرفا ارتفاع کادر متغیر باشه و محاسبه بشه.
151702
در اینصورت اگر طول سطر طولانی باشه باید شکسته بشه به سطر های بعد :
151703
اما یک وقت هست که طول و عرض هر دو متغیر ئه و هر دو باید محاسبه بشه :
151704

151705

arastoahmadi
سه شنبه 30 اردیبهشت 1399, 15:11 عصر
ممنون از پاسختون دوست گرامی حالا من میخام یه کار دیگه ای انجام بدم و اونم اینه که اگه حالت FixedWidth رو انتخاب کردم در این صورت ظولش تغییر میکنه و اگه متنم طولانی بشه چون اندازه فرممم هیچ تغییری نمیکنه مابقی متنو نمیتونم ببینم در این حالت باید چکار کرد . بعد اگه بخام به جای مستطیل یه کادر بالونی بزارم باید چکار کنم

the king
سه شنبه 30 اردیبهشت 1399, 15:47 عصر
ممنون از پاسختون دوست گرامی حالا من میخام یه کار دیگه ای انجام بدم و اونم اینه که اگه حالت FixedWidth رو انتخاب کردم در این صورت ظولش تغییر میکنه و اگه متنم طولانی بشه چون اندازه فرممم هیچ تغییری نمیکنه مابقی متنو نمیتونم ببینم در این حالت باید چکار کرد . بعد اگه بخام به جای مستطیل یه کادر بالونی بزارم باید چکار کنم

اگه طول کادر ثابت نباشه، ممکنه اونقدر متنی طولانی بشه که رسم از فرم بزنه بیرون و باقیش دیده نشه، پس یا باید متن در رسم Word Wrap بشه و بقیه نوشته شکسته بشه در سطر های بعدی و یا رسم طولانی بمونه اما با اضافه کردن ScrollBar اجازه Scroll شدنش رو بدید.
هر چیز دیگری هم که بخواهید پشت متن رسم کنید فقط باید قبل از رسم متن انجام بشه، می توانید قبل از رسم متن هر چیزی رسم کنید و در انتها متن رو رویش رسم کنید.
151706
151707

arastoahmadi
سه شنبه 30 اردیبهشت 1399, 16:13 عصر
ممنون از پاسختون دوست عزیز ، من یه گرید ویو تو فرمم دارم میخام یه چیزی شبیه این بشه ولی متاسفانه تو این زمینه من اطلاعاتی ندارم


151711

the king
سه شنبه 30 اردیبهشت 1399, 16:14 عصر
رجوع شود به :
151708
نقل قول: فرمی به شکل فایر فاکس (https://barnamenevis.org/showthread.php?357204-%D9%81%D8%B1%D9%85%DB%8C-%D8%A8%D9%87-%D8%B4%DA%A9%D9%84-%D9%81%D8%A7%DB%8C%D8%B1-%D9%81%D8%A7%DA%A9%D8%B3&p=1575585&viewfull=1#post1575585)
و
151710
tooltip متحرک در کنار موس (https://barnamenevis.org/showthread.php?384309-tooltip-%D9%85%D8%AA%D8%AD%D8%B1%DA%A9-%D8%AF%D8%B1-%DA%A9%D9%86%D8%A7%D8%B1-%D9%85%D9%88%D8%B3&p=1701927&viewfull=1#post1701927)

the king
سه شنبه 30 اردیبهشت 1399, 16:27 عصر
ممنون از پاسختون دوست عزیز ، من یه گرید ویو تو فرمم دارم میخام یه چیزی شبیه این بشه ولی متاسفانه تو این زمینه من اطلاعاتی ندارم


151711


طبعا برای یادگیری پیاده سازی هر چیزی باید بصورت جزء به جزء پیش برید، یکدفعه از DataGridView به ChatBox نمیشه رسید.
DataGridView برای این منظور چندان مناسب نیست، ListBox بهتره،
ListBox یک مشخصه DrawMode داره که در حالت OwnerDrawFixed رسم اش رو خودتون انجام می دهید ولی ارتفاع آیتم ها یکسان ئه و در حالت DrawMode ئه OwnerDrawVariable رسم رو خودتون انجام می دهید و ارتفاع هر آیتم متفاوت ئه (مثل همین مثال چت).
ListBox یک رخداد MeasureItem داره که در حالت OwnerDrawVariable از برنامه نویس میپرسه که عرض این آیتم فلان باید چقدر باشه و اونجا ابعاد رو بر حسب محتویاتش محاسبه می کنید.

arastoahmadi
سه شنبه 30 اردیبهشت 1399, 16:42 عصر
بازم ممنون از پاسختون عزیز ، دوست گرامی مثال از این لیست باکس دارید ؟

the king
سه شنبه 30 اردیبهشت 1399, 17:41 عصر
بازم ممنون از پاسختون عزیز ، دوست گرامی مثال از این لیست باکس دارید ؟

روال کار خیلی مشخص ئه، در DrawItem اون آیتمی که ListBox میخواد الان نشون بده رو در جایی که ListBox بهمون میگه رسم می کنیم و در MeasureItem ابعاد آیتمی که ListBox میخواد ابعادش رو بدونه مشخص می کنیم.

private void button1_Click(object sender, EventArgs e)
{
listBox1.Items.Add(new object[] { textBox1.Text, DateTime.Now });
textBox1.Text = "";
textBox1.Focus();
}

private void listBox1_DrawItem(object sender, DrawItemEventArgs e)
{
if ((e.Index < 0) || (e.Index >= listBox1.Items.Count))
{
return;
}
var item = (object[])listBox1.Items[e.Index];
var text = (string)item[0];
var date = (DateTime)item[1];
var format = new StringFormat (StringFormat.GenericDefault);
format.FormatFlags |= StringFormatFlags.NoClip | StringFormatFlags.DirectionRightToLeft;
format.Trimming = StringTrimming.None;
var size = Size.Round( e.Graphics.MeasureString (text, listBox1.Font, listBox1.ClientSize.Width - 20, format));
size.Width = Math.Max(30, size.Width);
var rect = new Rectangle(e.Bounds.Right - size.Width - 20, e.Bounds.Top, size.Width + 18, size.Height + 20);
var renderer = new VisualStyleRenderer (VisualStyleElement.ToolTip.Balloon.Normal);
renderer.DrawBackground(e.Graphics, rect);
rect.Inflate(-5, -5);
e.Graphics.DrawString(text, listBox1.Font, Brushes.Black, rect, format);
format.LineAlignment = StringAlignment.Far;
rect.Offset(0, 3);
using (var font = new Font(listBox1.Font.FontFamily, listBox1.Font.SizeInPoints - 2f))
{
e.Graphics.DrawString(date.ToString("HH:mm"), font, Brushes.Gray, rect, format);
}
}

private void listBox1_MeasureItem(object sender, MeasureItemEventArgs e)
{
var item = (object[]) listBox1.Items[e.Index];
var text = (string)item[0];
var date = (DateTime)item[1];
var format = new StringFormat( StringFormat.GenericDefault);
format.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
format.Trimming = StringTrimming.None;
var size = Size.Round(e.Graphics.MeasureString (text, listBox1.Font, listBox1.ClientSize.Width - 20, format));
e.ItemHeight = size.Height + 22;
}


151712

151713

arastoahmadi
چهارشنبه 31 اردیبهشت 1399, 08:53 صبح
سلام سپاس بی کران از شما دوست عزیز آیا کلاس VisualStyleRendere ماهیتش نمایش آیتم های لیست ویو در قالب کنترل های پیش فرض ویژوال استودیو هستش یا علاوه بر نمایش میتونیم از کنتزل ها مثل خود کنترل های ویژوال استودیو استفاده کنیم آیا اینجام هم میتونیم اینکارو بکنیم

the king
چهارشنبه 31 اردیبهشت 1399, 11:24 صبح
سلام سپاس بی کران از شما دوست عزیز آیا کلاس VisualStyleRendere ماهیتش نمایش آیتم های لیست ویو در قالب کنترل های پیش فرض ویژوال استودیو هستش یا علاوه بر نمایش میتونیم از کنتزل ها مثل خود کنترل های ویژوال استودیو استفاده کنیم آیا اینجام هم میتونیم اینکارو بکنیم
VisualStyleRenderer به ویژوال استدیو کاری نداره، برای یک کنترل خاص هم نیست، هر چی کنترل استاندارد در Visual Styles ویندوز تعریف شده رو میتونه رسم کنه.

ویندوز یک سیستم واسط کاربر گرافیکی داره به اسم Windows Visual Styles که همه کنترل ها با یک Theme نمایش داده میشن و تا یک Theme جدید برایش انتخاب می کنید ظاهر همه کنترل ها در ویندوز عوض میشه. این VisualStyleRenderer موتور رسم همون Visual Styles ئه، با همون Theme ای که کنترل های استاندارد رسم میشن برای شما هم چیزی رو که میخواهید رسم می کنه. برای برنامه نویسی بدرد میخوره که میخواد یک کنترل اختصاصی دست ساز خودش رو با ظاهر یک کنترل استاندارد رسم کنه.
مثلا بهش میگید در فلان موقعیت یک ScrollBar رو رسم کن، ظاهر یک Button فشرده شده رو رسم کن، کادر دور یک TextBox رو رسم کن، دکمه Close یک پنجره رو رسم کن و ...
VisualStyleRenderer هر بخشی از کنترل های استاندارد ویندوز (که در Theme ویندوز تعریف شده) رو میتونه در بخشی از یک رسم نمایش بده.
بهتون این امکان رو میده که یک کنترل اختصاصی رو با ظاهر شبیه به Theme ویندوز رسم کنید، طوری که با ظاهر بقیه کنترل ها هماهنگ باشه.

arastoahmadi
چهارشنبه 31 اردیبهشت 1399, 12:57 عصر
دوست عزیز همه چی بسیار عالی بود ما برای گرفتن اندازه طول رشته مون از MessureString استفاده می کنیم حالا اگه بخایم هم متن و هم عکسرو با هم بفرستیم باید چکار کنیم چون من تو تمام متدها گشتم برای گرفتن اندازه عکس متدی مثله MessureString وجود ندارد ممنون میشم یه راهنمایی بفرمایید

the king
چهارشنبه 31 اردیبهشت 1399, 14:23 عصر
دوست عزیز همه چی بسیار عالی بود ما برای گرفتن اندازه طول رشته مون از MessureString استفاده می کنیم حالا اگه بخایم هم متن و هم عکسرو با هم بفرستیم باید چکار کنیم چون من تو تمام متدها گشتم برای گرفتن اندازه عکس متدی مثله MessureString وجود ندارد ممنون میشم یه راهنمایی بفرمایید
ابعاد تصویر مشخصه، دیگه Measure نمیخواد.
شیء عکس یا از نوع Image ئه یا Bitmap که Bitmap هم خودش یک نوع Image ئه.
Image هم Image.Size و Image.Width و Image.Height داره که معلوم می کنه ابعادش چیه.

arastoahmadi
جمعه 02 خرداد 1399, 17:53 عصر
ممنون از راهنماییتون دوست گرامی

فقط میخاستم بدونم اون قسمتی که متغییرهای text و Date رو تعریف میکنیم من اگه متغییر دیگه ای اضافه کنم مثلا متغییر Image موقع مقداردهی کردنش من شاید نخوام متغییر Image رو مقدار دهی کنم بنابراین اررور میگیره که شما باید حتما اون متغییر رو هم مقدار دهی کنید ممنون میشم یه راهنمایی کنید


151759

the king
جمعه 02 خرداد 1399, 20:28 عصر
ممنون از راهنماییتون دوست گرامی

فقط میخاستم بدونم اون قسمتی که متغییرهای text و Date رو تعریف میکنیم من اگه متغییر دیگه ای اضافه کنم مثلا متغییر Image موقع مقداردهی کردنش من شاید نخوام متغییر Image رو مقدار دهی کنم بنابراین اررور میگیره که شما باید حتما اون متغییر رو هم مقدار دهی کنید ممنون میشم یه راهنمایی کنید


151759



شرط قرار بدهید، مثلا اول بررسی کنید که item.Length چیه، که فرضا اگر 2 تا عضو داشت item.Length برابر 2 میشه. اگر سه تا عضو داشت می توانید عضو سوم (item[2]) رو که میتونه Image باشه بخونید و وگرنه سراع item[2] نروید چون اندیس 2 در آرایه 2 عضوی وجود نداره (فقط اندیس 0 و 1 رو داره)
در ضمن می توانید بررسی کنید که اون item[0] نوع اش چیه، که فرضا اگر string نبود صریحا cast به string نکنید، با as می توانید جلوی بروز خطا رو بگیرید. اگر نوع اش مطابقت نداشته باشه as بجای خطا مقدار null برمیگردونه.

var item = (object[])listBox1.Items[e.Index];
var text = item[0] as string;
var image = item[0] as Image;
var date = (DateTime)item[1];
if ((item.Length == 3) && (image == null))
{
image = item[2] as Image;
}
var format = new StringFormat(StringFormat.GenericDefault);

یا می توانید کد رو کلا طوری بنویسید که با هر ترتیبی از رشته و تاریخ و تصویر بشه بهش پارامتر ارسال کرد و مهم نباشه که فرضا اول تاریخ رو ارسال می کنید یا آخر یا وسط :

var item = (object[])listBox1.Items[e.Index];
string text = null;
DateTime date;
Image image = null;
foreach (var value in item)
{
if (value is string)
{
text = (string)value;
}
else if (value is DateTime)
{
date = (DateTime)value;
}
else if (value is Image)
{
image = (Image)value;
}
}
var format = new StringFormat(StringFormat.GenericDefault);

arastoahmadi
شنبه 03 خرداد 1399, 18:43 عصر
ممنون از پاسختون دوست گرامی راستی دوست عزیز زمانی که متن طولانی باشد از لیست باکس میزنه بیرون ممنون میشم اینم یه راهنمایی بکنید




151769

the king
شنبه 03 خرداد 1399, 19:29 عصر
ممنون از پاسختون دوست گرامی راستی دوست عزیز زمانی که متن طولانی باشد از لیست باکس میزنه بیرون ممنون میشم اینم یه راهنمایی بکنید




151769

کدتون ایراد داره، کدی که برای رسم نوشتید رو با کدی که من برای رسم نوشته بودم مقایسه کنید.

arastoahmadi
شنبه 03 خرداد 1399, 20:09 عصر
ChatBoxSample.rar (https://barnamenevis.org/attachment.php?attachmentid=151713&d=1589895663)
(https://barnamenevis.org/attachment.php?attachmentid=151713&d=1589895663)
دوست عزیز من این لینک رو دانلود کردم

یه نکته که باید خدمتتون عرض کنم اینه که تمامی متن بالا برای یه سطره

the king
شنبه 03 خرداد 1399, 22:38 عصر
ChatBoxSample.rar (https://barnamenevis.org/attachment.php?attachmentid=151713&d=1589895663)
(https://barnamenevis.org/attachment.php?attachmentid=151713&d=1589895663)
دوست عزیز من این لینک رو دانلود کردم

یه نکته که باید خدمتتون عرض کنم اینه که تمامی متن بالا برای یه سطره
یک سطر؟ اگر متن در کادر ListBox جا نشه طبعا بیرون میزنه و چون متن خیلی طولانی است ListBox نمیتونه آیتم با این ارتفاع رو مدیریت کنه.
هم حداکثر ارتفاع رو محدود کنید و هم متن های طولانی تر رو با ... کوتاه کنید (StringTrimming.EllipsisCharacter)

var format = new StringFormat(StringFormat.GenericDefault);
format.FormatFlags |= StringFormatFlags.NoClip | StringFormatFlags.DirectionRightToLeft;
format.Trimming = StringTrimming.EllipsisCharacter;
var size = Size.Round(e.Graphics.MeasureString(text, listBox1.Font, listBox1.ClientSize.Width - 20, format));
size.Width = Math.Max(30, size.Width);
size.Height = Math.Min(100, size.Height);


var format = new StringFormat(StringFormat.GenericDefault);
format.FormatFlags |= StringFormatFlags.DirectionRightToLeft;
format.Trimming = StringTrimming.EllipsisCharacter;
var size = Size.Round(e.Graphics.MeasureString(text, listBox1.Font, listBox1.ClientSize.Width - 20, format));
size.Height = Math.Min(100, size.Height);
e.ItemHeight = size.Height + 22;
}

arastoahmadi
یک شنبه 04 خرداد 1399, 22:26 عصر
ممنون از پاسختون دوست عزیز من برنامه رو به این شکل تغییر دادم
151775

فقط میخام مثله تصویر زیر فایل ضمیمه بهش پیوست بدم اگه بخام فایل رو از اس کیو ال بخونه باید چطوری کدو تغییر بدم و اگر لینک باشه باید چطوری تغییر بدم ممنون میشم یه راهنمایی کنید



151776

arastoahmadi
دوشنبه 19 خرداد 1399, 12:07 عصر
ممنون میشم اگه کسی راهنمایی کنه

mr.sirwan
یک شنبه 10 اسفند 1399, 15:57 عصر
تشکر از راهنمایی های جناب the king (https://barnamenevis.org/member.php?259237-the-king) بنده میخوام لیست باکس رو بصورت سطر و ستون طراحی کنم به صورت زیر

153073


منتها داخل لیست باکس انگار هر آیتم کل یک سطر رو میگیره و اینجور نیست که هر آیتم سطر و ستون جداگانه بگیره، الان بنده این باکس هارو تونستم داخل لیست باکس توسط شی e.Grpahics طراحی کنم، به شکل زیر
153072


در حال حاضر میتونم با تنظیم location مربوط به هر باکس، باکس ها رو توی سطر و ستون کنار هم رسم کنم ولی مشکل اینه به ازای هر سطر، روی هر کدوم از باکس های موجود در ستون های اون سطر کلیک کنم، صرفا باکس اول از سمت راست (یعنی ستون اول) هایلایت میشه و مابقی باکس های اون سطر اصلا انگار وجود ندارن و کلیک نمیخورن، حتی پراپرتی e.ItemWidth رو هم ست میکنم ولی تفاوتی ایجاد نمیکنه
حالا سوالم اینه آیا راهی هست که این طراحی رو مثل عکس اولی پیاده کرد که هر آیتم لیست باکس فقط یه ستون رو بگیره یعنی دقیقا اون مستطیل مربوط به هر باکس؟

the king
یک شنبه 10 اسفند 1399, 20:01 عصر
تشکر از راهنمایی های جناب the king (https://barnamenevis.org/member.php?259237-the-king) بنده می
منتها داخل لیست باکس انگار هر آیتم کل یک سطر رو میگیره و اینجور نیست که هر آیتم سطر و ستون جداگانه بگیره، الان بنده این باکس هارو تونستم داخل لیست باکس توسط شی e.Grpahics طراحی کنم، به شکل زیر
در حال حاضر میتونم با تنظیم location مربوط به هر باکس، باکس ها رو توی سطر و ستون کنار هم رسم کنم ولی مشکل اینه به ازای هر سطر، روی هر کدوم از باکس های موجود در ستون های اون سطر کلیک کنم، صرفا باکس اول از سمت راست (یعنی ستون اول) هایلایت میشه و مابقی باکس های اون سطر اصلا انگار وجود ندارن و کلیک نمیخورن، حتی پراپرتی e.ItemWidth رو هم ست میکنم ولی تفاوتی ایجاد نمیکنه
حالا سوالم اینه آیا راهی هست که این طراحی رو مثل عکس اولی پیاده کرد که هر آیتم لیست باکس فقط یه ستون رو بگیره یعنی دقیقا اون مستطیل مربوط به هر باکس؟
لابد کدی که نوشته اید مشکلی داره وگرنه نباید خارج از محدوده کادر اون آیتم تاثیری داشته باشه.

153075

153076

mr.sirwan
یک شنبه 10 اسفند 1399, 23:25 عصر
واقعا ممنون از راهنماییتون، مشکلو برطرف کردم، حالا چندتا سوال دارم:

1. اینکه آیا میشه تعداد ستون ها در هر سطر رو کنترل کرد؟ در حال حاضر وقتی تعداد رکوردها بیشتر از اندازه مانیتور میشه، لیست باکس، اسکرول افقی میخوره که این مسئله زیاد کاربر پسند نیست، بنده میخوام متناسب با سایز مانیتور، تعداد آیتم هارو نمایش بدم که اصلا اسکرول نخوره و اگر چاره ای نبود و اسکرول هم خورد، اسکرول عمودی بخوره نه اسکرول افقی

2. آیتم ها از بالا به پایین (بصورت سطری) رسم میشن، آیا راهی هست که آیتم هارو بصورت ستونی رسم کنیم؟ منظورم از راست به چپ یا چپ به راست هستش

3. پراپرتی ItemHeight رو نمیشه بیشتر از 255 گذاشت، آیا راهی برای دور زدن این مشکل وجود داره؟

4. برای تعداد کمی از آیتم ها، آیتم ها از وسط لیست باکس به سمت چپ اون رسم میشن که چیز منطقی ای نیست (در حالی که لیست باکس راست به چپ هم هستش) باید از سمت راست لیست باکس شروع بشن، نمونه این مشکل:
153077



5. یه مورد هم که زیاد اذیت میکنه این چشمک زدنه ست، آیا میشه کاری برای رفع این چشمک زدن آیتم ها کرد؟ DoubleBuffer لیست باکس رو true کردم ولی فایده ای نداشت

6. درمورد پاکسازی و Dispose کردن آبجکت ها و فضای اشغال شده رم در این روش آیا نکته ای چیزی وجود داره که رعایت کنیم و باعث سربار زیاد روی سیستم نشیم؟

the king
دوشنبه 11 اسفند 1399, 03:27 صبح
واقعا ممنون از راهنماییتون، مشکلو برطرف کردم، حالا چندتا سوال دارم:
1. اینکه آیا میشه تعداد ستون ها در هر سطر رو کنترل کرد؟ در حال حاضر وقتی تعداد رکوردها بیشتر از اندازه مانیتور میشه، لیست باکس، اسکرول افقی میخوره که این مسئله زیاد کاربر پسند نیست، بنده میخوام متناسب با سایز مانیتور، تعداد آیتم هارو نمایش بدم که اصلا اسکرول نخوره و اگر چاره ای نبود و اسکرول هم خورد، اسکرول عمودی بخوره نه اسکرول افقی

طبعا با تنظیم ColumnWidth به نوعی تعداد ستون هم تنظیم میشه اما این چیزی که برای اسکروال توصیف می کنید رفتار ListView است نه ListBox.
رسم ListView رو تغییر بدهید (OwnerDraw = true و View=Tile) و تنظیم TileSize



2. آیتم ها از بالا به پایین (بصورت سطری) رسم میشن، آیا راهی هست که آیتم هارو بصورت ستونی رسم کنیم؟ منظورم از راست به چپ یا چپ به راست هستش

کنترل ListView رو جایگزین ListBox کنید.



3. پراپرتی ItemHeight رو نمیشه بیشتر از 255 گذاشت، آیا راهی برای دور زدن این مشکل وجود داره؟

بله. در set مشخصه ItemHeight کلاس یک شرط if (value < 1 || value > 255) هست که بهش علاقه ای ندارید و ناچار هستید دورش بزنید و از ItemHeight متعارف استفاده نکنید.
اگر از کلاس وراثت ایجاد می کنید که می توانید مشخصه رو override کنید وگرنه روال تغییر یافته بدون اون if اینه :

private static void SetItemHeight( ListBox listBox, int itemHeight)
{
var fieldInfo = typeof( ListBox).GetField( "itemHeight", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
fieldInfo.SetValue( listBox, itemHeight);
if ( ( listBox.DrawMode != DrawMode.OwnerDrawFixed) || ( listBox.IsHandleCreated == false))
{
return;
}
listBox.BeginUpdate( );
var methodInfo = typeof( Control).GetMethod( "SendMessage", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
methodInfo.Invoke( listBox, new object[] { 416, 0, itemHeight });
if ( listBox.IntegralHeight)
{
var size = listBox.Size;
listBox.Size = new Size( size.Width + 1, size.Height);
listBox.Size = size;
}
listBox.EndUpdate( );
}

مثلا :

SetItemHeight(lst, 400);




4. برای تعداد کمی از آیتم ها، آیتم ها از وسط لیست باکس به سمت چپ اون رسم میشن که چیز منطقی ای نیست (در حالی که لیست باکس راست به چپ هم هستش) باید از سمت راست لیست باکس شروع بشن

قطعا منطقی نیست ولی کد خودتون درست نیست که همچین ظاهری پیدا می کنه. یک جایی کار اشتباهی انجام می دهید.



5. یه مورد هم که زیاد اذیت میکنه این چشمک زدنه ست، آیا میشه کاری برای رفع این چشمک زدن آیتم ها کرد؟ DoubleBuffer لیست باکس رو true کردم ولی فایده ای نداشت

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



6. درمورد پاکسازی و Dispose کردن آبجکت ها و فضای اشغال شده رم در این روش آیا نکته ای چیزی وجود داره که رعایت کنیم و باعث سربار زیاد روی سیستم نشیم؟
قطعا. قاعده کلی اینه که چیزی که Dispose شدنی است رو تا حد امکان با using بکار ببرید یا در اولین فرصت Dispose کنید.

mr.sirwan
دوشنبه 11 اسفند 1399, 09:57 صبح
طبعا با تنظیم ColumnWidth به نوعی تعداد ستون هم تنظیم میشه اما این چیزی که برای اسکروال توصیف می کنید رفتار ListView است نه ListBox.
رسم ListView رو تغییر بدهید (OwnerDraw = true و View=Tile) و تنظیم TileSize


کنترل ListView رو جایگزین ListBox کنید.


بله. در set مشخصه ItemHeight کلاس یک شرط if (value < 1 || value > 255) هست که بهش علاقه ای ندارید و ناچار هستید دورش بزنید و از ItemHeight متعارف استفاده نکنید.
اگر از کلاس وراثت ایجاد می کنید که می توانید مشخصه رو override کنید وگرنه روال تغییر یافته بدون اون if اینه :

قطعا منطقی نیست ولی کد خودتون درست نیست که همچین ظاهری پیدا می کنه. یک جایی کار اشتباهی انجام می دهید.


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

خیلی ممنون از وقتی که گذاشتین و بنده رو راهنمایی کردین، واقعیتش بنده از listview استفاده نمیکنم، از همون اول از listbox استفاده کردم اتفاقا همون کد و اسکرین شاتی که شما از لیست باکس خودتون هم گذاشتین دقیقا مشکلات 1 تا 4 رو داره، لطفا خودتون هم تست کنید، اول اینکه لیست باکس رو راست به چپ کنید، بعد برای دیدن تاثیر مشکل اول، تعداد آیتم هارو زیاد کنید مثلا 30 یا 45 تا آیتم برای اینکه اسکرول خوردن افقی رو مشاهده کنید (این مشکل رو بنده روی برنامه اصلیم با تنظیم کردن تعداد آیتم های واکشی شده از دیتابیس حل کردم)

برای مورد دوم، که دقیقا توی اسکرین شاتی که فرستادین هم مشخصه که آیتم ها از بالا به پایین رسم میشن و نه از چپ به راست یا راست به چپ

برای مورد چهارم، تعداد آیتم هایی که داخل لیست باکس ساخته میشن رو کاهش بدین مثلا 5 آیتم و فرم رو maximize کنید که ملاحظه بفرمایید آیتم ها از وسط لیست باکس شروع به ترسیم شدن میکنن

در هر حال بنده کدایی که نوشتم رو در قالب یه نمونه پروژه اینجا میذارم، لطف کنید یه نگاهی بهش بندازید:

153078


قطعا. قاعده کلی اینه که چیزی که Dispose شدنی است رو تا حد امکان با using بکار ببرید یا در اولین فرصت Dispose کنید.

برای تصاویری که داخل resources قرار داده شدن، آیا dispose کردن لازمه؟

the king
سه شنبه 12 اسفند 1399, 01:09 صبح
خیلی ممنون از وقتی که گذاشتین و بنده رو راهنمایی کردین، واقعیتش بنده از listview استفاده نمیکنم، از همون اول از listbox استفاده کردم اتفاقا همون کد و اسکرین شاتی که شما از لیست باکس خودتون هم گذاشتین دقیقا مشکلات 1 تا 4 رو داره، لطفا خودتون هم تست کنید، اول اینکه لیست باکس رو راست به چپ کنید، بعد برای دیدن تاثیر مشکل اول، تعداد آیتم هارو زیاد کنید مثلا 30 یا 45 تا آیتم برای اینکه اسکرول خوردن افقی رو مشاهده کنید (این مشکل رو بنده روی برنامه اصلیم با تنظیم کردن تعداد آیتم های واکشی شده از دیتابیس حل کردم)

هر کدوم از کنترل ها یک رفتار مشخصی دارند که در طراحی واسط کاربری ویندوز روالش نوشته شده، نه در کد #C، مثلا اولویت درج آیتم ها در ListBox ابتدا عمودی و سپس افقی است، در ListView برعکس اینه.
انتخاب کنترل با شما است اما اگه رفتار کنترل مد دلخواه تون نباشه صرفا باید انتخاب تون رو تغییر بدهید.



برای مورد دوم، که دقیقا توی اسکرین شاتی که فرستادین هم مشخصه که آیتم ها از بالا به پایین رسم میشن و نه از چپ به راست یا راست به چپ

بله، جزو خصوصیات ListBox ئه.



برای مورد چهارم، تعداد آیتم هایی که داخل لیست باکس ساخته میشن رو کاهش بدین مثلا 3 آیتم که ملاحظه بفرمایید آیتم ها از وسط لیست باکس شروع به ترسیم شدن میکنن

RightToLeft با MultiColumn جور در نمیاد، باگ خود ListBox ئه.



برای تصاویری که داخل resources قرار داده شدن، آیا dispose کردن لازمه؟
خیر. هر منبعی که خودتون ایجاد نکنید Dispose نمی خواد. کنترل های روی فرم و کمپوننت ها هم موقع Dispose شدن فرم بصورت خودکار Dispose میشن.

mr.sirwan
سه شنبه 12 اسفند 1399, 01:49 صبح
RightToLeft با MultiColumn جور در نمیاد، باگ خود ListBox ئه.

همه موارد رو به نحوی میشه قبول کرد، ولی واقعا مورد چهارم رو نمیشه هیچ جوره هضم کرد، اصلا برای کاربر هم خوشایند نیست که همچین صحنه ای ببینه، یعنی راهی نیست که مثلا لیست باکس رو ازش ارث بری کنم و خودم دست به کد بشم و این مشکلی که با راست به چپ داره رو برطرف کنم؟ آیا کدهای زیادی میطلبه؟ ممنون میشم یه راهنمایی در این مورد بفرمایید

Mahmoud Zaad
سه شنبه 12 اسفند 1399, 08:05 صبح
سلام
اگه می تونید کنترل رو در wpf طراحی کنید و در ویندوز فرم استفاده کنید، اینجا برای کارهای گرافیکی مناسب نیست. همونطور که گفتید مشکل پرش هست، مشکل سرعت در تعداد رکوردهای بالا و مشکل چپ به راست و حتی در محاسبه اندازه یک متن بویژه متن های فارسی مشکل داره (اندازه به پیکسل یا تبدیل به میلی متر)
البته خودم فرصت طراحی در wpf و استفاده در ویندوز فرم رو نداشتم ولی با مشکلات طراحی کنترل در ویندوز فرم کاملا آشنا هستم!
این (https://www.codeproject.com/Articles/739902/How-to-Easily-Host-WPF-Control-inside-Windows-Form) هم یک مثال

mr.sirwan
سه شنبه 12 اسفند 1399, 13:32 عصر
سلام
اگه می تونید کنترل رو در wpf طراحی کنید و در ویندوز فرم استفاده کنید، اینجا برای کارهای گرافیکی مناسب نیست. همونطور که گفتید مشکل پرش هست، مشکل سرعت در تعداد رکوردهای بالا و مشکل چپ به راست و حتی در محاسبه اندازه یک متن بویژه متن های فارسی مشکل داره (اندازه به پیکسل یا تبدیل به میلی متر)
البته خودم فرصت طراحی در wpf و استفاده در ویندوز فرم رو نداشتم ولی با مشکلات طراحی کنترل در ویندوز فرم کاملا آشنا هستم!
این (https://www.codeproject.com/Articles/739902/How-to-Easily-Host-WPF-Control-inside-Windows-Form) هم یک مثال

ممنون از راهنماییتون، بله بنده هم قبلا یه UserControl داخل winform طراحی کرده بودم، که انصافا طراحیش خیلی راحت بود اما سربار زیادی روی سیستم ایجاد میکرد، در حدی که بعد از 50-60 بار ریفرش شدن این صفحه حاوی یوزرکنترل، برنامه خودبخود میپرید بیرون و بسته میشد، برا همین تصمیم گرفتم از این روش رسم لیست باکس استفاده کنم، اگه با لیست باکس به جایی نرسیدم ناچارن باید برم کنترل رو توی WPF ایجاد کنم و بیارمش داخل برنامه م