أهم أقسام المدونة

الصفحات

الجمعة، 20 ديسمبر 2013

طالب مندس!!


طالب مندس!!

 

من أطرف المواقف التي حدث لي، أنني كنت معتادا على الذهاب لمقابلة صديقي م. محمد الزيني في كلية حاسبات ومعلومات القاهرة، وأحيانا كنت أحضر معه بعض المحاضرات أو حصص التمارين (السكاشن).. وفي إحدى هذه المرات كان عليهم امتحان في مادة التصميم المنطقي Logic Design، ونظرا لأني كنت قد درست هذه المادة في كلية الهندسة في العام السابق، فقد قررت أن أحضر معهم الامتحان.. وبالفعل أخذت ورقة أسئلة، وبدأت أحل اعتمادا على ما أتذكره من عام مضى، ولإكمال الطرافة، كتبت اسمي على الورقة وسلمتها J

طبعا لم أحصل على نصف الدرجات وإن كدت، لكن المفاجأة أن درجتي جاءت أعلى من تلك التي حصل عليها الزيني :))، وهو الأمر الذي كاد يصيبه بالجنون :)

والأطرف من هذا أن أستاذة المادة أخذت تنادي على اسمي في المحاضرة التالية لتعرف ورقة من هذه، وكيف لا يوجد هذا الاسم في قائمة طلابها، وهل يوجد أحد يعرفه أم لا.. وطبعا كتم الزيني وأصدقاؤه الذين يعرفونني من المدينة الجامعية ضحكاتهم بصعوبة!

 

الخميس، 12 ديسمبر 2013

إلغاء عجلة الفأرة في الأداة NumericUpDown


س: عند تحريك عجلة الفأرة أثناء وجود المؤشر Focus داخل الأداة NumericUpDown يتم إنقاص أو زيادة العدد الذي تعرضه الأداة.. فكيف يمكن منع هذا؟ 

ج: المكان المناسب لتعطيل أي وظيفة تؤديها عجلة الفأرة في أي أداة، هو الحدث MouseWheel.. لكن المعامل الثاني e لهذا الحدث من النوع MouseEventArgs، وهو لا يمتلك الخاصية Handled التي يمكن جعل قيمتها True لإلغاء الحدث.. فما العمل؟

المفاجأة هي أن المعامل e في الحدث MouseWheel (في كل الأدوات) هو في الحقيقة من نوع الفئة HandledMouseEventArgs التي تمتلك الخاصية Handled، لكن لسبب ما قررت ميكروسوفت أن تخفي عنك هذه الحقيقة وتكتب نوع المعامل من الفئة الأم MouseEventArgs.. لهذا كل ما عليك فعله هو تحويل نوع المعامل e إلى نوعه الأصلي، واستخدام الخاصية Handled الخاصة به لإلغاء حدث تحريك عجلة الفأرة كالتالي:

CType(e, HandledMouseEventArgs).Handled = True
وهذا هو كل شيء!

 

ملحوظة:

إذا أردت أيضا أن تمنع المستخدم من تغيير العدد المعروض في الأداة NumericUpDown عند ضغط السهم العلوي أو السهم السفلي من لوحة المفاتيح، فكل ما عليك هو وضع القيمة False في الخاصية InterceptArrowKeys:

NumericUpDown.InterceptArrowKeys = False

 

 

الاثنين، 9 ديسمبر 2013

لحظة عشق 1



(اضغط الصورة لتكبيرها)

 

لقراءة القصيدة كاملة:


للاستماع لإلقائي للقصيدة:


لتحميل ديوان دلال الورد:


 

 

 

 

 

الأحد، 8 ديسمبر 2013

تطوير لبرنامج لمحاكاة إلقاء العملة


تطوير لبرنامج لمحاكاة إلقاء العملة المعدنية
لدراسة احتمال الحصول على 100 صورة متتالية 

في الموضوع السابق شرحت فكرة إنشاء برنامج يحاكي عملية إلقاء عملة، ويدرس عدد الصور المتوالية التي يمكن الحصول عليها.

