تعاملنا في الدروس السابقة في هذه السلسلة مع عناصر مرئيّة وظيفتها الأساسيّة عرض البيانات بشكل مناسب إلى المستخدم. في الحقيقة يوجد نوع آخر من العناصر المرئيّة، يتضمّن تلك العناصر التي يمكن أن يتفاعل المستخدم معها لتنفيذ أمر أو مهمّة معيّنة. سنتناول في هذا الدرس الممتع عنصر الزر Button وهو عنصر مرئي يسمح للمستخدم عند نقره (أو بالأحرى لمسه) بأن ينفّذ أمرًا معيّنًا.
تطبيق العدّاد
وهو تطبيق بسيط، الغرض منه فهم كيفيّة التعامل مع الأزرار في Xamarin.Forms. تتكوّن واجهة هذا التطبيق من زرّين بالإضافة إلى لصيقة. فكرة التطبيق بسيطة، فعندما ينقر المستخدم أحد الزرّين يزداد العدد المعروض على اللصيقة بمقدار واحد، وعندما ينقر على الزر الآخر ينقص هذا العدد بمقدار واحد أيضًا.
أنشئ تطبيقًا جديدًا من النوع Blank App (Xamarin.Forms Portable) كما هو معتاد وسمّه CounterApp، وأبق فقط على المشروعين CounterApp.Droid و CounterApp (Portable) ضمنه. أضف صفحة محتوى ContentPage جديدة سمّها CounterPage. احرص على أن يكون محتوى الملف CounterPage.cs على الشكل التالي:
1 using System; 2 using Xamarin.Forms; 3 4 namespace CounterApp 5 { 6 public class CounterPage : ContentPage 7 { 8 private int counter = 0; 9 private Label lblDisplay; 10 11 public CounterPage() 12 { 13 Button btnIncrement = new Button 14 { 15 Text = "+", 16 HorizontalOptions = LayoutOptions.CenterAndExpand, 17 FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)) 18 }; 19 btnIncrement.Clicked += btnIncrement_Clicked; 20 21 Button btnDecrement = new Button 22 { 23 Text = "-", 24 HorizontalOptions = LayoutOptions.CenterAndExpand, 25 FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)) 26 }; 27 btnDecrement.Clicked += BtnDecrement_Clicked; 28 29 lblDisplay = new Label 30 { 31 Text = "0", 32 TextColor = Color.Accent, 33 HorizontalOptions = LayoutOptions.CenterAndExpand, 34 FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)) 35 }; 36 37 Content = new StackLayout 38 { 39 Children = { 40 new StackLayout 41 { 42 Orientation = StackOrientation.Horizontal, 43 Padding = new Thickness(0,64,0,64), 44 Children = 45 { 46 btnIncrement, 47 btnDecrement 48 } 49 }, 50 lblDisplay 51 } 52 }; 53 } 54 55 private void BtnDecrement_Clicked(object sender, EventArgs e) 56 { 57 counter--; 58 lblDisplay.Text = counter.ToString(); 59 } 60 61 private void btnIncrement_Clicked(object sender, EventArgs e) 62 { 63 counter++; 64 lblDisplay.Text = counter.ToString(); 65 } 66 } 67 }
ملاحظة
تذكّر أنّنا نضيف صفحة محتوى جديدة بالنقر بزر الفأرة الأيمن على المشروع CounterApp (Portable) ثم نختار Add وبعدها New Item، ومن النافذة التي تظهر، تختار Cross-Platform من القسم الأيسر، ومن القسم الأيمن نختار Forms ContentPage
لقد صادفنا العديد من التقنيّات المستخدمة في هذا التطبيق وذلك في الدروس السابقة. مع وجود بعض الأمور الجديدة. فمثلًا ولأوّل مرّة وضعنا مخطّط مكدّس ضمن آخر، وهذا أمر شائع كثيرًا في تصميم الواجهات.
صرّحنا في السطر 8 عن الحقل الخاص counter
وهو العدّاد الذي سيحتفظ بالقيمة الحالية للعدد المعروض ضمن اللصيقة، وأسندنا له القيمة الابتدائيّة 0. كما صرّحنا في السطر 9 عن الحقل الخاص lblCounter
الذي سيمثّل اللصيقة التي سنعرض ضمنها قيمة العدّاد Counter
. سنحتاج إلى كلّ من الحقلين السابقين ضمن توابع مختلفة من الصنف CounterPage
لذلك وضعناهما على شكل حقلين خاصّين بهذه الصورة.
صرّحنا ضمن البانية CounterPage
عن المتغيّر btnIncrement
من النوع Button
وأسندنا إليه كائن جديد من نوع زر Button
حيث أسندنا قيم الخصائص مباشرةً عند الإنشاء، ووظيفة هذا الزر زيادة قيمة المتغيّر counter
بمقدار واحد وعرض النتيجة ضمن اللصيقة كما سنرى لاحقًا. لاحظ أنّنا في السطر 19 قد أسندنا معالج الحدث Clicked
لهذا الزر. اسم هذا المعالج btnIncrement_Clicked
وقد صرّحنا عنه في الأسفل في الأسطر من 61 حتى 65. تكرّر نفس الأمر من أجل الزر btnDecrement
(الأسطر من 21 حتى 27) ومعالج الحدث الخاص به btnDecrement_Clicked
(الأسطر من 55 حتى 59) ووظيفة هذا الزر هي إنقاص قيمة المتغيّر counter
بمقدار واحد وعرض النتيجة ضمن اللصيقة.
إذا انتقلنا إلى الخاصيّة Content
للصنف CounterPage
(السطر 37)، فنجد أنّه يتم إسناد مخطّط مكدّس جديد وهو يمتلك اتجاهًا رأسيًّا افتراضيًّا كما وسبق أن أوضحنا في درس سابق. سنُسند الخاصيّة Children
له فحسب (السطر 39). تصرّح هذه الخاصيّة عن وجود ابنين لهذا المخطّط، الابن الأوّل هو مخطّط مكدّس آخر (الأسطر من 40 حتى 49)، والثاني هو اللصيقة lblDisplay
التي ستعرض العدد الحالي:
Children = { new StackLayout { Orientation = StackOrientation.Horizontal, Padding = new Thickness(0,64,0,64), Children = { btnIncrement, btnDecrement } }, lblDisplay }
بالنسبة لمخطّط المكدّس الابن كما يظهر من الشيفرة الأخيرة، لاحظ أنّنا نضبط خاصيّة الاتجاه Orientation
له لتكون أفقيّة StackOrientation.Horizontal
، كما وضعنا حشوة Padding مناسبة من الأعلى والأسفل لمحتواه، وأخيرًا أسندنا الخاصيّة Children
له بحيث تحتوي على ابنين هنا زرّي الزيادة btnIncrement
والإنقاص btnDecrement
كما هو واضح.
إذًا سيحتوي المخطّط المكدّس الابن (الداخلي) على زرّين متموضّعين في الوسط أفقيًّا، وسيحتوي المخطّط المكدّس الأب (الخارجي) على مخطّط مكدّس ابن، وعلى لصيقة وهما متموضّعان رأسيًّا.
انتقل إلى الملف App.cs واحرص على أن تكون بانية الصنف App
على الشكل التالي:
public App() { // The root page of your application MainPage = new CounterPage(); }
عند تنفيذ البرنامج باستخدام F5 ستحصل على شكل شبيه بما يلي، علمًا أنّني أجريت عدّة نقرات على كلّ من الزرّين:
تحسين تطبيق العدّاد
سنُجري بعض التحسينات البسيطة على تطبيق العدّاد السابق. حيث سنعيد هيكلة الشيفرة البرمجيّة بحيث نستخدم تعابير Lambda كمعالجات أحداث، بدلًا من توابع مستقلّة ضمن الصنف، وفي ذلك فائدة كبيرة، حيث يجعل ذلك الشيفرة البرمجيّة سهلة القراءة والصيانة إلى حدٍّ كبير، كما يمكننا عند ذلك أن نجعل الحقلين counter
و lblDisplay
عبارة عن متغيّرين محليّين ضمن بانية الصنف. سنضيف ميّزة بسيطة أخرى إلى هذا التطبيق تتمثّل في أنّ البرنامج سيرفض جعل قيمة العدّاد سالبة، حيث سيعرض رسالة بهذا الخصوص، ولا يُغيّر قيمة العدّاد في هذه الحالة.
أضف صفحة محتوى جديدة سمّها EnhancedCounterPage
واحرص على أن تكون محتويات الملف EnhancedCounterPage.cs
على الشكل التالي:
1 using Xamarin.Forms; 2 3 namespace CounterApp 4 { 5 public class EnhancedCounterPage : ContentPage 6 { 7 public EnhancedCounterPage() 8 { 9 int counter = 0; 10 11 Label lblDisplay = new Label 12 { 13 Text = "0", 14 TextColor = Color.Accent, 15 HorizontalOptions = LayoutOptions.CenterAndExpand, 16 FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)) 17 }; 18 19 Button btnIncrement = new Button 20 { 21 Text = "+", 22 HorizontalOptions = LayoutOptions.CenterAndExpand, 23 FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)) 24 }; 25 btnIncrement.Clicked += (s, e) => 26 { 27 counter++; 28 lblDisplay.Text = counter.ToString(); 29 }; 30 31 Button btnDecrement = new Button 32 { 33 Text = "-", 34 HorizontalOptions = LayoutOptions.CenterAndExpand, 35 FontSize = Device.GetNamedSize(NamedSize.Large, typeof(Label)) 36 }; 37 btnDecrement.Clicked += (s, e) => 38 { 39 if (counter == 0) 40 { 41 DisplayAlert("تحذير", "لا يمكن لقيمة العدّاد أن تكون أصغر من الصفر", "موافق"); 42 } 43 else 44 { 45 counter--; 46 lblDisplay.Text = counter.ToString(); 47 } 48 }; 49 50 Content = new StackLayout 51 { 52 Children = { 53 new StackLayout 54 { 55 Orientation = StackOrientation.Horizontal, 56 Padding = new Thickness(0,64,0,64), 57 Children = 58 { 59 btnIncrement, 60 btnDecrement 61 } 62 }, 63 lblDisplay 64 } 65 }; 66 } 67 } 68 }
جعلنا كل من الحقلين counter
وlblDisplay
عبارة عن متغيّرين محليّين (السطرين 9 و11). كما تجدر الملاحظة أنّ معالجات الأحداث التقليديّة قد اختفت، وحلّ محلّها تعابير Lambda. انظر إلى الزر btnIncrement
في الأسطر من 25 حتى 29:
btnIncrement.Clicked += (s, e) => { counter++; lblDisplay.Text = counter.ToString(); };
صرّحنا عن تعبير Lambda يقبل وسيطين s
و e
، ويعمل على زيادة قيمة المتغيّر counter
بمقدار 1 ويعرض النتيجة ضمن اللصيقة. نفس الأمر تمامًا يسري على الزر btnDecrement
. انظر إلى الأسطر من 37 حتى 48:
btnDecrement.Clicked += (s, e) => { if (counter == 0) { DisplayAlert("تحذير", "لا يمكن لقيمة العدّاد أن تكون أصغر من الصفر", "موافق"); } else { counter--; lblDisplay.Text = counter.ToString(); } };
الفرق الوحيد هنا أنّنا نختبر قيمة المتغيّر counter
في حال كان يساوي الصفر قبل إنقاصه، وبالتالي عرض رسالة مناسبة في حال كان كذلك من خلال التابع DisplayAlert
(وهو من الصنف ContentPage
وكان يمكن أن نصل إليه عن طريق الكلمة المحجوزة this
أيضًا). يحتاج التابع DisplayAlert
في أحد أشكاله (وهو الشكل المستخدم هنا) إلى ثلاثة وساط هي: عنوان الرسالة، والنص المعروض ضمنها، والنص المعروض على زر الإلغاء، على الترتيب. توجد أشكال أخرى سنتناولها تباعًا ضمن هذه السلسلة.
انتقل إلى الملف App.cs
وتأكّد أنّ بانية الصنف App
على الشكل التالي:
public App() { // The root page of your application MainPage = new EnhancedCounterPage(); }
نفّذ البرنامج وانقر الزر (-) مباشرةً أي عندما تكون القيمة الظاهرة على اللصيقة هي صفر، مما سيؤدّي إلى ظهور رسالة التنبيه كما في الشكل التالي:
الخلاصة
تناولنا في هذا الدرس مبادئ التعامل مع الأزرار في Xamarin.Forms من خلال تطبيقين أساسيّين يتفاعلان مع المستخدم. بالإضافة إلى الحديث عن كيفيّة عرض رسائل مخصّصة للمستخدم باستخدام التابع DisplayAlert
. هناك العديد من المزايا التي تتمتّع بها الأزرار في Xamarin.Forms. سنستعرض لاحقًا في هذه السلسلة للمزيد من المزايا الإضافيّة للأزرار بالإضافة إلى عناصر مرئيّة أخرى يمكن للمستخدم أن يتفاعل معها.
أفضل التعليقات
لا توجد أية تعليقات بعد
انضم إلى النقاش
يمكنك أن تنشر الآن وتسجل لاحقًا. إذا كان لديك حساب، فسجل الدخول الآن لتنشر باسم حسابك.