PDA

View Full Version : طریقه کنترل و هدایت یک ایونت خاص



Sal_64
جمعه 19 مهر 1387, 20:46 عصر
سلام
به همه دوستان

طریقه کنترل و هدایت یک ایونت خاص چطورییه ؟

توضیح بیشتر

در رویداد keydown دیتاگرید ویو زمانی که UpویاDown زده شد سطر انتخاب شده تغییر نکند (در سطرها پیمایش انجام نشود) و بعد ازاون با کد نویسی روی این دو کلید کار دلخواه رو بشه انجام داد

با تشکر

SMRAH1
شنبه 20 مهر 1387, 08:15 صبح
سلام

کافیست یک کلاس از DataGrid مشتق کنی و در آن متد OnKeyDown رو Override کنی.در این متد override شده،اگر کلیدی غیر از Up و Down زده شده بود، می تونی همان متد پیش فرض یعنی base.OnKeyDown رو فراخوانی کنی و اگر این دو کلید بود که هیچ کاری نمی خواهد انجام دهد و تابع باز می گردد.

موفق باشی

Sal_64
شنبه 20 مهر 1387, 11:10 صبح
سلام
وقت بخیر
تشکر

حقیقتش تا حالا از این کارا نکردم :ناراحت:
می تونین برای توضیحات بیشتر یک قطعه کد براش بزارید :بوس:


با تشکر

nathan
شنبه 20 مهر 1387, 12:07 عصر
دوست عزيز اگه مي شه كدش رو بزار.

SMRAH1
شنبه 20 مهر 1387, 13:45 عصر
سلام دوستان
دقیقا این کلاس رو باید پیاده سازی کنید:

public partial class CustomDataGridView : DataGridView
{
public CustomDataGridView()
{
InitializeComponent();
}

protected override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyCode == Keys.Down || e.KeyCode == Keys.Up)
{
return;
}
base.OnKeyDown(e);
}

protected override void OnKeyUp(KeyEventArgs e)
{
if (e.KeyCode == Keys.Down || e.KeyCode == Keys.Up)
{
return;
}
base.OnKeyUp(e);
}
}
البته این روش برای برخی کنترلها جواب نمیده مثلا برای textBox چون پردازش واقعی روی ورودی صفحه کلید، قبل از فراخوانی این دو متد انجام میشه.البته در این گونه کنترل ها باید روال کنترل پیام های Control رو کنترل کنیم و هرگاه پیغام صفحه کلید اومد،اول خودمون پردازش کنید و اگرلازم بود به Control مورد نظر اجازه پردازش بدیم.در واقع باید WinProc کنترل رو کنترل کنیم.

خوشبختانه در مورد شما این پیچیدگی ها نیست.
موفق باشید

Sal_64
شنبه 20 مهر 1387, 14:54 عصر
سلام


:لبخند: بعدش چیکار باید کرد
اگه اشتباه نکنم باید از این کلاس یه شی تو فرمم ایجاد کنیم
یا یه دیتاگرید که از این کلاس (ارث ببره یا مشتق شه و یا ..)

امکان داره بیشتر توضیح بدین ؟؟:خجالت:

با تشکر

SMRAH1
شنبه 20 مهر 1387, 15:27 عصر
سلام

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

Sal_64
شنبه 20 مهر 1387, 15:45 عصر
سلام

امان از کم تجربگی :خجالت:

آقا یعنی که دیگه نباید از ToollBox یه دیتاگرید به فرمم اضافه کنم باید با کد نویسی این کارو انجام بدم اگه اینطوره میشه بگید چطور باید دیتاگریدی با استفاده از این کلاس ایجاد کنم


با تشکر

SMRAH1
شنبه 20 مهر 1387, 16:12 عصر
سلام

برای طراحی،اگر این کنترل رو به برنامت اضافه کنی (چه به صورت تعریف یک کنترل جدید یا چه با Refrence دادن به اسمبلی حاوی کنترل جدید)،در بالاترین قسمت ToollBox (حتی بالا تر از All Windows Forms) قسمتی اضافه میشه وتمام کنترلهایی که در این پروزه اضافه شده (کنترل های سفارشی که شما اضافه کرده اید) نمایش داده میشه.
اگر هم فرمی طراحی کرده ای و نمی خواهی تنظیمات DataGrid جاری از دست بره،کافی اول کلاس بالا رو به پروژت اضافه کنی،بعد برو در متد InitializeComponnent فرمت و به شکل دست تمام مرجع ها (در تعریف متغیر و ساختن یک شی جدید برای این متغیر با new) که به DataGrid شده،به این کلاس جدید تنظیم کن.