ذلك البرنامج كان يركز على حساب أقصى عدد من الصور يمكن الوصول إليه، لهذا كان يتجاهل بعض النتائج الأقصر من أقصى عدد حصلنا عليه، كما كان يتجاهل عدد مرات تكرار نفس النتيجة.

وقد قررت تطوير هذا البرنامج ليعطي صورة أشمل لمن يريد دراسة هذه الاحتمالات (على الأقل سيكون مفيدا كبرنامج توضيحي للطلاب الذين يدرسون علم الإحصاء).. لهذا جعلت البرنامج يأخذ في الاعتبار كل النتائج وعدد مرات تكرارها كما في الصورة:
 
 
يمكنكم تحميل كود هذا البرنامج من هنا:


الملاحظة الواضحة التي ستبرز لمن يدرس النتائج، هي أي التتابعات الأقصر للصور تحدث أسرع، وتتكرر أكثر.. فالحصول على صورة منفردة يحدث من أول بضع محاولات، ويتكرر ملايين المرات، والنسبة المئوية تظهر أن الصورة المنفردة تستأثر بحوالي نصف عدد النتائج التي نحصل عليها.. لاحظ أنني أحسب هذه النسبة المئوية بالقسمة على مجموع النتائج (مجموع القيم الموجودة في العمود "تكرار الحدوث").

ستلاحظ أيضا أن عدد مرات التكرار يقل إلى النصف كلما زدت عدد الصور المتتابعة بواحد.. فحدوث صورتين متتاليتين يستأثر بربع عدد النتائج.. وحدوث ثلاث صور متتابعة يستأثر بثمن عدد النتائج.. وهكذا يستمر القسمة على 2 كلمات زدنا عدد الصور المتتابعة بواحد.. وهذا ما يجعل مرات التكرار يقل بشكل أسي سريع، وهو ما يفسر لك لماذا يصير الحصول على عدد أكبر من الصور المتتابعة أصعب.. فالحصول على 6 صور متتابعة لم يحظ بأكثر من  1.25% من النتائج.. والحصول على 10 صور متتابعة شكّل أقل من 1 في الألف من النتائج.. أما حدوث 20 صورة متتابعة، فكان نصيبه حوالي 1 في المليون من النتائج!.. وكما تتوقع: حدوث 30 صورة متتالية نصيبه 1 في المليار من النتائج.. لاحظ أن زيادة 10 يعني القسمة على 2 عشر مرات.. 2 أس 10 يساوي 1024 ، ويمكننا اعتبار أنها تساوي 1000 للتسهيل.. هذا معناه أن كل 10 صور نضيفها للصور المتتابعة تقسم النسبة المئوية للناتج على 1000.. لهذا نتوقع أن تكون نسبة 40 صورة متتالية في النتائج هي 1 في التريليون، ونسبة 50 صورة هي 1/10 أس 15، ونسبة 60 صورة هي 1/10 أس 18، ونسبة 100 صورة  هي 1/10 أس 30، وهي النسبة التي أثبتنا مرارا وتكرارا أنها تساوي صفرا ولا يكفي عمر الكون لتوفير عدد كاف من المحاولات يجعلها تحدث.

 

ملاحظات:

- هذه النسخة المطورة من البرنامج أسرع من النسخة السابقة، حيث يمكنها تنفيذ حوالي 1.3 مليون محاولة في الثانية.. لكن لا تعتمد على هذا، فهو لن يقلل من مليارات السنين المنتظرة للحصول على 100 صورة متتابعة شيئا يذكر J

-  أقصى عدد من الخانات العشرية سمحت للبرنامج بعرضه في عمود نسبة التكرار، هو 15 خانة.. هذا معناه أن النسب المئوية الأصغر من هذا والتي تحتاج خانات عشرية أكثر، سيتم تقريبها إلى صفر.. لكن لكي ترى هذا، يجب أن تنتظر إلى أن يحدث تتابع أكثر من 50 صورة متتالية، وهو أمر يحتاج إلى ترك البرنامج يعمل لحوالي 27 سنة متواصلة لكي يكون حدوثه محتملا!

