نوشته شده توسط
ehsan_starlight
سلام دوستان میخواستم بدونم چطوری میشه یه لیست باکس بسازم
منظورم اینه که نمیخوام از لیست باکس ارجینال ویندوزی استفاده کنم
اگر دیده باشید بعضی از برنامه ها لیست باکشون رو خود برنامه نویس طراحی کرده
حتی اگر بشه همون لیست باکس ویندوزی رو سفارشی کرد بازم خوبه مثل ( تغییر شکل اسکرول ، تغییر سایز Sellection آیتم ها ، تغییر رنگ Sellection آیتم ها )
اگه بخواهید لیست باکس استاندارد رو تغییر بدهید عوض کردن ظاهر Scrollbar دردسر زیاد داره، در ویژوال بیسیک کلاسیک اینکار رو انجام دادم اما اونجا چون مجبور بودم
خود کنترل لیست باکس رو از نو طراحی کنم راحت تر بود اما اینجا چون می خواهیم لیست باکس استاندارد رو تغییر بدیم روال Scrollbar اش اونطور که می خواهیم به اختیار ما نیست.
یک فایل برای یک کلاس جدید بسازید، اینا رو اولش using کنید :
using System;
using System.Collections.Generic;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Drawing.Drawing2D;
و این کلاس رو داخل ایجاد کنید :
public class ListBoxPro : ListBox
{
private int hoveredIndex;
public int HoveredIndex
{
get
{
return hoveredIndex;
}
}
private string myName;
public string MyName
{
get
{
return myName;
}
set
{
myName = value;
}
}
public int SelectedItemIndex
{
get
{
return base.SelectedIndex;
}
set
{
base.SelectedIndex = value;
}
}
public override DrawMode DrawMode
{
get
{
return base.DrawMode;
}
}
public ListBoxPro()
{
hoveredIndex = -1;
base.ItemHeight = 20;
base.DrawMode = System.Windows.Forms.DrawMode.OwnerDrawFixed;
base.MouseLeave += new EventHandler(ListBox_MouseLeave);
base.MouseMove += new MouseEventHandler(ListBox_MouseMove);
base.DrawItem += new DrawItemEventHandler(ListBox_DrawItem);
}
private void ListBox_MouseMove(object sender, MouseEventArgs e)
{
int newIndex = FindItemByPoint(e.Location);
int prevIndex = hoveredIndex;
if (newIndex != prevIndex)
{
hoveredIndex = newIndex;
if (prevIndex > -1)
{
base.Invalidate(base.GetItemRectangle(prevIndex));
}
if (newIndex > -1)
{
base.Invalidate(base.GetItemRectangle(newIndex));
}
}
}
private void ListBox_MouseLeave(object sender, EventArgs e)
{
int prevIndex = hoveredIndex;
if (prevIndex > -1)
{
hoveredIndex = -1;
base.Invalidate(base.GetItemRectangle(prevIndex));
}
}
private int FindItemByPoint(Point location)
{
if (base.Items.Count == 0)
{
return -1;
}
Rectangle itemBounds = base.GetItemRectangle(0);
if ((itemBounds.Left > location.X) || (itemBounds.Right <= location.X))
{
return -1;
}
int first = 0;
int last = base.Items.Count - 1;
while (first <= last)
{
int index = (first + last) / 2;
itemBounds = base.GetItemRectangle(index);
if (itemBounds.Top <= location.Y)
{
if (itemBounds.Bottom > location.Y)
{
return index;
}
else
{
first = index + 1;
}
}
else
{
last = index - 1;
}
}
return -1;
}
private void ListBox_DrawItem(object sender, DrawItemEventArgs e)
{
BufferedGraphicsContext bufferedContext = BufferedGraphicsManager.Current;
BufferedGraphics buffer = bufferedContext.Allocate(e.Graphics, e.Bounds);
Graphics graphics = buffer.Graphics;
Rectangle frameBounds = new Rectangle
(
e.Bounds.X,
e.Bounds.Y,
e.Bounds.Width - 1,
e.Bounds.Height - 2
);
Rectangle fillBounds = new Rectangle
(
e.Bounds.X + 1,
e.Bounds.Y + 1,
e.Bounds.Width - 2,
e.Bounds.Height - 3
);
Rectangle textBounds = new Rectangle
(
e.Bounds.X + 2,
e.Bounds.Y + 2,
e.Bounds.Width - 4,
e.Bounds.Height - 3
);
Brush backBrush = new SolidBrush(base.BackColor);
graphics.FillRectangle(backBrush, e.Bounds);
if ((e.Index > -1) && (e.Index < base.Items.Count))
{
if ((e.State & DrawItemState.Selected) == DrawItemState.Selected)
{
Color c1 = GetColor(SystemColors.Highlight, 64);
Color c2 = GetColor(SystemColors.Highlight, 0);
Color c3 = GetColor(SystemColors.Highlight, -32);
LinearGradientBrush faceBrush = new LinearGradientBrush(fillBounds, c1, c2, 90);
graphics.FillRectangle(faceBrush, fillBounds);
Pen framePen = new Pen(c3);
graphics.DrawRectangle(framePen, frameBounds);
}
else if (e.Index == hoveredIndex)
{
Color c1 = GetColor(SystemColors.Highlight, 128);
Color c2 = GetColor(SystemColors.Highlight, 64);
Color c3 = GetColor(SystemColors.Highlight, 32);
LinearGradientBrush faceBrush = new LinearGradientBrush(fillBounds, c1, c2, 90);
graphics.FillRectangle(faceBrush, fillBounds);
Pen framePen = new Pen(c3);
graphics.DrawRectangle(framePen, frameBounds);
}
string text = base.Items[e.Index].ToString();
StringFormat textFormat = new StringFormat();
if (base.RightToLeft == System.Windows.Forms.RightToLeft.Yes)
{
textFormat.FormatFlags = StringFormatFlags.DirectionRightToLeft;
}
textFormat.LineAlignment = StringAlignment.Center;
Brush textBrush = new SolidBrush(e.ForeColor);
graphics.DrawString(text, e.Font, textBrush, textBounds, textFormat);
}
buffer.Render(e.Graphics);
}
private int LimitByte(int value)
{
if (value < byte.MinValue)
{
return byte.MinValue;
}
if (value > byte.MaxValue)
{
return byte.MaxValue;
}
return value;
}
private Color GetColor(Color baseColor, int brightness)
{
int red = LimitByte(baseColor.R + brightness);
int green = LimitByte(baseColor.G + brightness);
int blue = LimitByte(baseColor.B + brightness);
return Color.FromArgb(red, green, blue);
}
}
یکبار که کد رو کامپایل کنید در Toolbox ویژوال استدیو بالا یک کنترل ListBoxPro اضافه شده که می توانید در فرم تان بکار ببرید، این لیست باکس
بر خلاف لیست باکس استاندارد Hover رو نشون میده و رنگ اش هم متفاوته.