PDA

View Full Version : سوال: پاپ آپ منو برای dbgrid و باز شدن آن با کلیک روی کلید اینتر



hassan p.b
شنبه 29 خرداد 1395, 15:15 عصر
سلام
مدتی است دنبال این موضوع هستم چیز جالبی چه فارسی یا انگلیسی بدست نیومد
حال:
چطور می توانم در دی بی گرید که به یک جدول متصل است و در یکی از سلول ها هم popup menu وصل شده با شرط خالی بودن آن سلول بخصوص و با کلید اینتر منوی پاپ آپ باز گردد.لطفا راهنمایی نمایید

راستی دلفی من 2010 است واگر روی مثال در گزینه نام کلیک راست کنید پاپ آپ منو باز می شود البته بدون کنترل خالی بودن سلول مربوطه

این هم جدول
مسیر جدول هم mydocuments ویندوز قراردارد.


در جستجو هام این لینک را پیدا کردم که بسیار عالی است تمامی بخش دلفی برنامه نویس انجا لیست شده:
http://www.host3nter.com/webmasters/category/%D8%A8%D8%A7%D9%86%DA%A9-%D9%87%D8%A7%DB%8C-%D8%A7%D8%B7%D9%84%D8%A7%D8%B9%D8%A7%D8%AA%DB%8C-%D8%AF%D8%B1-delphi
مرسی
حسن

Mahmood_M
شنبه 29 خرداد 1395, 18:55 عصر
DBGrid یک تابع به نام CellRect داره که موقعیت یک سلول رو با گرفتن ردیف و ستون، در قالب TRect به ما میده
اما این تابع در قسمت Protected مربوط به DBGrid تعریف شده، برای فراخوانی اون باید اصطلاحا DBGrid رو هک کنید !
روش کار به این صورته که، یک کلاس از نوع TDBGrid تعریف می کنید و هر جایی خواستید از خصوصیات و توابع Protected استفاده کنید، DBGrid موردنظر رو به کلاس جدیدتون Type-Cast می کنید
در رویداد OnKeyPress مربوط به DBGrid کلید فشرده شده رو بررسی می کنید، بعد مقادیر فیلد رو بررسی می کنید و بعد با روشی که گفته شد مختصات سلول انتخاب شده رو بدست میارید و در نهایت PopupMenu رو در مختصات بدست اومده نمایش میدید
مثال :



TMyDBGrid = class(TDBGrid)

end;

var
MainFrm: TMainFrm;

implementation

...

procedure TMainFrm.DBGrid1KeyPress(Sender: TObject; var Key: Char);
var
CRect : TRect;
Point : TPoint;
CurrRow, CurrCol : Integer;
begin
if Key = #13 then
begin
if (DBGrid1.SelectedField.FieldName = 'MyField') and (DBGrid1.DataSource.DataSet.FieldByName('MyField') .AsString = '') then
begin
CurrRow := TMyDBGrid(DBGrid1).Row;
CurrCol := DBGrid1.SelectedField.Index;
CRect := TMyDBGrid(DBGrid1).CellRect(CurrCol, CurrRow);
Point := DBGrid1.ClientToScreen(CRect.CenterPoint);

PopupMenu1.Popup(Point.X, Point.Y);
end;
end;
end;

نیازی نیست به Column موردنظرتون PopupMenu اختصاص بدید

hassan p.b
شنبه 29 خرداد 1395, 18:58 عصر
مرسی استاد عزیز ببینم چه کاره ام میشه یه مثال عملی برام بزارید

راستی تو پراپرتی های dbgrid گزینه row برای سطرها نیست این چطور اضافه میشه!

Mahmood_M
شنبه 29 خرداد 1395, 19:58 عصر
خواهش می کنم، مثال رو قرار دادم که !

راستی تو پراپرتی های dbgrid گزینه row برای سطرها نیست این چطور اضافه میشه!
از همون روش هک استفاده کنید :


TMyDBGrid(DBGrid1).Row;

hassan p.b
شنبه 29 خرداد 1395, 19:58 عصر
این و قبلا دیدم ولی توش گزینه ای برای فهمیدن پر یا خالی بودن سلول مشخص که می خواهیم پاپ آپ منو براش باز بشه نداشت

var t:Tpoint;
...........................
procedure TForm1.DBGrid1DrawColumnCell(Sender : TObject;
const Rect: TRect; DataCol: Integer; Column: TColumn;
State: TGridDrawState);
begin
if gdselected in State then begin
t:=Rect.TopLeft;
t.X:=t.X+TDBGrid(Sender).Left;
t.Y:=t.Y+TDBGrid(Sender).Top;
t:=ClientToScreen(t);
end;

end;

procedure TForm1.DBGrid1KeyDown(Sender: TObject; var Key: Word;
Shift: TShiftState);
begin
if key = 13 then
PopupMenu1.Popup(t.X,t.Y);
end;

با این دستور با اینتر سلول ها مانند tab عمل می کنه در این هنگام چطور می توانم پر بودن سلول را بفهمم

if Key=VK_RETURN then
begin
Key := 0;
with TDBGrid(Sender) do
begin
if SelectedIndex < (FieldCount-1) then
SelectedIndex := SelectedIndex+1
else
SelectedIndex := 0;
end;
end;

با این دستور هم popup menu باز میشه ولی نه در محل سلول و در ناکجااباد مانیتور!

if(form10.DBGrid1.SelectedIndex=1) then
begin
//if(form10.DBGrid1.)
form10.PopupMenu1.Popup(100,100);
end