-  نظرا لأن النتائج لا تأتي بالترتيب، فمن الممكن أن يحدث تتابع 10 صور قبل أن يحدث تتابع 9 صور، فقد ظهرت الحاجة لترتيب النتائج (سابقا كنا نتجاهل النتيجة الأقصر لأننا نبحث عن النتائج التي تحوي أطول تتابع من الصور).. لهذا أضفت للبرنامج الفئة SortableBindingList لاستخدامها كمصدر ربط مع جدول العرض، بحيث يمكن ترتيب النتائج التي يعرضها.

-  لكي يمكن تحديث عدد مرات تكرار كل نتيجة، استخدمت قاموسا Dictionary، مفتاحه هو عدد مرات تتابع الصور، وقيمته هي البيانات الخاصة بالنتيجة المحفوظة كائن من نوع الفئة PictureInfo.. أي أننا صرنا نتعامل مع قاموس من النوع:

Dictionary(Of Integer, PictureInfo)

هذا القاموس لا يصلح كمصدر بيانات لجدول العرض، لهذا حصلنا منه على قائمة تصلح للربط كالتالي:

Coins.PicsInfo.Values.ToList

حيث إن الخاصية Values الخاصة بالقاموس تعيد مجموعة Collection تحتوي على كل القيم المحفوظة في القاموس (بدون المفاتيح).. لكن هذه المجموعة لا تصلح أيضا كمصدر ربط، لهذا حولناها إلى قائمة باستخدام الوسيلة ToList.

وستجد أننا أرسلنا التعبير السابق إلى حدث إنشاء الفئة SortableBindingList للحصول على قائمة قابلة للترتيب.

 

 

 

الجمعة، 6 ديسمبر 2013

الترتيب التلقائي لأعمدة DataGridView


س: عند ربط جدول العرض DataGridView بقائمة List فإن ضغط رؤوس الأعمدة لا يؤدي إلى إعادة ترتيب الجدول.. فلماذا؟.. وكيف يمكن حل هذه المشكلة؟ 

ج: عند ضغط رأس العمود لتنفيذ الترتيب التلقائي لجدول العرض تبعا لقيم هذا العمود، يطلب جدول العرض من مصدر البيانات DataSource المرتبط به أن يقوم هو بتنفيذ عملية الترتيب تبعا للخاصية التي يرتبط بها العمود المضغوط.. أي أن جدول العرض لا ينفذ أي شيء بنفسه.. لهذا يجب أن يكون مصدر البيانات قابلا للترتيب IsSortable = True.. وهذا غير متوفر في القوائم Lists والمجموعات Collections ولا حتى في قائمة الربط BindingList.

وبتتبع الأكواد التي تستخدمها ميكروسوفت في LinQ To SQL وجدت أنها تستخدم فئة خاصة اسمها SortableBindingList لتسمح بالترتيب عند عرضها في جدول العرض.. لكن الغريب أن ميكروسوفت جعلت هذه الفئة خاصة، ولا يمكن للمبرمج استخدامها.. لهذا عليك أن تكتب كود هذه الفئة بنفسك في مشاريعك.

وستجد كود هذه الفئة في هذا المشروع:


واستخدامها بسيط جدا، فهي فئة عامة Generic Type، يمكنك أن تخصصها لأي نوع تتعامل معه من البيانات، وليس عليك أكثر من أن ترسل إلى حدث إنشائها Constructor القائمة التي تريد أن تمنحها إمكانية الترتيب.. وستجدنا نستخدمها في المشروع المشار إليه على الصورة:

Dim SortedList As New SortableBindingList(

                               Of PictureInfo)(Coins.PicsInfo.Values.ToList)

DataGridView1.DataSource = SortedList

حيث:

