المتابعون للمدونة

السبت، 27 سبتمبر 2014

أداة اختيار اللون في WPF


 
 
وأنا أجهز مشروعا مكتوبا بـ WPF لرسم المخططات Diagram Designer لأستعين به في شرح قدرات الرسم والتلوين في الكتاب الجديد بإذن الله، احتجت لأداة تسمح للمستخدم باختيار الألوان (مثل الأداة ColorDialog في مشاريع نماذج الويندوز)، لكن للأسف هذه الأداة لا توجد جاهزة في WPF.. السبب في هذا أن WPF لا تتعامل مع الألوان فحسب بل مع الفرشاة Brush التي ترسمها، فكل جزء في الأداة تستطيع تلوينه بفرشاة من أي نوع (فرشاة مصمتة، فرشات تدرج، فرشاة رسم.. إلخ)، مما يسمح لك بالحصول على تأثيرات مدهشة وإمكانيات بلا حدود.

وبالبحث في جوجيل وجدت عدة أدوات لاختيار اللون (الفرشاة بالأحرى)، وكان أفضلها هذه الأداة:


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

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

وسأضع لكم الأداة المعدلة بإذن الله في موضوع تال بعد ضبط بعض خصائصها واختبارها.

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

لا تصدقني؟.. فليكن.. انظر لصورة مشروع رسم المخططات، ودعني أخبرك بما يلي:

-  اللوحة التي أرسم عليها الأشكال هي مربع قائمة ListBox عدلتها لأجعل عناصرها تُرسم على لوحة من النوع Canvas، وبهذا صار بالإمكان تحريك عناصر القائمة بحرية دون أن تكون متراصة كما هو مألوف في القوائم!

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

-  خطوط شبكة الرسم البياني مرسومة بفرشاة تبليط TileBrush، تكرر رسم مستطيل أبعاده 1 سم × 1 سم على لوحة الرسم.

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

-  صندوق الأدوات الذي يعرض رموز الأشكال المستخدمة في الرسم، صممته ليسمح لك بإضافة أي أشكال تريدها من خارج البرنامج، فهو ينظر في المجلد ToolBox، وكل مجلد يجده داخله ينشئ له شريطا باسمه على صندوق الأدوات، ويضع عليه الأدوات المعرفة في ملفات xaml الموجودة داخل هذا المجلد!.. وهذا معناه أنك تستطيع تعريف أي أشكال بكود xaml ووضعها في هذا المجلد، ليتم عرضها في صندوق الأدوات.. هذه الأشكال يمكن أن تكون أدوات Wpf أو رسوما هندسية أو صورا أو حتى فديوهات!!

هل صدقتني الآن أن الأمر مذهل ويعتبر نقلة كبيرة بالنسبة لمبرمجي نماذج الويندوز؟

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

 

 

الجمعة، 19 سبتمبر 2014

ساعات


ساعات 

بتفوت حاجات وتموت حاجات
وحاجات ساعات بتجيني تاني
وأنا عمري ما وقفت ف مكاني
ألحاني تتحدى السكات
سامحيني يا أحلى البنات
قطر الساعات سايقه بجناني
يبقى أنتي ليه مستنياني؟


محمد حمدي غانم
19/9/2014

 

الخميس، 18 سبتمبر 2014

Reflection C#


لمبرمجي سي شارب:
استخدام الانعكاس Reflection لتغيير طريقة عمل بعض أدوات دوت نت بدون إعادة كتابة كودها من البداية
(يمكن قراءة نسخة فيجوال بيزيك من هنا)

 

كلنا يعلم أن العناصر الخاصة Private Members المعرّفة داخل أي فئة Class لا يمكن التعامل معها إلا من داخل هذه الفئة.. هذه هي القاعدة العامة، لكن المثير في الأمر أنك تستطيع كسر هذه القاعدة باستخدام تقنية الانعكاس Reflection.

يوجد في إطار العمل .NET Framework نطاق اسمه System.Reflection يحتوي على الفئات اللازمة للتعامل مع ملفات التجميع Assemblies والحصول على معلومات عما تحتويه من فئات وسجلات Structures، وما تحتويه هذه العناصر من خصائص ووسائل.. هذا مفيد في حالات كثيرة (مثلا: عند إنشاء مترجم كود Compiler يعمل على دوت نت، أو عند كتابة كود ينسخ كائنا نسخا عميقا Deep Cloning.. إلخ).

ويمكننا استخدام تقنية الانعكاس للبحث في كائن (اسمه Obj مثلا) عن خاصية لها اسم معين (وليكن Prop1) والحصول على قيمتها بالكود التالي:

Type type = Obj.GetType();

PropertyInfo pr = type.GetProperty("Prop1", BindingFlags.Instance | BindingFlags.NonPublic);

var Value = pr.GetValue(Obj, null);

ويمكن تغيير قيمة الخاصية (مثلا إلى القيمة Test) كالتالي:

pr.SetValue(Obj, "Test", null);

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

Reflection


س: هل يمكنني أن أغير قيمة خاصية غير عامة Private Property موجودة داخل فئة من فئات إطار العمل؟!.. وهل يمكنني تغيير طريقة عمل بعض أدوات دوت نت بدون إعادة كتابة كودها من البداية؟ 

ج: نعم!


كلنا يعلم أن العناصر الخاصة Private Members المعرّفة داخل أي فئة Class لا يمكن التعامل معها إلا من داخل هذه الفئة.. هذه هي القاعدة العامة، لكن المثير في الأمر أنك تستطيع كسر هذه القاعدة باستخدام تقنية الانعكاس Reflection.

يوجد في إطار العمل .NET Framework نطاق اسمه System.Reflection يحتوي على الفئات اللازمة للتعامل مع ملفات التجميع Assemblies والحصول على معلومات عما تحتويه من فئات وسجلات Structures، وما تحتويه هذه العناصر من خصائص ووسائل.. هذا مفيد في حالات كثيرة (مثلا: عند إنشاء مترجم كود Compiler يعمل على دوت نت، أو عند كتابة كود ينسخ كائنا نسخا عميقا Deep Cloning.. إلخ).

ويمكننا استخدام تقنية الانعكاس للبحث في كائن (اسمه Obj مثلا) عن خاصية لها اسم معين (وليكن Prop1) والحصول على قيمتها بالكود التالي:

Dim type As Type = Obj.GetType( )

Dim pr As PropertyInfo = type.GetProperty("Prop1", BindingFlags.Instance Or BindingFlags.NonPublic)

Dim Value  =   pr.GetValue(Obj, Nothing)

ويمكن تغيير قيمة الخاصية (مثلا إلى القيمة Test) كالتالي:

pr.SetValue(Obj, "Test", Nothing)

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

الأربعاء، 10 سبتمبر 2014

عينكِ سوسنة


عينكِ سوسنة 

عينكِ سوسنةٌ، والفـرحُ داعـبَها      النورُ يَسكـنُها، والشِّعـرُ غنّاها
مِن بينِ فتنتِها، في نظرةٍ منـحَتْ      مِـن كـلِّ أمنيةٍ قلـبي
تمـنّاها
بالعطرِ، مُنسكبٌ شـلالُ بَسمـتِها
     لا يرتوي ظمـئي إلا بسُكـناها
في وجنتيكِ  كما الأحلامِ تَشغَـفُنا      أزهـارُكِ المُشتَـهَى أنّا لثَمْناها
أقسمتُ من شَفَةٍ أصطـادُ لُؤلـؤةً      فالبوحُ أحسنُها واشتقتُ حُسْناها!
محمد حمدي غانم
3/10/2013

 

 

صفحة الشاعر