PDA

View Full Version : سوال: تغییر رنگ آیتم انتخاب شده در لیست



joooje
سه شنبه 02 فروردین 1390, 18:42 عصر
سلام
من یه لیست باکس رو آیتمهاشو رنگی کردم
حالا میخوام با دستور زیر وقتی یه آیتم انتخاب میشه رو هم تغییر رنگ بدم
ولی خوب نمیشه
میشه بگید کجای کد من اشکال داره:



procedure Tg_theForm.ListBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
var
myColor: TColor;
myBrush: TBrush;
begin
myBrush := TBrush.Create;
with (Control as TListBox).Canvas do
begin
if Index=ListBox1.ItemIndex then
begin
myColor := clWhite;
end;
if Index<>ListBox1.ItemIndex then
begin
myColor := clYellow;
end;

myBrush.Style := bsSolid;
myBrush.Color := myColor;
Windows.FillRect(handle, Rect, myBrush.Handle) ;
Brush.Style := bsClear;
TextOut(Rect.Left+2, Rect.Top,(Control as TListBox).Items[Index]) ;
MyBrush.Free;
end;
end;

mbshareat
چهارشنبه 03 فروردین 1390, 14:09 عصر
سلام علیکم
سال نو رو به دوستان سایت برنامه نویس تبریک عرض می کنم.
این کد به خوبی کار می کنه.فقط نمی دونم چرا لازم میشه رنگ قلم رو هم تنظیم کنیم در غیر این صورت نوشته ها رو سفید می نویسه!


var
Form1: TForm1;
LastItem:Integer;
implementation

{$R *.dfm}

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
Var
Can:TCanvas;
C:TColor;
LastRect:TRect;
begin
Can:=ListBox1.Canvas;
Can.Brush.Color:=clYellow;
LastRect:=ListBox1.ItemRect(LastItem);
Can.FillRect(LastRect);
Can.Font.Color:=clBlack;
Can.TextOut(LastRect.Left+2,LastRect.Top,ListBox1. Items[LastItem]);
If Index=ListBox1.ItemIndex Then
C:=clWhite
Else
C:=clYellow;
Can.Brush.Color:=C;
Can.FillRect(Rect);
Can.TextOut(Rect.Left+2,Rect.Top,ListBox1.Items[Index]);
LastItem:=Index;
end;

joooje
چهارشنبه 03 فروردین 1390, 18:20 عصر
این کد به خوبی کار می کنه.فقط نمی دونم چرا لازم میشه رنگ قلم رو هم تنظیم کنیم در غیر این صورت نوشته ها رو سفید می نویسه!
سلام و ممنون از اینکه کد گذاشتین.
منم همین روش رو امتحان کرده بودم ولی یه مشکل داره اونم اینه که زمانی که لیست را multiSelecte بکنیم دیگه درست کار نمیده.
ممنون میشم راهنمایی کنید.

joooje
شنبه 06 فروردین 1390, 11:12 صبح
سلام
آقا یعنی کسی نمیتونه یه کمکی هم به من بکنه!!!

