خلاصة الدرس :
ستتعلم من خلال هذا الدرس كيف تبني مكوناتك الخاصة لكي تستخدمها في برامجك المكتوبة من اجل .NET Compact Framework
كما ستتطلع على بعض طرق استخدام مكتبات الرسوميات GDI+ في .NET Compact Framework .
ملاحظة : هذه المقالة تعتبر ان المستخدم متآلف مع لغة البرمجة Visual C Sharp من ميكروسوفت .
المحتويات :
مقدمة
عرض المكون
البدء بالمشروع
مقدمة :
يعتبر بناء المكونات واحدة من أفضل الطرق البرمجية التي توفر على المبرمج تكرار كتابة الشيفرة نفسها من اجل كل برنامج يكتبه, كما ان استخدام المكونات يجعل البرنامج اوضح و ابسط حيث ان شيفرة المكون تكون مخفية
و مستقلة عن شيفرة البرنامج مما يجعل صيانة و تحديث البرنامج اسهل بكثير.
عرض المكون :
المكون الذي سنبنيه هو مكون ساعة تقليدية سنرسم دائرة السعة و نضع الارقام التي تشير إلى الوقت
و من ثم سنرسم العقارب الثلاثة مع تحديث حركتها لكل ثانية.
البدء بالمشروع :
شغل Visual Studio 2005 و قم بانشاء مشروع Windows Mobile 5.0 جديد , قم بتسمية المشروع PocketClockTest
كما في الصورة ادناه :
سيتم إنشاء مشروع Pocket PC جديد , اذهب الان إلى Solution Explorer (اذا لم تجده اذهب إلى قائمة View ثم Solution Explorer )
ثم انقر على المشروع باليمين و اختر من القائمة التي ستظهر Add ثم User Control
قم بتسمية المكون بـ AnalogClock ثم انقر موافق
الان ستفتح صفحة التصميم الخاصة بالمكون اضف مكون Timer من صندوق الادوات الخاص بـ Visual Studio
قم بضبط الخاصية Interval للمؤقت Timer على القيمة 1000 و ذلك لأننا نريد تحديث واجهة الساعة و تحريك العقارب كل ثانية.
انقر على مكون الـ Timer و اكتب في الحدث Tick له ما يلي:
Invalidate();
ليصبح كالتالي :
private void timer1_Tick(object sender, EventArgs e)
{
Invalidate();
}الهدف من التعليمة السابقة هو ارسال رسائل تشغل حدث رسم Paint للمكون و بالتالي فإن المكون سيتم تحديثه كل ثانية
الان ننتقل إلى مكوننا و نستعرض شيفرته
في الباني (Constractor) الخاص بالمكون نضع الشيفرة التالية :
timer1.Enabled = true;
و ذلك لتشغيل المؤقت مع انشاء المكون
فيصبح شكل الباني كالتالي :
public AnalogClock()
{
InitializeComponent();
//Enables the timer so the clock refreshes every second
timer1.Enabled = true;
}الان قم بكتابة الشيفرة التالية في المكون :
protected override void OnPaint(PaintEventArgs e)
{
//Calls the base class’s OnPaint method
base.OnPaint(e);
//Smoothes out the appearance of the control
// e.Graphics.SmoothingMode = SmoothingMode.AntiAlias;
//The center of the control, which is used as center for the clock
PointF center = new PointF(this.Width / 2, this.Height / 2);
//The distance of the text from the center
float textRadius = (Math.Min(Width, Height)-5 ) / 2;
//The distance of the margin points from the center
float outerRadius = Math.Min(Width, Height) / 2 - 5;
//The length of the hour line
float hourRadius = outerRadius * 6 / 9;
//The length of the minute line
float minuteRadius = outerRadius * 7 / 9;
//The length of the second line
float secondRadius = outerRadius * 8 / 9;
for (int i = 1; i <= 60; i++)
//Gets the angle of the outer dot
float angle = GetAngle(i / 5f, 12);
//Gets the location of the outer dot
PointF dotPoint = GetPoint(center, outerRadius, angle);
//Indicates the size of the point
int pointSize = 2;
//Is true when a large dot needs to be rendered
if (i % 5 == 0)
{
//Sets the size of the point to make it bigger
pointSize = 4;
//The hour number
string text = (i / 5).ToString();
SizeF sz = e.Graphics.MeasureString(text, Font);
//The point where the text should be rendered
PointF textPoint =
GetPoint(center, textRadius, angle);
//Offsets the text location so it is centered in that point.
textPoint.X -= sz.Width / 2;
textPoint.Y -= sz.Height / 2;
//Draws the hour number
e.Graphics.DrawString(text, Font,
new SolidBrush(this.ForeColor), textPoint.X,textPoint.Y);
}
Pen pen = new Pen(this.ForeColor, 1);
//Draws the outer dot of the clock
e.Graphics.DrawEllipse(pen, Convert.ToInt32(dotPoint.X - pointSize / 2),
Convert.ToInt32(dotPoint.Y - pointSize / 2), pointSize, pointSize);
pen.Dispose();
//Gets the system time
DateTime dt = DateTime.Now;
//Calculates the hour offset from the large outer dot
float min = ((float)dt.Minute) / 60;
//Calculates the angle of the hour line
float hourAngle = GetAngle(dt.Hour + min, 12);
//Calculates the angle of the minute line
float minuteAngle = GetAngle(dt.Minute, 60);
//Calculates the angle of the second line
float secondAngle = GetAngle(dt.Second, 60);
//Draws the clock lines
DrawLine(e.Graphics, Color.Black, 1, center, secondRadius,
secondAngle);
DrawLine(e.Graphics, Color.Black, 2, center, minuteRadius,
minuteAngle);
DrawLine(e.Graphics, Color.Black, 3, center, hourRadius,
hourAngle);
}
}
private float GetAngle(float clockValue, float divisions)
{
//Calculates the angle
return 360 - (360 * (clockValue) / divisions) + 90;
}
private PointF GetPoint(PointF center, float radius, float angle)
{
//Calculates the X coordinate of the point
float x = (float)Math.Cos(2 * Math.PI * angle / 360) * radius +
center.X;
//Calculates the Y coordinate of the point
float y = -(float)Math.Sin(2 * Math.PI * angle / 360) * radius +
center.Y;
return new PointF(x, y);
}
private void DrawLine(Graphics g, Color color, int penWidth, PointF
center, float radius, float angle)
{
//Calculates the end point of the line
PointF endPoint = GetPoint(center, radius, angle);
//Creates the pen used to render the line
Pen pen = new Pen(color, penWidth);
//Renders the line
g.DrawLine(pen ,Convert.ToInt32(center.X),Convert.ToInt32(center.Y),Convert.ToInt32(endPoint.X), Convert.ToInt32(endPoint.Y));
pen.Dispose();
}تجد فوق كل سطر مما سبق شرحا لوظيفة هذا السطر و لا داعي لإعادة الشرح لك
لكن الشيء الاساسي اننا قمنا بتحميل زائد للحدث OnPaint حتى نقوم بعمليات الرسم كما سأركز على نقطة مهمة واحدة نلاحظ انني استخدم PointF (و هي عبارة عن كائن نقطة يأخذ احداثيين من نوع Float) رغم انها غير مدعومة في .NET Compact Framework 2.0 لتجاوز عدم توافر الدعم لـ PointF في .NET Compact Framework 2.0 قمت بإنشاء بنية struct تحاكي عمل PointF في نسخة سطح المكتب كالتالي :
public struct PointF
{
public float X;
public float Y;
public PointF(float x, float y)
{
X = x;
Y = y;
}
}الان دعونا نضيف خاصية للساعة , سترغب باضافة مظهر جمالي للساعة من خلال اضافة خلفية
ما للساعة لذا قم بما يلي قم باضافة الشيفرة التالية :
private Image _BackImage = null;
public Image BackImage
{
get
{
return _BackImage;
}
set
{
if (value != _BackImage)
{
_BackImage = value;
Invalidate();
}
}
}من خلال هذه الشيفرة نحن نضيف خاصية اضافة الصورة للساعة في زمن التصميم
اذهب إلى الاجرائية OnPaint و اكتب في بدايتها ما يلي حتى ترسم الصورة على خلفية المكون :
if (_BackImage != null)
{
e.Graphics.DrawImage(_BackImage, 0,0);
}الان اذهب إلى القائمة Build و قم باختيار Build Solution اذا تم ترجمة التطبيق بدون مشاكل اذهب إلى النموذج الرئيسي للمشروع ثم و من صندوق
الادوات Tool Box ستجد موكن الساعة الذي انشأناه قم بإضافته للمشروع كما في الشكل :
الان اصبحت تمتلك مكونا للساعة الكلاسيكية تهانينا
ملاحظة : هذا الدرس في الاساس يعتمد على مثال في احد الكتب لدي مع بعض التعديلات ليتوافق مع محدودية .NET Compact Framework و بعض الاضافات و بعض الامور تم حذفها كي لا يطول الموضوع
تمام كوجان في 30/01/2007
ُEmail : TammamKoujan@Gmail.com
يجوز نشر هذه المقالة أو أجزاء منها بشرط المحافظة على اسم الكاتب و ذكر المصدر
اتمنى ان تستفيدوا من هذا الدرس
هذا الدرس متاح أيضا على مدونتي الشخصية على الرابط التالي :