کار تمومه!

Sal_64
سه شنبه 23 مهر 1387, 11:15 صبح
سلام

من کلاس به برنامه اضافه کردم با اسم(Class1) بعد از اون تو قسمت Fourm1.Designer.cs

this.dgv = new System.Windows.Forms.DataGridView();را به

this.dgv = new Class1.CustomDataGridView();تغییر دادم ، تا اینجاش درسته ؟؟ :اشتباه:

در کلاس مذکور (Class1) روی این کد

throw new NotImplementedException();این خطا رو میده


The method or operation is not implemented.
میشه بیشتر راهنمایی کنید ؟؟ :خجالت:

امیدوارم توضیحات کافی باشه :چشمک:

SMRAH1
سه شنبه 23 مهر 1387, 15:23 عصر
سلام

اگر Class1 ،کلاسه پس کد

new Class1.CustomDataGridView()یعنی چی.(اگر CustomDataGridView یک متد از کلاس Class1،کلمه new قبل از آن معنی ندارد).

اگر Class1 یک namespace است باید کد درست کار کند.
در ضمن هر وقت شما به یک کلاس یک متد اضافه می کنید،به شکل اتوماتیک VS در اون متد خط

throw new NotImplementedException();
رو اضافه می کنه تا کاربر حتما متوجه باشه که باید کد رو پیاده سازی کنه.(می تونید خط رو حذف کنید)

Sal_64
پنج شنبه 25 مهر 1387, 13:07 عصر
سلام

باز هم امان از کم تجربگی

Class1 یک namespace نیست

کد رو اینطور تغییر دادم ام ایررور زیر رو میده


this.dgv = datagridview_rowfilter.Class1.CustomDataGridView() ;

'datagridview_rowfilter.Class1.CustomDataGridView' is a 'type', which is not valid in the

و با حذف اون خط هم این ایرور رو میده

public CustomDataGridView()
{
InitializeComponent();
}


The name 'InitializeComponent' does not exist in the current context

لطف میکنید یه کم توضیحات بیشتر بدید:ناراحت:

SMRAH1
پنج شنبه 25 مهر 1387, 17:14 عصر
بطور مشخص داره به عدم هماهنگی dgv با نوع CustomDataGridViewاشکال می گیره.
باز هم از نوشته شما (مثل دفعه قبل) سر در نیاوردم.اگر ممکنه نمونه کد رو بگذارید تا کامل متوجه بشم (یک نمونه ساده شده هم کافیست به شرط اینکه دارای این خطا باشد).

موفق باشید

Sal_64
پنج شنبه 25 مهر 1387, 18:04 عصر
سلام

تو برنامه کلاس شما اضافه شده و اون خطا هم وجود داره و دیگر هیچ !

احتمالا باید کلی تغییرات داخلش بدین :اشتباه:


با تشکر :قلب:

SMRAH1
پنج شنبه 25 مهر 1387, 18:16 عصر
سلام

دوست من:
1) اولا من برنامه رو کامپایل کردم و اجرا کردم ،البته بدون مشکل
2) اصلا کنترلی که برات فرستادم توی برنامه نیست چه برسه که روی فرم باشه.

یه نگاه به فایل پیوستی بنداز

موفق باشی

Sal_64
پنج شنبه 25 مهر 1387, 19:03 عصر
سلام


یه نگاه به فایل پیوستی بنداز

فایل رو نمی بینم ، ایراد از سیستم منه ؟!


با تشکر

SMRAH1
پنج شنبه 25 مهر 1387, 19:07 عصر
اگر کد رو بگذاری در خدمت هستیم

Sal_64
پنج شنبه 25 مهر 1387, 19:30 عصر
سلام

اینو ببینید

با تشکر

SMRAH1
پنج شنبه 25 مهر 1387, 19:42 عصر
سلام

دوست من
1) در فایل Class1.cs،نام class1 کلا اضافه است یعنی این فایل رو باید به این شکل بنویسی


