PDA

View Full Version : سوال در مورد ComponentIndex



Anis131313
سه شنبه 13 دی 1390, 15:34 عصر
سلام و خسته نباشید خدمت دوستان
نمونه فرمی که من دارم تا دیروز درست کار میکرد اما امروز دیگه کار نمیکنه
من تمامی پنل ها رو با ComponentIndex عدد دادم اما کار نمیکنه.
مثلا در FormCreate نوشتم :

Panel8.Componentindex:=100

بعد در FormShow نوشتم

Self.Components[100] as Tpanel . Color = ClRed

اما انگار نه انگار من به ComponentIndex مقدار دادم

80101

moein+
سه شنبه 13 دی 1390, 17:19 عصر
من تا به حال با ComponentIndex کار نکردم چون تو حالت ویژوال بیشتر از ترکیب Control و ControlCount و البته tag بهره بردم، ولی اون چیزی که مشخصه اینه که ComponentIndex هر چند قابل مقدار دهی هست ولی در مجموعه ای که شما 10 کامپوننت دارید شامل اعدا 1 تا 10 میشود ولا غیر، حالا شما اگر بخواهید یکی از اونها رو مقدار بدهید مثلا بدهید 20 اون به مقدار ماکزیمم یعنی 10 ست می شود و ایندکس بقیه هم شیفت پیدا می کند و این یعنی با هر با مقدار دهی یکی از عناصر هم والد، باقی عناصر مقدارشان بروز می شود ... پس کلاً این راه، راه مناسبی نیست برای تفکیک یکسری کنترل شاید تگ دادن به اونا راه بهتری باشه ...

بعد هم من فرم شما را باز کردم و 847 کنترل !!!! به نظر میرسه شما برای نمایش مفهوم مورد نظرتون باید کنترل جدیدی طراحی کنید، ایجاد چنین فرمی هم زمان زیادی از برنامه شما میبرد و هم حافظه زیادی که بهینه نیست!!!

BORHAN TEC
سه شنبه 13 دی 1390, 18:37 عصر
میتونید از کدی مثل زیر استفاده کنید:

procedure TForm1.Button1Click(Sender: TObject);
var
pnl: TPanel;
begin
FormCreate(nil);
pnl := TPanel(Self.Components[100]);
pnl.Color := clred;
end;
ولی در هر صورت، روشی که به کار برده اید روش بسیار بدی است که پیشنهاد می کنم به جای استفاده از این روش یک کامپوننت بنویسید و از آن کامپوننت استفاده کنید.

soft-c
سه شنبه 13 دی 1390, 22:48 عصر
ولی در هر صورت، روشی که به کار برده اید روش بسیار بدی است که پیشنهاد می کنم به جای استفاده از این روش یک کامپوننت بنویسید و از آن کامپوننت استفاده کنید.
میشه بگین با این روش چه مشکلی پیش می یاد و با روش کامپوننت چه مزیتی داره ؟

Anis131313
چهارشنبه 14 دی 1390, 00:15 صبح
دوستان عزیزم بسیار بزرگواری کردین از اینکه جواب دادین.

این فرمی که اینجا هست در واقع یک فرم رزرو هستش که 7 روز آینده رو برای منشی نمایش میده تا بتونه بهترین انتخاب رو انجام بده، اگه روش بهتری برای این کار سراغ دارید خوشحال میشم من رو راهنمایی کنید.

اما حرف دوستمون جناب Moein درست هستش و چون من به زور عددی مثلا 700 رو به یک کامپوننت دادم و از طرفی به تعداد 700 تا کامپوننت روی فرم نیست بنابر این این اشتباه رخ میده...

MohsenB
چهارشنبه 14 دی 1390, 01:07 صبح
سلام


به نظر من :

اگر میخواید از اشیاء برای هر سلول استفاده کنید بهتره اولا از اشیائی سبکتر مثل Shape استفاده کنید و برای دستیابی بهتر و ساخت راهتتر اونها رو بصورت کد درست کنید ، و از اون بهتر بصورت آرایه ای از اشیاء .


پیشنهاد من اینه که از یه طراحی گرافیکی استفاده کنید تا کدتون به کمترین اندازه ، برنامتون به حداقل و سرعتتون به حداکثر برسه . منظورم اینه که اون اشیاء رو خودتون بصورت اشیاء گرافیکی بکشید . و برای کنترل و مدیریت بهتر ، بهتر اینه که بصورت کامپوننت نوشته بشه یعنی یک ردیف از داده ها رو بصورت یک کامپوننت بنویسید و برای بقیه ردیفها از اون استفاده کنید . اگر توانایتون تو نوشتن گرافیکی سریعتر خوب باشه میتونید یه برنامه خیلی خیلی سریع بسازید .

البته من کامپوننت TdxfLabel رو نداشتم و جاش لیبل گذاشتم اگه میشه یک عکس از محیط بفرستید تا ببینیم همینی شده که من دارم .


ولی واقعا آفرین به پشتکار شما ! 1253 خط برنامه نویسی کردین ، ولی هنوز برنامه ننوشتسن !! اگه مینوشتین چقدر میشد؟؟!!


موفق باشید

Anis131313
چهارشنبه 14 دی 1390, 13:27 عصر
سلام

محسن جان خیلی لطف کردین.

متاسفانه TShape رویداد Onclick نداره منتها کلا منظورتون رو متوجه شدم ولی از طرفی من نیاز دارم به تشخیط دقیق مختصات ماتریس تاریخ و ساعت و راه ساده تری به نظرم نرسید ...

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