- PictureInfo هو نوع البيانات المخزنة في القائمة، وهي فئة خاصة بي عرّفتها في المشروع.. هذا يوضح أنك تستطيع استخدام هذه الفئة مع أي نوع، سواء كان جزءا من إطار العمل أو خاصا بك.

- Coins.PicsInfo.Values هو مجموعة Collection تحتوي على عناصر من النوع PictureInfo.. ولتحويلها إلى قائمة استخدمنا الوسيلة الإضافية ToList، وهي الوسيلة التي ستستخدمها في الغالب لإرسال القائمة إلى حدث إنشاء الفئة SortableBindingList، لتحويل المجموعات العائدة من نتائج استعلامات LinQ إلى قوائم.

هذا كل شيء.. بعد هذا جعلنا مجموعة الربط القابلة للترتيب مصدر بيانات جدول العرض بإرسالها إلى الخاصية DataGridView.DataSource.. الآن يمكنك ترتيب الجدول تبعا لأي عمود فيه بمجرد ضغط العمود بدون كتابة أي كود إضافي.

ولا تسلني مرة أخرى لماذا لم تمنحنا ميكروسوفت هذه الإمكانية مباشرة ما دامت موجودة في إطار العمل وقررت أن تخفيها عنا، فأنا لا أعلم!

 

ملحوظة:

في الفئة SortableBindingList ستجد أنني حولت جزءا من الكود إلى تعليق في حدث إنشاء الفئة الداخلية PropertyComparer.. هذا الجزء من الكود سبب معي خطأ عندما كنت أتعامل مع نوع بيانات موروث من نوع آخر، لأن هذا الكود اعتبر أن الصفات الموروثة ليست خاصة بهذا النوع!!.. وقد وجدت أنه لا ضرورة لهذا الكود فحذفته، وعملت الفئة بعد ذلك على ما يرام!

 

الأربعاء، 4 ديسمبر 2013

ابتســــــامــة


ابتســــــامــة

 

بدرٌ مُضيءٌ ضاحكٌ، في سِحرِ طِيبتِهِ بَشاشةْ
في لَمحةٍ ما غيرُها، سهمًا رَمى عُمري فَناشَهْ
يا مَنْ سَبَتْ قلبَ الفتى مِن خلفِ حاسوبٍ وشاشةْ!
لَعِبَ الجمالُ بعقلِهِ وصوابَهُ عمدًا أطاشَهْ
فإذا لِفَرطِ جنونِهِ أمسَى كتوفيقٍ عكاشةْ!!
يا مَن خُطِفتُ بحُسنِها واستوطَنتْ صَدري ارتعاشةْ
قلبي غدا كَهُرَيرةٍ، أَجْمِلْ بكفّيكِ انكماشَهْ!
عيناكِ أنوارُ المَدَى، شوقي يُلبيها فَراشةْ
إنّي بِنارِكِ مُسهدٌ وعَذَرتُ مَن جافَى فِراشَهْ
يا لابتسامتِكِ التي كالنهرِ إذ يَروي عِطاشَهْ
أتَرَكْتِ ثَغري ظامئًا وزهورُ خدّيكِ انتعاشةْ؟
يا لؤلؤا أغرَى بهِ: ماذا عن الشفتينِ حاشَهْ؟
شفتاكِ قطعةُ سكّرٍ وتذوبُ من فَرطِ الهشاشةْ
هلاّ أجبتِ مُحيَّرًا لم يُبقِ مِن لَهَفٍ حُشاشةْ:
هل حلمُهُ فيكِ اهتدَى أم أنّهُ في الوهمِ عاشَهْ؟


محمد حمدي غانم

11/8/2013

برنامج لمحاكاة إلقاء العملة المعدنية


برنامج لمحاكاة إلقاء العملة المعدنية
لدراسة احتمال الحصول على 100 صورة متتالية
 