namespace datagridview_rowfilter
{
public class CustomDataGridView : DataGridView
{
public CustomDataGridView()
{
InitializeComponent();
}

private void InitializeComponent()
{
//throw new NotImplementedException();
}
}
}

2) خط

this.dgv = datagridview_rowfilter.CustomDataGridView();
در سی شارپ درست نیست بلکه باید یک نمونه از این شی انتقال داده بشه یعنی این ;کد درسته:


this.dgv = new datagridview_rowfilter.CustomDataGridView();

موفق باشی

Sal_64
پنج شنبه 25 مهر 1387, 22:24 عصر
سلام

بابت اصلاح برنامه تشکر

حالا تازه رسیدیم به سوال اول :لبخند:

اون کد مربوط به رویداد keydown رو تو کلاس قرار دادم

حالا چطور توی فرم از اون استفاده کنم الان با زدن کلید Up و Down اتفاقی رخ نمی ده



باز هم تشکر:قلب:

SMRAH1
جمعه 26 مهر 1387, 05:36 صبح
سلام

توی همین برنامه (datagridview_rowfilter) کافیه فایل Class1.cs رو به این تغییر بدی:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.ComponentModel;


namespace datagridview_rowfilter
{
public class CustomDataGridView : DataGridView
{
public CustomDataGridView()
{
InitializeComponent();
}

private void InitializeComponent()
{
//throw new NotImplementedException();
}

protected override void OnKeyDown(KeyEventArgs e)
{
if (e.KeyCode == Keys.Down || e.KeyCode == Keys.Up)
{
return;
}
base.OnKeyDown(e);
}

protected override void OnKeyUp(KeyEventArgs e)
{
if (e.KeyCode == Keys.Down || e.KeyCode == Keys.Up)
{
return;
}
base.OnKeyUp(e);
}
}
}