Panel8.ComponentIndex:=100
.
.
.
تا
.
.
Panel385.ComponentIndex:=751

کافیست از نرم افزار Excel جهت تولید کد برنامه استفاده کنیم مانند عکس زیر :

80163

بعد از Excel کپی کرده و به محیط دلفی میبریم، اون کامپوننت dxf رو از Uses حذف کن مهم نیست
اما در هر حال اگر نمایی از فرم را میخواهید چشم در پایین قرار میدم :

80164

به هر حال ببخشید وقتتون رو گرفتم.

MohsenB
چهارشنبه 14 دی 1390, 15:57 عصر
سلام خوب این کارهارو نمیخواست . اینجوری میتونستید جای اون 751 خط 1 خط کد بنویسید : for i := 8 to 385 do TPanel(FindComponent('Panel' + IntToStr(i))).ComponentIndex:= i + 92; اون سبز و آبی تو جدول چیه؟ اصلا باید چه اتفاقاتی تو جدول بیفته ؟ و توسط چه کاری؟ ( منظورم اینه که کی باید سبز بشه و کی آبی و کی بیرنگ و آیا رنگ دیگه ای داره؟ اینکس ها بر چه مبناییه؟

Anis131313
چهارشنبه 14 دی 1390, 16:18 عصر
سلام

به 2 دلیل از کد شما استفاده نکردم :
1. از وجود دستوری به نام FindComponent بیخبر بودم :لبخند:
2. یه استثنااتی مثل عکس زیر وجود داشت:

80170

بیخیال اون 700 خط شیم ، دیگه شد دیگه ...

کاربر وقتی رزروی رو انجام میده با کلیک روی پنل ساعت شروع انتخاب میشه و یک فرم باز میشه که توی اون فرم مدت زمان ویزیت تعیین میشه (مضربی از 15) (بر حسب دقیقه) بعد از تایید فرم باز شده اون بازه زمانی رو (ساعت ورود به ویزیت تا ساعت خروج) را به رنگ مثلا آبی اختصاص میدهیم .
خوب وجود این رنگ سبز به این دلیل بود که اگه همه رو آبی میکردم اونوقت کاربر دچار سردرگمی میشد و نمیتونست بازه های اشغال شده رو پیدا کنه...
این بود که یکی در میان از مثلا سبز و آبی استفاده کردم، شاید هم Random کنم رنگ ها رو اما رنگ سفید به منزله ی خالی بودن هستش.

مرسی.

MohsenB
چهارشنبه 14 دی 1390, 22:45 عصر
سلام


یه مثال برا راحتی تغییر همین برنامه براتون میزنم و لی هنوز پیشنهاد بهتر براتون همون حالت گرافیکیه :


فایل پروژه هم براتون ضمیمه شده و لی اگر دلفی 16 ندارین همینجا کدشو براتون میزارم:


این یه قسمت از کد فرم هست
توی فرم دوتا پنل هستش که تو اون با دستور CreatePanels مقدار سلولهای لازم و مقادیر و مشخصات مورد نیاز ست میشن .
type
TForm1 = class(TForm)
pnl1: TPanel;
btn1: TBitBtn;
pnl2: TPanel;
procedure btn1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
pnls :array[100..265]of TPanel;
procedure plnsClick(Sender :TObject);
//property plnsClick :TNotifyEvent;
procedure CreatePanels(p_Selfs :TPanel; indLow, indHi :Word);
end;

var
Form1: TForm1;

implementation

{$R *.dfm}

const
cl_Blank =clWhite;
cl_Sel1 =clLime;
cl_Sel2 =clBlue;
//
s_WP =12; //selectble cell width
s_WL =4 ; //houre line width

procedure TForm1.CreatePanels(p_Selfs: TPanel; indLow, indHi :Word);
var i :Word;
begin
for i := indLow to indHi do begin
pnls[i]:= TPanel.Create(p_Selfs);
with pnls[i] do begin
Parent:= p_Selfs;
Align:= alLeft;
ParentBackground:= False;
BevelOuter:= bvNone;
BorderStyle:= bsSingle;
BorderWidth:= 1;
Ctl3D:= False;
Tag:= i;
if (indLow - i) mod 5 = 0 then begin
width:= s_WL;
Color:= clGray; //Hour color
end else begin
Width:= s_WP;
Color:= cl_Blank;
Cursor:= crHandPoint;
OnClick:= plnsClick;
end;
end;
end;
p_Selfs.Width:= ((indHi - indLow+1)* s_WP) - (((indHi - indLow)div 5)*(s_WP - s_WL));
end;

procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
var
i: Integer;
begin
for i := Low(pnls) to High(pnls) do
pnls[i].Free;
end;

procedure TForm1.plnsClick(Sender: TObject);
begin
with TPanel(Sender) do
if Color = cl_Blank then begin
if Tag mod 10 >5 then Color:= cl_Sel1 else Color:= cl_Sel2;
end else
Color:= cl_Blank;
end;

procedure TForm1.btn1Click(Sender: TObject);
begin
CreatePanels(pnl1, 100, 165);
CreatePanels(pnl2, 200, 265);
end;

چند تا نکته که میتونید تو این کد پیدا کنید:
ساخت آرایه ای از کنترلها
گرفتن مشخصات فرستنده رویداد از Sender
ساخت کنترل های درون آرایه بصورت زمان اجرا
و ...


موفق یاشید

Anis131313
پنج شنبه 15 دی 1390, 19:44 عصر
زحمت کشیدید

خیلی ممنون