تطرقت في كتاب "خرافة داروين" إلى هذه المسألة، كمدخل بسيط ومختصر لكيفية حساب الاحتمالات، أدلل به على استحالة أن تصنع الصدفة أي شيء مركّب، مفيدا كان أو غير مفيد.. وأثبتّ رياضيا أن الحصول على مئة صورة متتالية عند إلقاء العملة المعدنية هو أمر مستحيل، حتى لو ظل كل سكان كوكب الأرض البالغ عددهم 7 مليارات إنسان، يلقون العملة المعدنية بمعدل مرة في الثانية لمدة 300 مليار سنة!!

السبب في هذا أن هذا الاحتمال يساوي 1/2 أس 100، أي 1/1267650600228229401496703205376، وهو يساوي صفرا بلا جدال، لأن الرقم الموجود في المقام أكبر من تصوراتنا العلمية للمالانهاية، ويعجز الحاسوب عن محاكاته ولو بمجرد العد (أثبتّ هذا برمجيا أيضا في الكتاب نفسه).

لكن نظرا لأن غير المتخصصين قد يتشككون في هذه الاحتمالات ويعجزن عن تخيل فداحة هذه الأرقام التي تتكون من أكثر من 30 خانة عشرية، قررت أن أكتب برنامجا يحاكي عملية إلقاء عملة معدنية، ويسجل عدد مرات تكرار الصور على التوالي.

فكرة هذا البرنامج بسيطة، فهو يحصل على عدد صحيح عشوائي، فإن كان هذا العدد زوجيا نعتبر أننا حصلنا على صورة، وإن كان فرديا نعتبر أننا حصلنا على كتابة.. ويسجل البرنامج عدد مرات الحصول على صور على التوالي وعدد محاولات إلقاء العملة التي نتج بعدها هذا العدد من الصور المتتابعة، لكي ندرك مقدار التجريب العشوائي الذي نحتاجه.. ويعرض البرنامج هذه النتائج كما في الشاشة:

يمكنكم تحميل كود البرنامج من هنا:


والآن دعونا نعلّق على هذا البرنامج.. سيكون لدينا هنا تعليق خاص للمبرمجين، وتعليق عام على فكرة الصدفة والعشوائية التي كتبنا البرنامج من أجلها.

الجمعة، 29 نوفمبر 2013

كتاب خرافة داروين


كتاب:
خرافة داروين: حينما تتحول الصدفة إلى علم!!
نسف نظرية داروين باستخدام الرياضيات والبرمجة 




بقلم:
م. محمد حمدي غانم 

للتحميل:
أو
 


يستخدم هذا الكتاب الرياضيات والإحصاء لنفي فكرة التطور العشوائي، ويقدم بعض برامج الحاسوب التي تدعم هذه الإثباتات (مرفق بالكتاب ثلاثة مشاريع مكتوبة بلغة فيجوال بيزيك دوت نت).

كما أن الكتاب يوضّح التناظر بين بنية الحاسوب وأنظمة تشغيله من جهة، وبين المخلوقات الحية وشفرة DNA التي تبني أجسادها وتتحكم في وظائفها من جهة أخرى.

وفي نهاية الكتاب، تقديم وعرض ونقاش للفيلم الوثائقي Expelled الذي ترجمه المؤلف، مع روابطه على يوتيوب.. هذا الفيلم يناقش نظرية التصميم الذكي التي تشق طريقها الآن في الأوساط العلمية الغربية كنقيض لنظرية التطور، ويوضح الفيلم مدى الاضطهاد والإقصاء الذي يتعرض له العلماء الذين يتبنون هذه النظرية، لدرجة رفتهم من وظائفهم ومنعهم من النشر.

 

المحتويات

 

·    تمهيد: الداروينية: من سببية العلم، إلى عشوائية الصدفة

- الداروينية القديمة، والتطور بالانتخاب الطبيعي

- الداروينية الجديدة، والتطور بالطفرات

 

·      أبدع حاسب وأبدع نظام تشغيل

1. الإنسان يطوّر، لكن لا يخلق

2. لغة الكيمياء

3. تطبيقات برمجية ونظام تشغيل

4. الدقّة حيث لا مجال للعبث

5. مصانع عالية التقنية