Mahmood_M
شنبه 29 خرداد 1395, 20:09 عصر
این و قبلا دیدم ولی توش گزینه ای برای فهمیدن پر یا خالی بودن سلول مشخص که می خواهیم پاپ آپ منو براش باز بشه نداشت
این کد هر لحظه مختصات سلول انتخاب شده رو در یک متغیر عمومی قرار میده و توی رویداد OnKeyDown از مختصات ذخیره شده استفاده می کنه
شرط مقدار فیلد رو باید در همون رویداد OnKeyDown قرار بدید
این روش برای دریافت مختصات درست نیست چون Parent مربوط به DBGrid درنظر گرفته نشده، مثلا اگه DBGrid داخل یک GroupBox قرار داشته باشه دیگه این مختصات معتبر نیست
نکته دیگه اینکه رویداد OnDrawColumnCell هر لحظه در حال اتفاق افتادنه و کدنویسی توی این رویداد باعث میشه بی دلیل یک سری دستورات هر لحظه اجرا بشه

با این دستور با اینتر سلول ها مانند tab عمل می کنه در این هنگام چطور می توانم پر بودن سلول را بفهمم

با این دستور هم popup menu باز میشه ولی نه در محل سلول و در ناکجااباد مانیتور!
از همون روشی که قرار دادم استفاده کنید
...
لطفا چند پست پشت هم ارسال نکنید و برای اضافه کردن توضیح پست قبلی تون رو ویرایش کنید
کدهاتون رو درون تگ CODE قرار بدید

hassan p.b
یک شنبه 30 خرداد 1395, 02:16 صبح
در دستورات شما در بالا من با خطای دلفی مواجه می شوم

if Key = #13 then
begin
if (DBGrid1.SelectedField.FieldName = 'name') and (DBGrid1.DataSource.DataSet.FieldByName('name') .AsString = '') then
begin
CurrRow := DBGrid1.Row;
CurrCol := DBGrid1.SelectedField.Index;
CRect := TMyDBGrid(DBGrid1).CellRect(CurrCol, CurrRow);
Point := DBGrid1.ClientToScreen(CRect.CenterPoint);

PopupMenu1.Popup(Point.X, Point.Y);
end
end

Mahmood_M
یک شنبه 30 خرداد 1395, 02:29 صبح
در دستورات شما در بالا من با خطای دلفی مواجه می شوم
برای بیان مشکل نمایش خطا، اولین کاری که باید بکنید اینه که متن خطا رو قرار بدید
بدون دیدن متن خطا نمیشه جواب مناسبی داد
...
این قسمت رو :

CurrRow := DBGrid1.Row;
تغییر بدید به این :

CurrRow := TMyDBGrid(DBGrid1).Row;

hassan p.b
یک شنبه 30 خرداد 1395, 11:08 صبح
سلام
مرسی از وقتی که گذاشتید
در هنگام کامپایل دو گزینه قرمز رنگ میشه البته بصورت زیر خط:
می خواستم تصویر بزارم در بالا اضافه کردن تصویر قسمت اپلود از کامپیوتر به سایت مشکل داره:
[DCC Error] Unit10.pas(183): E2003 Undeclared identifier: 'CenterPoint'
مرسی
گزینه بالا حل شد حالا این خطا هنوز هست!

hassan p.b
یک شنبه 30 خرداد 1395, 11:19 صبح
گزینه فوق را با مثلا Point := DBGrid1.ClientToScreen(CRect.BottomRight); تغییر دادم ولی پاپ اپ در همون محل نا کجاآباد نمایش داده میشه
راستی در دلفی ابزار و کامپوننتی هست که برای سلول هاش گزینه keypress را بطور مستقل داشته باشه مانند edit؟

hassan p.b
یک شنبه 30 خرداد 1395, 11:25 صبح
علت این دستور بود
procedure TForm10.DBGrid1ColEnter(Sender: TObject);
var
x,y:integer;
Cell: TGridCoord;
begin
if(form10.DBGrid1.SelectedIndex=1) then
begin
form10.PopupMenu1.Popup(100,100);
end

end;

با حذفش حالا هیچ اتفاقی نمی افتد با اینتر؟؟؟؟
شکل فعلی دستورات:

if Key = #13 then
begin
if (DBGrid1.SelectedField.FieldName = 'name') and (DBGrid1.DataSource.DataSet.FieldByName('name') .AsString = '') then
begin
//CurrRow := DBGrid1.Row;
CurrRow := TMyDBGrid(DBGrid1).Row;
CurrCol := DBGrid1.SelectedField.Index;
CRect := TMyDBGrid(DBGrid1).CellRect(CurrCol, CurrRow);
Point := DBGrid1.ClientToScreen(CRect.BottomRight);

PopupMenu1.Popup(Point.X, Point.Y);
end
end

hassan p.b
یک شنبه 30 خرداد 1395, 11:35 صبح
با تغییر دستور

if (DBGrid1.SelectedField.FieldName = 'name') and (DBGrid1.DataSource.DataSet.FieldByName('name') .AsString = '') then
begin

با

if(form10.DBGrid1.SelectedIndex=1) then
begin

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

Mahmood_M
یک شنبه 30 خرداد 1395, 11:42 صبح
شرط خالی بودن رو بهش اضافه کنید
برای ستون مشخصی می خواید نمایش بدید ؟
اگر اینطوره پس نام فیلد مشخصه، به این صورت شرط بذارید :

if(form10.DBGrid1.SelectedIndex=1) and (DBGrid1.DataSource.DataSet.FieldByName('FieldName ').AsString = '') then