توجه کن که فقط دو متد OnKeyDown و OnKeyUp رو اضافه کردم و برنامه و این کلاس کلا بدون تغییر باقی مونده.حالا کافیه کامپالش کنی و لذتشو ببری.
در ضمن پیشنهاد می کنم تا جایی که ممکنه در فایل های کد طراحی (در این برنامه مانند فایل Form1_Designer.cs( اصلا تغییر مهمی ایجاد نکن (در حد همون تغییراتی که گفتم فقط انجام بده).چون تغییر جدی باعث می شه که دیگه فرم توی حالت طراحی باز نشه مثل همین فرم Form1 برنامه و این یعنی اول یه دردسر!!

موفق باشی

Sal_64
جمعه 26 مهر 1387, 11:22 صبح
سلام

من این کد رو اضافه کرده بودم و همونطور که گفتم با زدن Up و Down اتفاقی رخ نمی ده چطور توی فرم برنامه بتونم ازش استفاده و هدایتش کنم

اگه یه قطعه کد بزارید ممنون میشم

با تشکر

SMRAH1
جمعه 26 مهر 1387, 18:59 عصر
خوب نباید اتفاقی رخ بده.به عبارت دیگه قبلا با زدن دکمه های جهت بر بالا و پایین،انتخاب ما به بالا و پایین حرکت می کرد ولی با این کد دیگه این اتفاق نمی افته یعنی انتخاب ما به بالا و پایین حرکت نمی کنه.
برای کنترل پیغامهای صفحه کلید هم باید مثلا توی دستور :


if (e.KeyCode == Keys.Down || e.KeyCode == Keys.Up)
{
//DO Work Here
}

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

موفق باشید

Sal_64
جمعه 26 مهر 1387, 19:44 عصر
سلام

سوال رو جور دیگه ای مطرح می کنم

نمونه کدی که گذاشتم و شما اون رو تصحیح کردین ، اگه دقت کنین یک رویداد KeyDown توی فرم یک تعریف شده بود که توی اون برای یه سری کلیدها (اعداد و Back) و همچنین up , down کد نوشته شده بود و بعد از اضافه کردن اون قطعه کد آخری (مربوط به رویدادها) به کلاس ، باعث شد که رویدادی که از قبل توی فرم وجود داشت(Key Down) برای (اعداد و Back) به درستی کار کنه اما برای Up و Down خیر

حتی با MessagBox هم امتحان کردم حتی با زدن Up و Down وارد رویداد KeyDown هم نمیشه آیا باید رویداد رو دوباره و اون هم با کد نویسی ایجاد کنم ، ولی چرا برای باقی کلیدها جواب میده.:ناراحت:

مشکل کجاست ؟؟

SMRAH1
جمعه 26 مهر 1387, 21:36 عصر
خوب دوست من،اگر دقت کنید ملاحظه می کنید که مثلا در کلاس CustomDataGridView،اگر OnKeyDown وOnKeyUp رو پیاده سازی کنید،عملا به این کنترل دستور داره اید که قبل از پردازش فرم روی کنترل شما (همان متد dgv_KeyDown در فرم) کنترل خودش،یک پردازش انجام دهد که در این پردازش (مطابق پیاده سازی بالا) هر گاه که دکمه های جهت بر بالا و پایین فشرده شوند،کنترل آنها را نادیده می گیرد (توجه کنید که برای تمام کلید های دیگر به غیر از این دو کلید دستور:

base.OnKeyUp(e);که باعث می شود کلید های ورودی پردازش شوند ،فراخوانی می شوند در نتیجه کنترل کار خود را به درست انجام می دهد و بعد از پردازش خود متد dgv_KeyDown رو فراخوانی می کند.ولی اگر شما مثلا کلید جهت بر پایین را بزنید،ابتدا پیغام به OnKeyDown در CustomDataGridView می رسد و این کنترل این پیغام را در نطفه خفه می کند تا صدایش به کنترل اصلی نرسد:قهقهه:).
اما اگر می خواهید که این کنترل فقط باعث عدم حرکت به بالا و پایین انتخاب نشود ولی باز هم متد dgv_KeyDown مربوط به فرم را فراخوانی کند،باید کمی بیشتر توضیح دهم.

موفق باشید

Sal_64
جمعه 26 مهر 1387, 21:55 عصر
سلام

داخل صورت سوال (اولین سوال) توضیحات دادم
در واقع الان هم همان است


در رویداد keydown دیتاگرید ویو زمانی که UpویاDown زده شد سطر انتخاب شده تغییر نکند (در سطرها پیمایش انجام نشود) و بعد ازاون با کد نویسی روی این دو کلید کار دلخواه رو بشه انجام داد

و اون کار دلخواه هم اینه که خودم با دادن اندیس شروع پیمایش(بالا یا پایین رفتن) در سطرهای دیتاگرید رو مدیریت کنم


با تشکر

SMRAH1
شنبه 27 مهر 1387, 12:49 عصر
سلام

در کلاس CustomDataGridView دو Event جديد با نامهاي MyKeyDown و MyKeyUp معرفي کردم.درحالتي که کاربر دکمه هاي جهت بر بالا و پايين رو بزنه،اين دوتا رويداد به جاي رويداد هاي پيشفرض KeyDown و KeyUp رخ ميده.براي دريافت اين دوتا ويداد هم در پنجره خصوصيات مي تونيد پيداشون کنيد.در برنامه ضميمه هم يک نمونه کارکرد اونها رو نشون دادم.

موفق باشيد

Sal_64
شنبه 27 مهر 1387, 15:43 عصر
سلام

تشکر

اما در نمونه کد شما ، پنجره Design مربوط به فرم 1 باز نمیشه :ناراحت:

SMRAH1
شنبه 27 مهر 1387, 17:26 عصر
سلام

یک project>Rebiuld Solution بزنید بعد پنجره طراحی فرم 1 رو باز کنید.البته قبل از ساخت دوباره ،VS از شما مسیر ذخیره sln برنامه رو می خواد که کافیه فقط OK کنید.

دلیلش اینه که بعضی از پوشه های اضافی برنامه رو (obj و bin) رو حذف کردم و چون از یک کنترل سفارشی استفاه شده،برنامه مشکل پیدا می کنه.با ساخت دوباره پروژه،این پوشه ها با تنظیاتشون درست میشوند و برنامه به شکل مناسب فرم رو خواهد خوند.

دلیل حذف این پوشه ها هم اولا کم کردن از حجم کدها و ثانیا (و مهمتر) اینکه برخی اطلاعات کامپیوتر کامپایل کننده از جمله مسیر کامل پروژه رو توی کامپیوتر من و .. رو میده که بهتره حذف بشن:چشمک:.

موفق باشید