6. فبأيّ حديث بعده يؤمنون؟

7. وللرياضيات كلمة

8. برنامج لمحاكاة إلقاء العملة المعدنية

9. إنهم يعبدون الصدفة!

10. رواية الحصن الرقمى: دان براون يخدعك!

11. برنامج لرسم الموناليزا بالصدفة!

12. برنامج لتوليد الكلمات والنصوص عشوائيا

13. التدخل البشري في إنتاج أول صبغ وراثي صناعي

14. إنتاج البشر

15. البعث والحساب علميا

16. لكن لماذا يكفرون؟

17. البحث عن الضلال

18. نحن نأكل البشر

19. من نحن؟

20. البرامج الحية

 

·      الحلقات المفقودة في الداروينية الفقيدة!.. هيا نفند نظرية داروين في خمسة أسئلة!

1- كيف ظهرت الحلقات الوسيطة بالصدفة؟

2- لماذا ما تزال الحلقات المفقودة مفقودة حتى الآن؟

3- لماذا انقرضت الحلقات الوسيطة أصلا؟

4- لماذا لا تتطور حلقات وسيطة جديدة في عالمنا اليوم؟

5- أين هي حفريات المحاولات التطورية الفاشلة؟

- الخاتمة: الداروينية علم أم دين؟!

 

·    ناندينو كمبورس

 

·    التصميم الذكي Intelligent Design

 

·    مطرودون: لا يُسمح بالذكاء! Expelled: No intelligence allowed

- المقطع الأول من الفيلم الوثائقي Expelled

- المقطع الثاني من الفيلم الوثائقي Expelled

- المقطع الثالث من الفيلم الوثائقي Expelled

- المقطع الرابع من الفيلم الوثائقي Expelled

- المقطع الخامس من الفيلم الوثائقي Expelled

- المقطع السادس من الفيلم الوثائقي Expelled

- المقطع السابع من الفيلم الوثائقي Expelled

- المقطع الثامن من الفيلم الوثائقي Expelled

- المقطع التاسع من الفيلم الوثائقي Expelled

- المقطع العاشر من الفيلم الوثائقي Expelled

 

 

 

 

 

الأربعاء، 27 نوفمبر 2013

استخدام فئة التفقيط


استخدام فئة التفقيط 


 

في الموضوع السابق، وضعت لكم كود الفئة NumericToLiteral التي تقوم بتحويل الأعداد من الصيغة الرقمية إلى الصيغة الحرفية.. الكود موجود أيضا داخل ملف المشروع المرفق بهذا الموضوع، ويمكنكم تحميله من هذا الرابط:


نريد الآن معرفة كيفية التعامل مع الفئة NumericToLiteral.

هذه الفئة تمتلك وسيلة واحدة مشتركة Shared يمكن استدعاؤها من اسم الفئة مباشرة، وهي الوسيلة Convert.. والمثال التالي يريك كيف تحول الرقم 225 إلى تمثيله النصي:

Dim LiteralNo = NumericToLiteral.Convert(225)

MsgBox(LiteralNo)

عند تنفيذ هذا الكود، ستعرض الرسالة النص:

(مئتان وخمسة وعشرون)

ملاحظات:

1- أقصى عدد تتعامل معه هذه الفئة هو 9,223,372,036,854,775,807.. والتمثيل النصي له هو:

(تسعة كوينتيليونات، ومئتان وثلاثة وعشرون كدريليونا، وثلاثمئة واثنان وسبعون تريليونا، وستة وثلاثون مليارا، وثمانمئة وأربعة وخمسون مليونا، وسبعمئة وخمسة وسبعون ألفا، وثمانمئة وسبعة)

حيث إن:

الاثنين، 25 نوفمبر 2013

تحويل الأعداد إلى الصيغة الحرفية (التفقيط)


س: هل يمكن برمجيا، تحويل العدد من الصيغة الرقمية (مثل 225) إلى الصيغة الحرفية (مثل مئتان واثنان وعشرون) لاستخدامها في التفقيط؟ 