SAASTN
یک شنبه 07 فروردین 1390, 14:41 عصر
خوب وقتی شما با MulitSelect توی ListBox سروکار داری حتما Selected رو هم میشناسی دیگه؟:متفکر:
با اجازه mbshareat (http://barnamenevis.org/member.php?79490-mbshareat) کدشون رو به شکل زیر تغییر دادم:
var
Form1: TForm1;
LastItem: Integer;
LastSelected: Boolean;

implementation

{$R *.dfm}

procedure MyDrawItem(Canvas: TCanvas; Rect: TRect; Selected: Boolean;
Text: string);
const
Colors: array[Boolean] of TColor = (clYellow, clWhite);
begin
Canvas.Brush.Color := Colors[Selected];
Canvas.FillRect(Rect);
Canvas.Font.Color:=clBlack;
Canvas.TextOut(Rect.Left + 2, Rect.Top, Text);
end;

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
Var
Can:TCanvas;
C:TColor;
LastRect:TRect;
begin
Can:=ListBox1.Canvas;
if LastSelected <> ListBox1.Selected[LastItem] then
MyDrawItem(Can, ListBox1.ItemRect(LastItem), ListBox1.Selected[LastItem],
ListBox1.Items[LastItem]);
MyDrawItem(Can, ListBox1.ItemRect(Index), ListBox1.Selected[Index],
ListBox1.Items[Index]);
LastItem := Index;
LastSelected := ListBox1.Selected[Index];
end;

البته تعریف اون متغیرهای سراسری قانونا، عرفا و شرعا اشکال داره و کل این قضیه باید در قالب یه کامپوننت پیاده سازی بشه.

mbshareat
دوشنبه 08 فروردین 1390, 01:27 صبح
با سلام
جناب SAASTN دوست عزیز خیلی وقت بود خبری از شما نبود.
آقا کدتون رو امتحان کردم اونطور که از MultiSelect انتظار میره عمل نمیکنه!

joooje
سه شنبه 09 فروردین 1390, 09:56 صبح
سلام
ممنون از کمکتون
ولی فکر کنم واقعا راهی برای حل این مشکل نیست! دقیقا یه مشکلاتی داره.
ولی ممنون. انگار دلفی هم با ما سر ناسازگاری گذاشته.!!!
کس یمیتونه بهتر راهنمایی کنه؟

SAASTN
جمعه 12 فروردین 1390, 11:11 صبح
با سلام
جناب SAASTN دوست عزیز خیلی وقت بود خبری از شما نبود.
سلام، کم سعادتی آقا.
من واقعا عذرخواهی می کنم، چند روزی سفر رفتم. و خیلی جالبه که اخیرا تو بخش دلفی، اساتید اصلا رغبت نمی کنن به این مسائل پیش پا افتاده جواب بدن.:چشمک: خوب اون کاربرای عادی یا هستن یا نیستن، وقتی نیستن باید یکی دیگه بیاد جواب بده ها! اگه نده کابرای کمتری میان اینجا ها! بعد دلفی میره زیر برنامه نویسی موبایل ها! بعد هی فقط اساتید می مونن و اساتید ها! اووه! البته یبار دیگه که نگاه کردم دیدم آموزشگاهم چندوقتیه که کلاس دلفی نمیذاره! چه جالب!:متفکر:
بگذریم، زمانی که کد رو دیدم متوجه شدم که هیچ امکانی برای حالت MultiSelect در اون تعبیه نشده، تغییرات رو اعمال کردم و تست کردم و جواب گرفتم. البته فقط با Ctrl!!:اشتباه:
نمی دونم کسی در مورد وضعیت بوجود اومده در حالتی که با Shift چند آیتم رو انتخاب می کنیم جستجویی، Traceی چیزی کرده یا نه. ولی به هر صورت مشکل اینجاست که وقتی شما چند آیتم رو با Shift انتخاب می کنی تمام آیتمهایی که قراره Selectedشون تغییر کنه یکبار ترسیم می شن اما در زمان ترسیم هنوز Selectedشون مقدار تغییر یافته رو نگرفته! یعنی مثلا Selected هنوز False هست درصورتی واقعیت اینه که اون آیتم انتخاب شده.
آقا خلاصه اینا رو ول کن، کلا Selected در DrawItem مقدار معتبری نیست و باید از همون پارامتر State بدبخت که از اول هم همونجا بوده استفاده کنیم، جالب اینجاست که اگه از اول به این پارامتر و دفعات ترسیم هر آیتم نگاه می کردیم دیگه اصلا نیازی به استفاده از اون متغیر های سراسری غیر شرعی هم نداشتیم. کد به شکل شسته رفته زیر در میاد:
var
Form1: TForm1;

implementation

{$R *.dfm}

procedure MyDrawItem(Canvas: TCanvas; Rect: TRect; Selected: Boolean;
Text: string);
const
Colors: array[Boolean] of TColor = (clYellow, clWhite);
begin
Canvas.Brush.Color := Colors[Selected];
Canvas.FillRect(Rect);
Canvas.Font.Color:=clBlack;
Canvas.TextOut(Rect.Left + 2, Rect.Top, Text);
end;

procedure TForm1.ListBox1DrawItem(Control: TWinControl; Index: Integer;
Rect: TRect; State: TOwnerDrawState);
begin
MyDrawItem(ListBox1.Canvas, ListBox1.ItemRect(Index), odSelected in State,
ListBox1.Items[Index]);
end;

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

a_mosavian
جمعه 12 فروردین 1390, 17:11 عصر
درسته پیچیده نیست ولی چنان پیش پا افتاده هم نیست!!

SAASTN
شنبه 13 فروردین 1390, 02:22 صبح
درسته پیچیده نیست ولی چنان پیش پا افتاده هم نیست!!
نه نه، من به هیچ عنوان منظورم این نبود که موضوع تاپیک فعلی پیش پا افتادس، اون پاراگراف کلا دارای یه سری آرایه های ادبی مثل تلمیح و مراعات نظیر و استعاره و غیرست و به هیچ عنوان جدی نگیریدش.
اما برای اینکه پست کلا بی محتوا نباشه خدمتتون عرض کنم که رسیدن از پست 5 به 8 بنده امری کاملا پیش پا افتادس که به عقیده من حداقل نصف افرادی که توی فاصله چند روزه بین این دو پست در بخش دلفی پست دادن از پسش برمیان.
بنده خودم که در جریان موضوع بودم در حدود 10-12 دقیقه روش کارکردم، حالا یکی از اون نصفی بخواد روش کارکنه بسته به این که کی باشه از 2 تا حداکثر 30 دقیقه زمان لازم داره تا به کد پست 8 برسه. موضوع از این قراره:
1- کدی تولید شده و کنترلهای اولیه روی اون انجام شده، صاحب تاپیک اعلام می کنه کد هنوز مشکل داره، باید کنترلهای بیشتری روی برنامه انجام بشه تا مشکل تشخیص داده بشه. (یه نکته جانبی اینجاست: صاحب تاپیک به نوعی مدیر اون تاپیکه(نظر من)، و باید جریان بحث ها رو در اون تاپیک کاملا کنترل کنه. این زمانیه که فرد برای حل مشکل خودش میذاره و در مقابل کاری می کنه که تاپیک با حداکثر سرعت به نتیجه برسه و کیفیت کلی سایت بالاتر بره، مثلا توقع من این بود که دوستان در پستهای 6 و 7 اعلام کنند که دقیقا با چه مشکلی روبرو شدن و من رو هدایت کنند.)
2- بعد از تشخیص مشکل، حالا کد باید Trace بشه تا بفهمیم منشا مشکل کجاست.
3- بعد از تشخیص عاملی که باعث خرابی شده، باید نحوه پیاده سازی رو تغییر بدیم. حالا اینجا یا < باید =< بشه یا مثلا باید یه Searchی بشه، یه Manualی خونده بشه، یه کد خونی روی کدای بالاتر انجام بشه یا ...

حالا در مورد این مثال خاص، من اول اومدم یه ذره ور رفتم دیدم تو حالت انتخاب با Shift درست کار نمیکنه، بعد با Debugرفتم دیدم DrawItem یه جایی باید با Selectedه True اجرا میشده با False اجرا شده، یهو یاد State افتادم یه Ctrl+Click رو DataTypeش کردم دیدم توش یه چیزی تو مایه های Selected هست و ازش استفاده کردم. حالا شما خودت بگو کل این کارا کار شاقیه که سوال کاربر سه چهار روز رو زمین مونده؟! اینجاست که یخورده بیشتر ادبیات کار کنی می رسی به ..:چشمک:

joooje
شنبه 13 فروردین 1390, 14:55 عصر
سلام
با خوندن توضیحاتتون یه چیزی به ذهنم رسید.الان دلفی دم دست ندارم.ولی چک میکنم که اگه درست جواب داد بزارم تو پست.
ممنون از راهنماییهاتون