ج: نعم ممكن.. وقد وجدت فئة مكتوبة بالجافا سكربت تقوم بهذا الأمر، مؤلفها الأخ MazenB، وقد بذل فيها جهدا يستحق الشكر لمراعاة بعض القواعد العربية، وقد أخذت أنا هذه الفئة وحولتها إلى فيجوال بيزيك وأصلحت بعض أخطائها، وأدخلت عليها بعض التعديلات والإضافات لضبط نحو اللغة العربية، فيما يتعلق بنصب تمييز العدد في بعض الحالات (مثل خمسة عشر ألفا)، وحذف نون المثنى عند الإضافة (مثل مئتا ألف)، ومراعاة قواعد التأنيث والتذكير بين العدد وتمييزه، وكذلك مراعاة إفراد تمييز العدد أو جمعه (مثل: ثلاث نساء، تسع عشرة امرأة).. وأظن أن الفئة بهذه الصيغة صارت منضبطة على قواعد اللغة العربية تمام الانضباط.
كما أني وضعت بعض علامات الترقيم في الصيغة الناتجة لجعلها أكثر وضوحا، فوضعت فاصلة بعد مواضع الآلاف والملايين والمليارت... إلخ، ووضعت الصيغة كلها بين قوسين لفصلها عن تمييز العدد إن تم ذكره.

إليكم كود الفئة، وسأشرح لكم كيفية استخدامها في موضوع لاحق بإذن الله:

السبت، 23 نوفمبر 2013

حكاية البحر 1


(اضغط الصورة لتكبيرها)
لقراءة القصيدة كاملة:
للاستماع لإلقائي للقصيدة:

 

 

الخميس، 21 نوفمبر 2013

الإشارة إلى عمود في DataGridView


عند التعامل مع خانة في جدول العرض DatagridView أنصحك ألا تستخدم رقم العمود للإشارة إلى الخانة مثل:

DatagridView1.Rows(0).Cells(1).Value = "Ahmed"

لأنك قد تغير موضع العمود بعد ذلك أو تضيف أعمدة أخرى قبله تؤدي على تغيير ترقيمه، مما يضع عليك عبء إعادة تغير كل الأكواد التي تحتوي على أرقام الأعمدة.

أنصحك أيضا ألا تستخدم اسم العمود للإشارة إلى الخانة مثل:

DatagridView1.Rows(0).Cells("StudentName").Value = "Ahmed"

فحتى لو لم تكن ستغير اسم العمود بعد هذا، فكتابة اسم نصي بهذه الطريقة قد يجعلك تخطئ في كتابته، فيحدث خطأ عند تنفيذ البرنامج.

إذن فما أنسب حل؟

أسهل حل لهذا الأمر، هو منح الأعمدة عند تعريفها في جدول العرض أسماء برمجية واضحة (مثل ColStudentName)، واستخدام الخاصية Index الخاصة بكائن العمود للحصول على رقمه للإشارة إلى الخانة من خلاله مثل:

DatagridView1.Rows(0).Cells(ColStudentName.Index).Value = "Ahmed"

بهذه الطريقة لن يتأثر الكود بتغيير موضع العمود بعد ذلك، وفي نفس الوقت هذا الكود واضح وقابل للقراءة والفهم كما في حالة استخدام الاسم النصي للعمود، لكن بدون أي احتمال للخطأ في كتابة الاسم.

الأربعاء، 20 نوفمبر 2013

حين التقينا 1


(اضغط الصورة لتكبيرها)

لقراءة القصيدة كاملة:
لتحميل ديوان "دلال الورد":

الاثنين، 18 نوفمبر 2013

القاسية1


(اضغط الصورة لتكبيرها)

لقراءة القصيدة كاملة:
للاستماع لإلقائي للقصيدة:
لتحميل ديوان "دلال الورد":
 

 

 

التضارب في ربط البيانات


س: أستخدم ربط البيانات DataBindings لربط التاريخ الذي تعرضه الأداة DateTimePicker بمصدر ربط BindingSource.. لكن مشكلة غريبة تحدث عند تغيير التاريخ في الأداة DateTimePicker والانتقال إلى أداة أخرى على النافذة وتغيير قيمتها ثم ضغط الزر Tab لمغادرتها، ففي هذه اللحظة يعود التاريخ الذي تعرضه الأداة DateTimePicker إلى قيمته الأصلية قبل التغيير!.. فكيف يمكن حل هذه المشكلة؟

 

ج: من الواضح أن كائن ربط البيانات Binding Object لم ينقل التاريخ الجديد الذي تم اختياره في الأداة DateTimePicker إلى كائن مصدر الربط BindingSource عند مغادرة الأداة، وأن تغيير قيمة الأداة الأخرى ثم مغادرتها أدى إلى تحديث بيانات مصدر الربط، فقام بدوره بتحديث التاريخ في الأداة DateTimePicker فعاد إلى قيمته الأولى!

من ملاحظاتي، فإن هذا الخطأ يحدث في الأدوات المرتبطة بمصدر ربط، عندما تكتب كودا في حدث تغير قيمة الأداة (مثل الحدث DateTimePicker.ValueChanged) تقوم فيه بتحديث قيم أدوات أخرى مرتبطة بنفس مصدر الربط.. هنا يحدث التضارب، لأن أداة اختيار التاريخ لم تنقل قيمتها الجديدة لمصدر الربط، بينما قامت بتغيير قيم أدوات أخرى حدّثت بيانات مصدر الربط الذي ما زال لا يرى إلا القيمة القديمة للتاريخ!.. لهذا يمكن أن يتكرر مثل هذا الخطأ في أدوات أخرى مثل NumericUpDown وغيرها.

ولحل هذه المشكلة، يجب ألا تكتب أي كود في حدث تغير قيمة الأداة ValueChanged.. أحيانا لا يكون الحل ممكنا، لهذا يمكنك استخدام حل أفضل، وهو إجبار كائن الربط على إرسال التاريخ الجديد إلى مصدر الربط بعد تغييره مباشرة.. أسهل طريقة لفعل هذا هي جعل القيمة تنتقل بمجرد تغير الخاصية DateTimePicker.Value بدلا من نقل القيمة بعد إجازة البيانات Validation (وهو التصرف الافتراضي لكائن الربط).. إذا كنت تستخدم الكود في عملية الربط، فعدله ليكون كالتالي:

DateTimePicker1.DataBindings.Add(New Binding(

         "Value", BindingSource1, "Date", True,

          DataSourceUpdateMode.OnPropertyChanged))

أما إذا كنت تستخدم نافذة الخصائص، فحدد الأداة DateTimePicker1 على النافذة، واضغط F4 لعرض نافذة الخصائص، وفيها أسدل الخصائص الفرعية للعنصر (DataBindings) واضغط الزر الموجود في خانة العنصر (Advanced)، وفي النافذة التي ستظهر اختر الخاصية Value من قائمة الخصائص، ومن القائمة المنسدلة المعنونة بـ Data Source Update Mode اختر القيمة OnPropertyChanged، واضغط OK.

بهذه الطريقة سينتقل التاريخ من الأداة DateTimePicker إلى مصدر الربط بمجرد حدوث التغيير، ودون انتظار مغادرة الأداة، مما سيمنع أية أخطاء غير متوقعة كالخطأ المذكور.

 

ملحوظة:

نقل التاريخ إلى مصدر الربط فور اختيار المستخدم له، يعتبر تصرفا جيدا عليك باتباعه دائما، فأنت لا تحتاج إلى إجازة البيانات Validation هنا فلا يمكن للمستخدم أن يكتب قيمة خاطئة في الأداة DateTimePicker، خاصة إذا ضبطت قيمتي الخاصيتين MinDate و MaxDate لمنعه من اختيار أي تاريخ خارج نطاق التواريخ المناسب لوظيفة برنامجك.