<?xml version="1.0"?>
<rss version="2.0"><channel><title>&#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629;: &#x645;&#x646;&#x635;&#x629; Xamarin</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/?d=2</link><description>&#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629;: &#x645;&#x646;&#x635;&#x629; Xamarin</description><language>ar</language><item><title>&#x62A;&#x637;&#x628;&#x64A;&#x642; &#x639;&#x645;&#x644;&#x64A;: &#x62A;&#x637;&#x628;&#x64A;&#x642; &#x642;&#x627;&#x631;&#x626; &#x627;&#x644;&#x62E;&#x644;&#x627;&#x635;&#x627;&#x62A; - &#x627;&#x644;&#x62C;&#x632;&#x621; &#x627;&#x644;&#x62B;&#x627;&#x646;&#x64A;</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D8%B9%D9%85%D9%84%D9%8A-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D9%82%D8%A7%D8%B1%D8%A6-%D8%A7%D9%84%D8%AE%D9%84%D8%A7%D8%B5%D8%A7%D8%AA-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%AB%D8%A7%D9%86%D9%8A-r493/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_05/main2.png.dece469fdecbcd78eca1a75e5117b201.png" /></p>

<p>
	سنتناول في هذا الدرس من <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/" rel="">سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms</a> الجزء الثاني من <a href="https://academy.hsoub.com/tags/feeds-reader/" rel="">تطبيق قارئ الخلاصات</a> الخاص بموقع أكاديميّة حسوب.
</p>

<p style="text-align: center;">
	<img alt="main2.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23450" data-unique="pffd7vb1z" src="https://academy.hsoub.com/uploads/monthly_2017_05/main2.png.0e5e9f660566aa39367bb02572fb1066.png"></p>

<p>
	<br>
	لقد بنينا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D8%B9%D9%85%D9%84%D9%8A-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D9%82%D8%A7%D8%B1%D8%A6-%D8%A7%D9%84%D8%AE%D9%84%D8%A7%D8%B5%D8%A7%D8%AA-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%A3%D9%88%D9%91%D9%84-r491/" rel="">الجزء الأوّل</a> تطبيق أساسي أسميناه BasicFeedReader وكانت وظيفته تنحصر في عرض خلاصات قسم مقالات البرمجة. سنطوّر هذه الفكرة من خلال إنشاء تطبيق جديد يعمل على إتاحة الإمكانية للمستخدم بأن يستعرض الخلاصات المتاحة من جميع أقسام الموقع. سيكون ذلك من خلال إضافة صفحة جديدة لعرض أقسام الموقع على شكل مجموعات. لنبدأ فورًا في بناء هذا التطبيق التي سيحتوي على بعض من المكوّنات المتطابقة مع سلفه.
</p>

<h2 id="بناء-تطبيق-قارئ-الخلاصات-المحسن">
	بناء تطبيق قارئ الخلاصات المحسّن
</h2>

<p>
	أنشئ مشروعًا جديدًا من النوع Blank App (Xamarin.Forms Portable) وسمّه EnhancedFeedReader ثم أبق فقط على المشروعين EnhancedFeedReader (Portable) و EnhancedFeedReader.Droid كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-visual-studio-2015-community-%D9%88%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-xamarin-%D9%84%D9%84%D8%B9%D9%85%D9%84-r373/" rel="">هذا الدرس</a>.<br>
	رغم الشبه الكبير بين هذا التطبيق وسلفه إلًّا أنّني آثرت إعادة إدراج الشيفرة البرمجيّة للأجزاء المتشابهة، وذلك لكي يكون هذا التطبيق متكاملًا قائمًا بحد ذاته.<br>
	أضف المجلّدين التاليين إلى المشروع EnhancedFeedReader (Portable) (عن طريق النقر بزر الفأرة الأيمن ثم اختيار Add ثم New Folder): Pages و Entities.
</p>

<h2 id="الأصناف-ضمن-المجلد-entities">
	الأصناف ضمن المجلّد Entities
</h2>

<p>
	أضف الأصناف التالي إلى المجلّد Entities: FeedItem و Section و GroupSection.<br>
	بالنسبة للصنف FeedItem فلقد تحدثنا عنه في الجزء الأوّل، وإليك الشيفرة البرمجيّة الخاصّة به:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8685_7" style="">
<span class="kwd">namespace</span><span class="pln"> </span><span class="typ">EnhancedFeedReader</span><span class="pun">.</span><span class="typ">Entities</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">FeedItem</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> string </span><span class="typ">Link</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> get</span><span class="pun">;</span><span class="pln"> </span><span class="typ">set</span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> string </span><span class="typ">Title</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> get</span><span class="pun">;</span><span class="pln"> </span><span class="typ">set</span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> string </span><span class="typ">Description</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> get</span><span class="pun">;</span><span class="pln"> </span><span class="typ">set</span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">

        </span><span class="kwd">public</span><span class="pln"> override string </span><span class="typ">ToString</span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> </span><span class="typ">Title</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	الصنف Section هو صنف جديد تمامًا وهو يمثّل قسم من أقسام المحتوى الخاصّة بموقع أكاديميّة حسّوب. الشيفرة البرمجيّة للملف Section.cs هي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8685_7" style="">
<code class="hljs cs"><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Collections</span><span class="pun">.</span><span class="typ">ObjectModel</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Linq</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Threading</span><span class="pun">.</span><span class="typ">Tasks</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Xml</span><span class="pun">.</span><span class="typ">Linq</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">EnhancedFeedReader</span><span class="pun">.</span><span class="typ">Entities</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">class</span></span><span class="pln"> </span><span class="typ">Section</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pln"> </span><span class="typ">Name</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">get</span></span><span class="pun">;</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">set</span></span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pln"> </span><span class="typ">ResourceUrl</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">get</span></span><span class="pun">;</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">set</span></span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">async</span></span><span class="pln"> </span><span class="typ">Task</span><span class="pun">&lt;</span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">FeedItem</span><span class="pun">&gt;&gt;</span><span class="pln"> </span><span class="hljs-title"><span class="typ">GetFeedItems</span></span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">return</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">await</span></span><span class="pln"> </span><span class="typ">Task</span><span class="pun">.</span><span class="typ">Factory</span><span class="pun">.</span><span class="typ">StartNew</span><span class="pun">(()</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                </span><span class="typ">XDocument</span><span class="pln"> doc </span><span class="pun">=</span><span class="pln"> </span><span class="typ">XDocument</span><span class="pun">.</span><span class="typ">Load</span><span class="pun">(</span><span class="typ">ResourceUrl</span><span class="pun">);</span><span class="pln">

                </span><span class="hljs-keyword"><span class="kwd">var</span></span><span class="pln"> feeds </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">from</span></span><span class="pln"> newsItem </span><span class="hljs-keyword"><span class="kwd">in</span></span><span class="pln"> doc</span><span class="pun">.</span><span class="typ">Descendants</span><span class="pun">(</span><span class="hljs-string"><span class="str">"item"</span></span><span class="pun">)</span><span class="pln">
                            </span><span class="hljs-keyword"><span class="kwd">select</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">FeedItem</span><span class="pln">
                            </span><span class="pun">{</span><span class="pln">
                                </span><span class="typ">Title</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> newsItem</span><span class="pun">.</span><span class="typ">Element</span><span class="pun">(</span><span class="hljs-string"><span class="str">"title"</span></span><span class="pun">).</span><span class="typ">Value</span><span class="pun">,</span><span class="pln">
                                </span><span class="typ">Description</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> newsItem</span><span class="pun">.</span><span class="typ">Element</span><span class="pun">(</span><span class="hljs-string"><span class="str">"description"</span></span><span class="pun">).</span><span class="typ">Value</span><span class="pun">,</span><span class="pln">
                                </span><span class="typ">Link</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> newsItem</span><span class="pun">.</span><span class="typ">Element</span><span class="pun">(</span><span class="hljs-string"><span class="str">"link"</span></span><span class="pun">).</span><span class="typ">Value</span><span class="pln">
                            </span><span class="pun">};</span><span class="pln">

                </span><span class="hljs-keyword"><span class="kwd">return</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">FeedItem</span><span class="pun">&gt;(</span><span class="pln">feeds</span><span class="pun">);</span><span class="pln">
            </span><span class="pun">});</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">override</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">ToString</span></span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">return</span></span><span class="pln"> </span><span class="typ">Name</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>
	يحتوي هذا الصنف على خاصيّتين: الاسم Name وعنوان المصدر ResourceUrl الذي سيتم جلب الخلاصات منه. يوجد أيضًا التابع <code>GetFeedItems</code> الذي سيجلب الخلاصات التابعة للقسم الحالي. هذا التابع هو البديل للتابع LoadFeeds الذي كان موجودًا في الصنف SectionFeedsPage وهو يقوم بنفس وظيفته مع ميزة استخدام البرمجة غير المتزامنة. وأخيرًا التابع ToString للحصول على تمثيل نصّي لكائن من النوع Section.<br>
	أمّا بالنسبة للصنف GroupSection فهو يمثّل تصنيف لمجموعة من الأقسام. في الحقيقة يعمل موقع أكاديميّة حسوب على تقسيم الخلاصات ضمن مجموعات كل منها يحتوي على قسمين. انظر إلى الشيفرة الخاصّ بهذا الصنف:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8685_7" style="">
<code class="hljs cs"><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Collections</span><span class="pun">.</span><span class="typ">ObjectModel</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">EnhancedFeedReader</span><span class="pun">.</span><span class="typ">Entities</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">class</span></span><span class="pln"> </span><span class="typ">GroupSection</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">Section</span><span class="pun">&gt;</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pln"> </span><span class="typ">Name</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">get</span></span><span class="pun">;</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">set</span></span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>
	لاحظ كم هي بسيطة هذه الشيفرة. يحتوي هذا الصنف على خاصيّة واحدة هي خاصيّة الاسم Name له. مع الانتباه إلى أنّه يرث من الصنف العمومي <code>ObservableCollection&lt;Section&gt;</code>. وهذا إشارة إلى أنّه يمثّل مجموعة من الأقسام Section. سنرى سبب عمليّة الوراثة هذه بعد قليل.
</p>

<h2 id="الواجهات-ضمن-المجلد-pages">
	الواجهات ضمن المجلّد Pages
</h2>

<p>
	يوجد لدينا ضمن هذا المجلّد ثلاث واجهات تتبع لثلاثة أصناف. صنفان منهما قديمان وهما: SectionFeedsPage و FeedDetailsPage وهما يمثّلان على الترتيب: الواجهة المسؤولة عن عرض خلاصات قسم محدّد من الأقسام المتوفّرة، ومحتوى الخلاصة التي اختارها المستخدم من الواجهة السابقة.<br>
	أمّا الصنف الثالث فهو SectionsPage وهو يمثّل الواجهة الرئيسيّة الخاصة بعرض جميع الأقسام المتوفّرة ضمن موقع الأكاديميّة.<br>
	انتقل إلى ملف الرماز SectionFeedsPage.xaml واحرص على أن تكون محتوياته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8685_7" style="">
<code class="hljs xml"><span class="hljs-pi"><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">ContentPage</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">xmlns</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"http://xamarin.com/schemas/2014/forms"</span></span><span class="pln">
             </span><span class="hljs-attribute"><span class="atn">xmlns:x</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"http://schemas.microsoft.com/winfx/2009/xaml"</span></span><span class="pln">
             </span><span class="hljs-attribute"><span class="atn">x:Class</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"EnhancedFeedReader.Pages.SectionFeedsPage"</span></span><span class="tag">&gt;</span></span><span class="pln">
  </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">StackLayout</span></span><span class="tag">&gt;</span></span><span class="pln">
    </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">ListView</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">x:Name</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"lsvFeeds"</span></span><span class="pln">
              </span><span class="hljs-attribute"><span class="atn">ItemTapped</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"lsvFeeds_ItemTapped"</span></span><span class="tag">/&gt;</span></span><span class="pln">
  </span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">StackLayout</span></span><span class="tag">&gt;</span></span><span class="pln">

</span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">ContentPage</span></span><span class="tag">&gt;</span></span></code></pre>

<p>
	ثم انتقل إلى ملف الشيفرة الموافق له وهو SectionFeedsPage.xaml.cs واحرص على أن تكون محتوياته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8685_7" style="">
<code class="hljs cs"><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">EnhancedFeedReader</span><span class="pun">.</span><span class="typ">Entities</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">EnhancedFeedReader</span><span class="pun">.</span><span class="typ">Pages</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">partial</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">class</span></span><span class="pln"> </span><span class="typ">SectionFeedsPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">SectionFeedsPage</span></span><span class="pun">(</span><span class="typ">Section</span><span class="pln"> section</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">InitializeComponent</span><span class="pun">();</span><span class="pln">

            </span><span class="typ">Title</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> section</span><span class="pun">.</span><span class="typ">Name</span><span class="pun">;</span><span class="pln">

            </span><span class="typ">PopulateFeedsListView</span><span class="pun">(</span><span class="pln">section</span><span class="pun">);</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">private</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">async</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">void</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">PopulateFeedsListView</span></span><span class="pun">(</span><span class="typ">Section</span><span class="pln"> section</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            lsvFeeds</span><span class="pun">.</span><span class="typ">ItemsSource</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">await</span></span><span class="pln"> section</span><span class="pun">.</span><span class="typ">GetFeedItems</span><span class="pun">();</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">private</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">async</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">void</span></span><span class="pln"> </span><span class="hljs-title"><span class="pln">lsvFeeds_ItemTapped</span></span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">object</span></span><span class="pln"> sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ItemTappedEventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">FeedItem</span><span class="pln"> selectedFeed </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">FeedItem</span><span class="pun">)</span><span class="pln">e</span><span class="pun">.</span><span class="typ">Item</span><span class="pun">;</span><span class="pln">
            </span><span class="typ">FeedDetailsPage</span><span class="pln"> feedDetailsPage </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln">
                </span><span class="typ">FeedDetailsPage</span><span class="pun">(</span><span class="pln">selectedFeed</span><span class="pun">);</span><span class="pln">

            </span><span class="hljs-keyword"><span class="pln">await</span></span><span class="pln"> </span><span class="typ">Navigation</span><span class="pun">.</span><span class="typ">PushAsync</span><span class="pun">(</span><span class="pln">feedDetailsPage</span><span class="pun">);</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>
	الجديد في هذا الصنف هو التابع PopulateFeedsListView الذي يُمرّر إليه وسيط واحد من النوع Section حيث يتم الحصول على خلاصاته ومن ثمّ إسنادها إلى القائمة lsvFeeds لعرضها. لاحظ كيف يتمّ ذلك باستخدام البرمجة غير المتزامنة.
</p>

<p>
	انتقل بعد ذلك إلى ملف الرماز FeedDetailsPage.xaml واحرص على أن تكون محتوياته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8685_7" style="">
<code class="hljs xml"><span class="hljs-pi"><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">ContentPage</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">xmlns</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"http://xamarin.com/schemas/2014/forms"</span></span><span class="pln">
             </span><span class="hljs-attribute"><span class="atn">xmlns:x</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"http://schemas.microsoft.com/winfx/2009/xaml"</span></span><span class="pln">
             </span><span class="hljs-attribute"><span class="atn">x:Class</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"EnhancedFeedReader.Pages.FeedDetailsPage"</span></span><span class="tag">&gt;</span></span><span class="pln">

  </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">StackLayout</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">Orientation</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"Vertical"</span></span><span class="tag">&gt;</span></span><span class="pln">

    </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">WebView</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">x:Name</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"wvDescription"</span></span><span class="pln">
             </span><span class="hljs-attribute"><span class="atn">VerticalOptions</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"FillAndExpand"</span></span><span class="pln">
             </span><span class="hljs-attribute"><span class="atn">HorizontalOptions</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"FillAndExpand"</span></span><span class="tag">/&gt;</span></span><span class="pln">
  </span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">StackLayout</span></span><span class="tag">&gt;</span></span><span class="pln">

</span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">ContentPage</span></span><span class="tag">&gt;</span></span></code></pre>

<p>
	ثم انتقل إلى ملف الشيفرة البرمجيّة الموافق له وهو FeedDetailsPage.xaml.cs:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8685_7" style="">
<code class="hljs cs"><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">EnhancedFeedReader</span><span class="pun">.</span><span class="typ">Entities</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">EnhancedFeedReader</span><span class="pun">.</span><span class="typ">Pages</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">partial</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">class</span></span><span class="pln"> </span><span class="typ">FeedDetailsPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">FeedDetailsPage</span></span><span class="pun">(</span><span class="typ">FeedItem</span><span class="pln"> feedItem</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">InitializeComponent</span><span class="pun">();</span><span class="pln">

            </span><span class="hljs-keyword"><span class="kwd">this</span></span><span class="pun">.</span><span class="typ">Title</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> feedItem</span><span class="pun">.</span><span class="typ">Title</span><span class="pun">;</span><span class="pln">

            </span><span class="hljs-keyword"><span class="kwd">var</span></span><span class="pln"> descriptionHtmlSource </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">HtmlWebViewSource</span><span class="pun">();</span><span class="pln">
            descriptionHtmlSource</span><span class="pun">.</span><span class="typ">Html</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-string"><span class="pun">@</span><span class="str">"&lt;html dir='rtl'&gt;&lt;body&gt;"</span></span><span class="pln">
                                        </span><span class="pun">+</span><span class="pln"> feedItem</span><span class="pun">.</span><span class="typ">Description</span><span class="pln">
                                        </span><span class="pun">+</span><span class="pln"> </span><span class="hljs-string"><span class="str">"&lt;/body&gt;&lt;/html&gt;"</span></span><span class="pun">;</span><span class="pln">

            wvDescription</span><span class="pun">.</span><span class="typ">Source</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> descriptionHtmlSource</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>
	لم يطرأ في الحقيقة أيّ تعديل على هذا الصنف.<br>
	انتقل أخيرًا إلى ملف الرماز SectionsPage.xaml الذي يمثّل واجهة العرض الأساسيّة، التي ستعرض جميع أقسام الخلاصات المتاحة في الأكاديميّة واحرص على أن تكون محتوياته كما يلي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8685_7" style="">
<code class="hljs xml"><span class="hljs-pi"><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">ContentPage</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">xmlns</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"http://xamarin.com/schemas/2014/forms"</span></span><span class="pln">
             </span><span class="hljs-attribute"><span class="atn">xmlns:x</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"http://schemas.microsoft.com/winfx/2009/xaml"</span></span><span class="pln">
             </span><span class="hljs-attribute"><span class="atn">x:Class</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"EnhancedFeedReader.Pages.SectionsPage"</span></span><span class="tag">&gt;</span></span><span class="pln">

  </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">ListView</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">x:Name</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"lsvSections"</span></span><span class="pln">
              </span><span class="hljs-attribute"><span class="atn">ItemTapped</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"lsvSections_ItemTapped"</span></span><span class="pln">
              </span><span class="hljs-attribute"><span class="atn">IsGroupingEnabled</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"True"</span></span><span class="pln">
              </span><span class="hljs-attribute"><span class="atn">GroupDisplayBinding</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"{Binding Name}"</span></span><span class="pln"> </span><span class="tag">/&gt;</span></span><span class="pln">

</span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">ContentPage</span></span><span class="tag">&gt;</span></span></code></pre>

<p>
	واضح أنّ محتوياته بسيطة، فهي لا تتعدى عنصر القائمة الذي أسميته lsvSections. الأمر الملفت للنظر هنا هو وجود الخاصيتين IsGroupingEnabled و GroupDisplayBinding لعنصر القائمة. أسندنا القيمة True للخاصيّة IsGroupingEnabled وذلك للإشارة إلى وجوب أن تدعم هذه القائمة ميزة التجميع Grouping. أمّا الخاصيّة GroupDisplayBinding فقد أسندت لها القيمة {Binding Name} للإشارة إلى أنّني أرغب بأن يتم ربطها مع قيمة الخاصيّة Name للكائن GroupSection فهي تُحدّد النص المراد إظهاره كعنوان لكل مجموعة. لكي تتوضّح الأمور بشكل أفضل انظر إلى الواجهة في حالة العمل:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="23449" href="https://academy.hsoub.com/uploads/monthly_2017_05/fig01.png.6efc7522358bc61f573e53ffbb7e1bfa.png" rel=""><img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23449" data-unique="toh7uvb4d" src="https://academy.hsoub.com/uploads/monthly_2017_05/fig01.thumb.png.f83d8a111f448912b0aec7853eaee329.png"></a>
</p>

<p>
	انتقل الآن إلى ملف الشيفرة البرمجيّة الموافق وهو SectionsPage.xaml.cs لكي نتعرّف على طريقة الاستفادة من هذه الميزة، واحرص على أن تكون محتوياته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8685_7" style="">
<code class="hljs cs"><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Collections</span><span class="pun">.</span><span class="typ">Generic</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Collections</span><span class="pun">.</span><span class="typ">ObjectModel</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">EnhancedFeedReader</span><span class="pun">.</span><span class="typ">Entities</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">EnhancedFeedReader</span><span class="pun">.</span><span class="typ">Pages</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">partial</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">class</span></span><span class="pln"> </span><span class="typ">SectionsPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">SectionsPage</span></span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">InitializeComponent</span><span class="pun">();</span><span class="pln">

            </span><span class="typ">Title</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-string"><span class="str">"قارئ خلاصات أكاديمية حسوب"</span></span><span class="pun">;</span><span class="pln">

            </span><span class="typ">LoadGroupSections</span><span class="pun">();</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">private</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">void</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">LoadGroupSections</span></span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">int</span></span><span class="pln"> spacePos </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-number"><span class="lit">0</span></span><span class="pun">;</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pln"> tmp</span><span class="pun">;</span><span class="pln">
            </span><span class="typ">GroupSection</span><span class="pln"> gs </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">null</span></span><span class="pun">;</span><span class="pln">
            </span><span class="typ">Dictionary</span><span class="pun">&lt;</span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pun">[]&gt;</span><span class="pln"> groupSectionDic </span><span class="pun">=</span><span class="pln"> 
                </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">Dictionary</span><span class="pun">&lt;</span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pun">[]&gt;()</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-string"><span class="str">"خلاصات ريادة الأعمال"</span></span><span class="pun">,</span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pun">[]</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-string"><span class="str">"https://academy.hsoub.com/entrepreneurship/?rss=1"</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">"https://academy.hsoub.com/questions/rss/entrepreneurship-5.xml"</span></span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">},</span><span class="pln">
                </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-string"><span class="str">"خلاصات العمل الحر"</span></span><span class="pun">,</span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pun">[]</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-string"><span class="str">"https://academy.hsoub.com/freelance/?rss=1"</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">"https://academy.hsoub.com/questions/rss/freelance-8.xml"</span></span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">},</span><span class="pln">
                </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-string"><span class="str">"خلاصات التسويق والمبيعات"</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pun">[]</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-string"><span class="str">"https://academy.hsoub.com/marketing/?rss=1"</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">"https://academy.hsoub.com/questions/rss/marketing-7.xml"</span></span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">},</span><span class="pln">
                </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-string"><span class="str">"خلاصات البرمجة"</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pun">[]</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-string"><span class="str">"https://academy.hsoub.com/programming/?rss=1"</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">"https://academy.hsoub.com/questions/rss/programming-3.xml"</span></span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">},</span><span class="pln">
                </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-string"><span class="str">"خلاصات التصميم"</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pun">[]</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-string"><span class="str">"https://academy.hsoub.com/design/?rss=1"</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">"https://academy.hsoub.com/questions/rss/design-4.xml"</span></span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">},</span><span class="pln">
                </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-string"><span class="str">"خلاصات DevOps"</span></span><span class="pun">,</span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pun">[]</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-string"><span class="str">"https://academy.hsoub.com/devops/?rss=1"</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">"https://academy.hsoub.com/questions/rss/devops-6.xml"</span></span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">},</span><span class="pln">
                </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-string"><span class="str">"خلاصات البرامج والتطبيقات"</span></span><span class="pun">,</span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pun">[]</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-string"><span class="str">"https://academy.hsoub.com/apps/?rss=1"</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">"https://academy.hsoub.com/questions/rss/apps-9.xml"</span></span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">},</span><span class="pln">
                </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-string"><span class="str">"خلاصات الشهادات المتخصصة"</span></span><span class="pun">,</span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pun">[]</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-string"><span class="str">"https://academy.hsoub.com/certificates/?rss=1"</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">"https://academy.hsoub.com/questions/rss/certificates-10.xml"</span></span><span class="pln"> </span><span class="pun">}</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
            </span><span class="pun">};</span><span class="pln">

            </span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">GroupSection</span><span class="pun">&gt;</span><span class="pln"> groupSections </span><span class="pun">=</span><span class="pln">
                </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">GroupSection</span><span class="pun">&gt;();</span><span class="pln">

            </span><span class="hljs-keyword"><span class="kwd">foreach</span></span><span class="pln"> </span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">var</span></span><span class="pln"> grp </span><span class="hljs-keyword"><span class="kwd">in</span></span><span class="pln"> groupSectionDic</span><span class="pun">)</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                gs </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">GroupSection</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="typ">Name</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> grp</span><span class="pun">.</span><span class="typ">Key</span><span class="pln"> </span><span class="pun">};</span><span class="pln">

                spacePos </span><span class="pun">=</span><span class="pln"> grp</span><span class="pun">.</span><span class="typ">Key</span><span class="pun">.</span><span class="typ">IndexOf</span><span class="pun">(</span><span class="hljs-string"><span class="str">" "</span></span><span class="pun">);</span><span class="pln">
                tmp </span><span class="pun">=</span><span class="pln"> grp</span><span class="pun">.</span><span class="typ">Key</span><span class="pun">.</span><span class="typ">Substring</span><span class="pun">(</span><span class="pln">spacePos </span><span class="pun">+</span><span class="pln"> </span><span class="hljs-number"><span class="lit">1</span></span><span class="pun">);</span><span class="pln">

                gs</span><span class="pun">.</span><span class="typ">Add</span><span class="pun">(</span><span class="pln">
                    </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">Section</span><span class="pln">
                    </span><span class="pun">{</span><span class="pln">
                        </span><span class="typ">Name</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-string"><span class="str">"مقالات "</span></span><span class="pln"> </span><span class="pun">+</span><span class="pln">  tmp </span><span class="pun">,</span><span class="pln">
                        </span><span class="typ">ResourceUrl</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> grp</span><span class="pun">.</span><span class="typ">Value</span><span class="pun">[</span><span class="hljs-number"><span class="lit">0</span></span><span class="pun">]</span><span class="pln">
                    </span><span class="pun">}</span><span class="pln">
                </span><span class="pun">);</span><span class="pln">

                gs</span><span class="pun">.</span><span class="typ">Add</span><span class="pun">(</span><span class="pln">
                    </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">Section</span><span class="pln">
                    </span><span class="pun">{</span><span class="pln">
                        </span><span class="typ">Name</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-string"><span class="str">"أسئلة "</span></span><span class="pln"> </span><span class="pun">+</span><span class="pln"> tmp</span><span class="pun">,</span><span class="pln">
                        </span><span class="typ">ResourceUrl</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> grp</span><span class="pun">.</span><span class="typ">Value</span><span class="pun">[</span><span class="hljs-number"><span class="lit">1</span></span><span class="pun">]</span><span class="pln">
                    </span><span class="pun">}</span><span class="pln">
                </span><span class="pun">);</span><span class="pln">

                groupSections</span><span class="pun">.</span><span class="typ">Add</span><span class="pun">(</span><span class="pln">gs</span><span class="pun">);</span><span class="pln">
            </span><span class="pun">}</span><span class="pln">

            lsvSections</span><span class="pun">.</span><span class="typ">ItemsSource</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> groupSections</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">private</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">async</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">void</span></span><span class="pln"> </span><span class="hljs-title"><span class="pln">lsvSections_ItemTapped</span></span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">object</span></span><span class="pln"> sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ItemTappedEventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">Section</span><span class="pln"> selectedSection </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">Section</span><span class="pun">)</span><span class="pln">e</span><span class="pun">.</span><span class="typ">Item</span><span class="pun">;</span><span class="pln">

            </span><span class="typ">SectionFeedsPage</span><span class="pln"> sectionFeedsPage </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln">
                </span><span class="typ">SectionFeedsPage</span><span class="pun">(</span><span class="pln">selectedSection</span><span class="pun">);</span><span class="pln">

            </span><span class="hljs-keyword"><span class="pln">await</span></span><span class="pln"> </span><span class="typ">Navigation</span><span class="pun">.</span><span class="typ">PushAsync</span><span class="pun">(</span><span class="pln">sectionFeedsPage</span><span class="pun">);</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>
	هناك الكثير من المتعة في الشيفرة السابقة! تتمحور معظم الشيفرة حول التابع <code>LoadGroupSections</code> ويُستَخدم لتجهيز الأقسام المختلفة لمصادر الخلاصات في الأكاديمية ووضعها ضمن مجموعات منفصلة ضمن عنصر القائمة lsvSections. هذه الأقسام (كعناوين) موجودة في وضع عدم اتصال وقد نسختها يدويًا من موقع الأكاديميّة، وهي ضمن المتغير <code>groupSectionDic</code> الذي صرحنا عنه من نوع القاموس Dictionary
</p>

<h2 id="ملف-التطبيق-appcs">
	ملف التطبيق App.cs
</h2>

<p>
	انتقل إلى ملف التطبيق App.cs واحرص على أن تكون بانية الصنف App على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8685_7" style="">
<code class="hljs cs"><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">App</span></span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="hljs-comment"><span class="com">// The root page of your application</span></span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">NavigationPage</span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">SectionsPage</span><span class="pun">());</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>
	احرص على استخدام فضاء الاسم Pages لكي تستطيع الوصول إلى الصفحة SectionsPage كما يلي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8685_7" style="">
<code class="hljs cs"><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">EnhancedFeedReader</span><span class="pun">.</span><span class="typ">Pages</span><span class="pun">;</span></code></pre>

<p>
	ستضع السطر السابق أوّل الملف App.cs كما هو معلوم. نفّذ البرنامج وتنقّل في أقسامه المختلفة.
</p>

<h2 id="الخلاصة">
	الخلاصة
</h2>

<p>
	تناولنا في هذا الدرس الجزء الثاني من <a href="https://academy.hsoub.com/tags/feeds-reader/" rel="">تطبيق قارئ الخلاصات الخاص بموقع أكاديميّة حسّوب</a>. لقد أجرينا تحسينات مهمّة على هذا التطبيق من خلال السماح للمستخدم بتصفّح الخلاصات من جميع أقسام الموقع. حيث استخدمنا ميزة التجميع grouping لعنصر القائمة ListView وذلك لتجميع العناوين التابعة لنفس القسم معًا. نكون بذلك قد انتهينا من هذا التطبيق.
</p>
]]></description><guid isPermaLink="false">493</guid><pubDate>Tue, 30 May 2017 21:01:05 +0000</pubDate></item><item><title>&#x62A;&#x637;&#x628;&#x64A;&#x642; &#x639;&#x645;&#x644;&#x64A;: &#x62A;&#x637;&#x628;&#x64A;&#x642; &#x642;&#x627;&#x631;&#x626; &#x627;&#x644;&#x62E;&#x644;&#x627;&#x635;&#x627;&#x62A; - &#x627;&#x644;&#x62C;&#x632;&#x621; &#x627;&#x644;&#x623;&#x648;&#x651;&#x644;</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D8%B9%D9%85%D9%84%D9%8A-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D9%82%D8%A7%D8%B1%D8%A6-%D8%A7%D9%84%D8%AE%D9%84%D8%A7%D8%B5%D8%A7%D8%AA-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%A3%D9%88%D9%91%D9%84-r491/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_05/main2.png.6dece6ef95905bfbed3842687d7a6cba.png" /></p>

<p>
	سنتناول في هذا الدرس من <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/" rel="">سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms</a> تطبيقًا عمليًا آخرًا وهو تطبيق قارئ الخلاصات من موقع أكاديمية حسوب. تندرج مثل هذه التطبيقات تحت النوع rss feed reader ولها مزايا كثيرة ومتنوّعة. سيكون تطبيقنا بسيطًا وعمليًّا ويوضّح مبدأ العمل كما جرت العادة.
</p>

<p style="text-align: center;">
	<img alt="main2.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23424" data-unique="6la5xwymq" src="https://academy.hsoub.com/uploads/monthly_2017_05/main2.png.1ae020c4cf49b855aaafeba94c5a59ce.png"></p>

<p>
	<br>
	سننفّذ التطبيق على مرحلتين: المرحلة الأولى سيكون تطبيق لعرض الخلاصات الموجودة ضمن أحد أقسام الموقع، مع إمكانية اختيار أيّ خلاصة وعرض تفاصيل حولها، وهذا هو محتوى هذا الدرس. أمّا المرحلة الثانية فستكون تحسين للتطبيق المنجز في هذا الدرس حيث سنضيف إمكانيّة قراءة الخلاصات من جميع أقسام الموقع مع إضافة بعض التحسينات على أسلوب العرض بشكل عام، وسيكون ذلك في درس منفصل.
</p>

<h2 id="ماهي-الخلاصات">
	ماهي الخلاصات؟
</h2>

<p>
	خلاصات موقع تكون عادةً عبارة عن مستند XML يحتوي على بيانات تمثّل آخر الأخبار التي يوفّرها الموقع. لا تمتلك جميع المواقع خلاصات بالطبع، ولكنّ من الجيّد دومًا أن يوفّر الموقع مثل هذه الخلاصات في حال كان يمتلك محتوىً متجدّدًا كما هو الحال في موقع أكاديميّة حسوب.<br>
	بما أنّ الخلاصة تكون ضمن ملف XML فمن البديهي أن تكون البيانات منسّقة بتنسيق XML، أي على شكل عقد آباء وأبناء. انظر مثلًا إلى جزء من خلاصات قسم مقالات البرمجة في أكاديميّة حسوب كما ظهرت لي عند كتابة هذا المقال:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="23421" href="https://academy.hsoub.com/uploads/monthly_2017_05/fig01.png.39fed3457f347b18e0c17f8a78134d27.png" rel=""><img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23421" data-unique="826beaun8" src="https://academy.hsoub.com/uploads/monthly_2017_05/fig01.thumb.png.2aaeb3e398a83f7cd963dfda5a4b073e.png"></a>
</p>

<p>
	لاحظ أنّني أستعرض هذه الخلاصات عن طريق متصفّح Chrome عن طريق الرابط:<br><a href="https://academy.hsoub.com/programming/?rss=1" rel="">https://academy.hsoub.com/programming/?rss=1</a><br>
	وهو الرابط الذي توفّره الأكاديميّة للحصول على خلاصات مقالات البرمجة. من الواضح أنّ هذا الأسلوب غير عملي في الحصول على آخر الخلاصات، لذلك يلجأ المستخدمون عادةً إلى تطبيقات متنوّعة لعرض هذه الخلاصات بشكل مريح ومقروء.
</p>

<h2 id="تطبيق-قارئ-الخلاصات">
	تطبيق قارئ الخلاصات
</h2>

<p>
	سنبني في هذا الدرس تطبيق قارئ خلاصات وظيفته قراءة الخلاصات الموجودة في قسم مقالات البرمجة في موقع أكاديميّة حسّوب. وسنعمل في الدرس التالي على تحسين هذا التطبيق بإتاحة الإمكانيّة لتصفّح الخلاصات من جميع الأقسام.<br>
	أنشئ مشروعًا جديدًا من النوع Blank App (Xamarin.Forms Portable) وسمّه BasicFeedReader ثم أبق فقط على المشروعين BasicFeedReader (Portable) و BasicFeedReader.Droid كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-visual-studio-2015-community-%D9%88%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-xamarin-%D9%84%D9%84%D8%B9%D9%85%D9%84-r373/" rel="">هذا الدرس</a>.
</p>

<h3 id="الصنف-feeditem">
	الصنف FeedItem
</h3>

<p>
	من نافذة مستكشف الحل Solution Explorer انقر بزر الفأرة الأيمن على المشروع BasicFeedReader واختر من القائمة التي ستظهر الخيار Add ثم من القائمة الفرعية الخيار New Folder لإضافة مجلّد جديد. سمّ هذا المجلّد بالاسم Entities، وبعد أن يظهر في نافذة الحل Solution Explore انقر عليه بزر الفأرة الأيمن واختر الخيار Add ومن القائمة الفرعية اختر Class. ستظهر نافذة تسمح لك بتعيين اسم لهذا الصنف. اختر الاسم FeedItem له. هذا الصنف هو حجر البناء الأساسي لهذا البرنامج. احرص على جعل محتويات الملف FeedItem.cs كما يلي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_7475_8" style="">
<span class="kwd">namespace</span><span class="pln"> </span><span class="typ">BasicFeedReader</span><span class="pun">.</span><span class="typ">Entities</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">FeedItem</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> string </span><span class="typ">Link</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> get</span><span class="pun">;</span><span class="pln"> </span><span class="typ">set</span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> string </span><span class="typ">Title</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> get</span><span class="pun">;</span><span class="pln"> </span><span class="typ">set</span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> string </span><span class="typ">Description</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> get</span><span class="pun">;</span><span class="pln"> </span><span class="typ">set</span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">

        </span><span class="kwd">public</span><span class="pln"> override string </span><span class="typ">ToString</span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> </span><span class="typ">Title</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	الخصائص Link و Title و Description في هذا الصنف تقابل العناصر link و title و description في مستند XML. أمّا التابع ToString فهو للحصول على تمثيل نصّي لأي كائن من النوع FeedItem.
</p>

<h3 id="الواجهات">
	الواجهات
</h3>

<p>
	أضف مجلّدًا جديدًا للمشروع BasicFeedReader كما فعلنا قبل قليل، وسمّه Pages. ثم أضف إليه صفحتي محتوى تعتمدان رماز XAML بحيث يكون اسم الصفحة الأولى هو FeedDetailsPage وهي الواجهة الرئيسيّة، واسم الصفحة الثانية SectionFeedsPage وهي واجهة التفاصيل.<br>
	الصفحة SectionFeedsPage هي الواجهة التي ستعرض خلاصات قسم مقالات البرمجة في أكاديمّية حسوب. أمّا الواجهة FeedDetailsPage فهي لعرض الخلاصة التي يتم اختيارها من الواجهة SectionFeedsPage.
</p>

<h3 id="الواجهة-sectionfeedspage">
	الواجهة SectionFeedsPage
</h3>

<p>
	انتقل إلى الملف SectionFeedsPage.xaml واحرص على أن تكون محتوياته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_7475_8" style="">
<code class="hljs xml"><span class="hljs-pi"><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">ContentPage</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">xmlns</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"http://xamarin.com/schemas/2014/forms"</span></span><span class="pln">
             </span><span class="hljs-attribute"><span class="atn">xmlns:x</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"http://schemas.microsoft.com/winfx/2009/xaml"</span></span><span class="pln">
             </span><span class="hljs-attribute"><span class="atn">x:Class</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"BasicFeedReader.Pages.SectionFeedsPage"</span></span><span class="tag">&gt;</span></span><span class="pln">
  </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">StackLayout</span></span><span class="tag">&gt;</span></span><span class="pln">
    </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">ListView</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">x:Name</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"lsvFeeds"</span></span><span class="pln">
              </span><span class="hljs-attribute"><span class="atn">ItemTapped</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"lsvFeeds_ItemTapped"</span></span><span class="tag">/&gt;</span></span><span class="pln">
  </span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">StackLayout</span></span><span class="tag">&gt;</span></span><span class="pln">

</span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">ContentPage</span></span><span class="tag">&gt;</span></span></code></pre>

<p>
	لاحظ كم هو بسيط هذا الرماز، فهو لا يحتوي سوى عنصر قائمة lsvFeeds لعرض خلاصات قسم مقالات البرمجة، حيث سنربط الحدث ItemTapped الخاص بها بالمعالج lsvFeeds_ItemTapped. انتقل الآن إلى ملف الشيفرة البرمجيّة الموافق SectionFeedsPage.xaml.cs واحرص على أن تكون محتوياته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_7475_8" style="">
<code class="hljs cs"><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">BasicFeedReader</span><span class="pun">.</span><span class="typ">Entities</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Linq</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Xml</span><span class="pun">.</span><span class="typ">Linq</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">BasicFeedReader</span><span class="pun">.</span><span class="typ">Pages</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">partial</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">class</span></span><span class="pln"> </span><span class="typ">SectionFeedsPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">SectionFeedsPage</span></span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">InitializeComponent</span><span class="pun">();</span><span class="pln">

            </span><span class="typ">LoadFeeds</span><span class="pun">(</span><span class="hljs-string"><span class="str">"https://academy.hsoub.com/programming/?rss=1"</span></span><span class="pun">);</span><span class="pln">

            </span><span class="typ">Title</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-string"><span class="str">"مقالات البرمجة"</span></span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">private</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">async</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">void</span></span><span class="pln"> </span><span class="hljs-title"><span class="pln">lsvFeeds_ItemTapped</span></span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">object</span></span><span class="pln"> sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ItemTappedEventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">FeedItem</span><span class="pln"> selectedFeed </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">FeedItem</span><span class="pun">)</span><span class="pln">e</span><span class="pun">.</span><span class="typ">Item</span><span class="pun">;</span><span class="pln">
            </span><span class="typ">FeedDetailsPage</span><span class="pln"> feedDetailsPage </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln">
                </span><span class="typ">FeedDetailsPage</span><span class="pun">(</span><span class="pln">selectedFeed</span><span class="pun">);</span><span class="pln">

            </span><span class="hljs-keyword"><span class="pln">await</span></span><span class="pln"> </span><span class="typ">Navigation</span><span class="pun">.</span><span class="typ">PushAsync</span><span class="pun">(</span><span class="pln">feedDetailsPage</span><span class="pun">);</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">private</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">void</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">LoadFeeds</span></span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pln"> resource</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">

            </span><span class="typ">XDocument</span><span class="pln"> doc </span><span class="pun">=</span><span class="pln"> </span><span class="typ">XDocument</span><span class="pun">.</span><span class="typ">Load</span><span class="pun">(</span><span class="pln">resource</span><span class="pun">);</span><span class="pln">

            </span><span class="hljs-keyword"><span class="kwd">var</span></span><span class="pln"> feeds </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">from</span></span><span class="pln"> newsItem </span><span class="hljs-keyword"><span class="kwd">in</span></span><span class="pln"> doc</span><span class="pun">.</span><span class="typ">Descendants</span><span class="pun">(</span><span class="hljs-string"><span class="str">"item"</span></span><span class="pun">)</span><span class="pln">
                       </span><span class="hljs-keyword"><span class="kwd">select</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">FeedItem</span><span class="pln">
                       </span><span class="pun">{</span><span class="pln">
                           </span><span class="typ">Title</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> newsItem</span><span class="pun">.</span><span class="typ">Element</span><span class="pun">(</span><span class="hljs-string"><span class="str">"title"</span></span><span class="pun">).</span><span class="typ">Value</span><span class="pun">,</span><span class="pln">
                           </span><span class="typ">Description</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> newsItem</span><span class="pun">.</span><span class="typ">Element</span><span class="pun">(</span><span class="hljs-string"><span class="str">"description"</span></span><span class="pun">).</span><span class="typ">Value</span><span class="pun">,</span><span class="pln">
                           </span><span class="typ">Link</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> newsItem</span><span class="pun">.</span><span class="typ">Element</span><span class="pun">(</span><span class="hljs-string"><span class="str">"link"</span></span><span class="pun">).</span><span class="typ">Value</span><span class="pln">
                       </span><span class="pun">};</span><span class="pln">

            lsvFeeds</span><span class="pun">.</span><span class="typ">ItemsSource</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> feeds</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>
	عند يتم إنشاء كائن من هذه الصفحة لعرضها للمستخدم، يتم تنفيذ بانيتها. حيث يعمل التطبيق على استدعاء التابع LoadFeeds والذي يتطلّب وسيطًا واحدًا من النوع string ويمثّل عنوان المصدر المزوّد للخلاصات. في الحقيقة ما فعلناه هنا هو أمر غير جيّد من الناحية العمليّة، فلا ينبغي وضع مثل هذا الاستدعاء هنا في البانية، سيما وأنّ التابع LoadFeeds لا يستخدم تقنية البرمجة غير المتزامنة، مما سيسبب جمودًا مزعجًا في التطبيق عند أوّل تشغيله. سنحل هذه المشكلة لاحقًا في الجزء الثاني.<br>
	انظر الآن إلى تعريف التابع LoadFeeds من الشيفرة السابقة. ستلاحظ أنّه يستخدم تقنيّة ممتازة يوفرها إطار العمل .NET من خلال الصنف XDocument الذي يمثّل مستند XML بشكل كائني، حيث يعمل السطر الأوّل من هذا التابع على إنشاء كائن جديد من الصنف XDocument من خلال تحميل مستند XML مباشرةً من الانترنت عن طريق التابع الساكن Load.<br>
	بعد ذلك يتم إعراب مستند XML المحمّل من الإنترنت بسرعة وفعاليّة عاليتين. حيث تحتاج إلى عدد قليل من الأسطر البرمجيّة على شكل استعلام LINQ to XML لكي تقوم بالمطلوب. لقد اطلعنا على تقنيّة شبيهة في درس سابق حيث استخدمنا LINQ to Objects. يمكنك معرفة المزيد حول هذا الموضوع بقراءة <a href="https://msdn.microsoft.com/en-us/library/mt693062.aspx" rel="external nofollow">هذا المقال</a>.<br>
	بعد استخلاص المعلومات من مستند XML المُحمّل، وإنشاء كائن من النوع FeedItem لكل خلاصة موجودة في هذا المستند، يتم إسناد المجموعة المنشأة من هذه الكائنات إلى الخاصيّة ItemsSource من القائمة lsvFeeds ليتم عرضها للمستخدم.<br>
	أمّا بالنسبة لمعالج الحدث lsvFeeds_ItemTapped من الشيفرة السابقة. فوظيفته بسيطة، وهي تنحصر في الحصول على كائن FeedsItem الموجود ضمن العنصر الذي تمّ نقره (لمسه) ضمن القائمة lsvFeeds ومن ثمّ الانتقال إلى الصفحة FeedDetailsPage لعرض محتوى هذه الخلاصة.
</p>

<h3 id="الواجهة-feeddetailspage">
	الواجهة FeedDetailsPage
</h3>

<p>
	انتقل إلى الملف FeedDetailsPage.xaml واحرص على أن تكون محتوياته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_7475_8" style="">
<code class="hljs xml"><span class="hljs-pi"><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">ContentPage</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">xmlns</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"http://xamarin.com/schemas/2014/forms"</span></span><span class="pln">
             </span><span class="hljs-attribute"><span class="atn">xmlns:x</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"http://schemas.microsoft.com/winfx/2009/xaml"</span></span><span class="pln">
             </span><span class="hljs-attribute"><span class="atn">x:Class</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"BasicFeedReader.Pages.FeedDetailsPage"</span></span><span class="tag">&gt;</span></span><span class="pln">

  </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">StackLayout</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">Orientation</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"Vertical"</span></span><span class="tag">&gt;</span></span><span class="pln">

    </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">WebView</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">x:Name</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"wvDescription"</span></span><span class="pln">
             </span><span class="hljs-attribute"><span class="atn">VerticalOptions</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"FillAndExpand"</span></span><span class="pln">
             </span><span class="hljs-attribute"><span class="atn">HorizontalOptions</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"FillAndExpand"</span></span><span class="tag">/&gt;</span></span><span class="pln">
  </span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">StackLayout</span></span><span class="tag">&gt;</span></span><span class="pln">

</span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">ContentPage</span></span><span class="tag">&gt;</span></span></code></pre>

<p>
	لاحظ مرّة أخرى كم هو بسيط هذا الرماز. حيث يقتصر على استخدام عنصر واحد، هو العنصر WebView ويُستخدم لعرض محتوى مستند HTML. وسبب استخدامي لهذا العنصر، هو أنّ الخلاصات التي ترد من موقع أكاديميّة حسّوب تحتوي على المحتوى كاملًا وهو منسّق بتنسيق HTML. وهذا أمر لا تجده في كثير من مزوّدات خدمة الخلاصات. لذلك فوجدت أنّ أفضل طريقة هو عرض هذا المحتوى مباشرةً ضمن عنصر WebView.<br>
	انتقل الآن إلى ملف الشيفرة البرمجيّة الموافق FeedDetailsPage.xaml.cs واحرص على أن يكون كما في الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_7475_8" style="">
<code class="hljs cs"><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">BasicFeedReader</span><span class="pun">.</span><span class="typ">Entities</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">BasicFeedReader</span><span class="pun">.</span><span class="typ">Pages</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">partial</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">class</span></span><span class="pln"> </span><span class="typ">FeedDetailsPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">FeedDetailsPage</span></span><span class="pun">(</span><span class="typ">FeedItem</span><span class="pln"> feedItem</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">InitializeComponent</span><span class="pun">();</span><span class="pln">

            </span><span class="hljs-keyword"><span class="kwd">this</span></span><span class="pun">.</span><span class="typ">Title</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> feedItem</span><span class="pun">.</span><span class="typ">Title</span><span class="pun">;</span><span class="pln">

            </span><span class="hljs-keyword"><span class="kwd">var</span></span><span class="pln"> descriptionHtmlSource </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">HtmlWebViewSource</span><span class="pun">();</span><span class="pln">
            descriptionHtmlSource</span><span class="pun">.</span><span class="typ">Html</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-string"><span class="pun">@</span><span class="str">"&lt;html dir='rtl'&gt;&lt;body&gt;"</span></span><span class="pln"> </span><span class="pun">+</span><span class="pln"> feedItem</span><span class="pun">.</span><span class="typ">Description</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="hljs-string"><span class="str">"&lt;/body&gt;&lt;/html&gt;"</span></span><span class="pun">;</span><span class="pln">
            wvDescription</span><span class="pun">.</span><span class="typ">Source</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> descriptionHtmlSource</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>
	كل الشيفرة البرمجيّة موجودة ضمن البانية التي تتطلّب وسيطًا واحدًا من النوع FeedItem الذي يحتوي على بيانات الخلاصة المراد عرض تفاصيلها. نعمل على وضع عنوان هذه الصفحة ليكون مطابقًا لعنوان الخلاصة، ثمّ ننشئ كائنًا من النوع HtmlWebViewSource نسنده ضمن المتغيّر descriptionHtmlSource الذي سيمثّل الكائن المحتوى للعنصر wvDescription (عنصر WebView الذي صرّحنا ضمن ملف الرماز). لاحظ كيف أسندنا للخاصيّة Html لهذا المتغيّر محتوى الخاصيّة Description لكائن الخلاصة، وهو كما أشرنا قبل قليل عبارة عن مستند HTML ينقصه فقط الوسمين و اللذان أضفناهما يدويًّا. ثمّ نُسند المتغيّر descriptionHtmlSource بدوره إلى الخاصيّة Source للعنصر wvDescription مما يؤدّي إلى ظهور مستند HTML كما هو مخطّط له.
</p>

<h3 id="ملف-التطبيق-appcs">
	ملف التطبيق App.cs
</h3>

<p>
	انتقل إلى ملف التطبيق App.cs واحرص على أن تكون بانية الصنف App على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_7475_8" style="">
<code class="hljs cs"><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">App</span></span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="hljs-comment"><span class="com">// The root page of your application</span></span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">NavigationPage</span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">SectionFeedsPage</span><span class="pun">());</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>
	احرص على استخدام فضاء الاسم Pages لكي تستطيع الوصول إلى الصفحة SectionFeedsPage كما يلي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_7475_8" style="">
<code class="hljs cs"><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">BasicFeedReader</span><span class="pun">.</span><span class="typ">Pages</span><span class="pun">;</span></code></pre>

<p>
	ستضع السطر السابق أوّل الملف App.cs كما هو معلوم. نفّذ البرنامج، ستحصل على شكل شبيه بما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="23422" href="https://academy.hsoub.com/uploads/monthly_2017_05/fig02.png.de5fe4f9a81105171265e5240e602872.png" rel=""><img alt="fig02.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23422" data-unique="am8y7yxcp" src="https://academy.hsoub.com/uploads/monthly_2017_05/fig02.thumb.png.603a4c12910db9e2de3cb9afd03f2633.png"></a>
</p>

<p>
	وهي الواجهة التي تحتوي على الخلاصات الموجودة ضمن قسم مقالات البرمجة. جرّب اختيار أحد هذه الخلاصات لتحصل على شكل شبيه بما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="23423" href="https://academy.hsoub.com/uploads/monthly_2017_05/fig03.png.3a69db6d76a513152679ca5900bcddd9.png" rel=""><img alt="fig03.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23423" data-unique="nz7snw7oa" src="https://academy.hsoub.com/uploads/monthly_2017_05/fig03.thumb.png.699f8e286f59b189b7c4d38510193dde.png"></a>
</p>

<p>
	لاحظ كيف تظهر الخلاصة كما لو أنّه يتم عرضها ضمن متصفّح الويب العادي. جرّب سحب الصفحة إلى الأسفل ليؤكّد ذلك هذه الملاحظة.
</p>

<h3 id="الخلاصة">
	الخلاصة
</h3>

<p>
	تناولنا في هذا الدرس الجزء الأوّل من تطبيق قارئ الخلاصات الخاص بموقع أكاديميّة حسّوب. حيث نفّذنا بعض المهام الأساسيّة، والتي سنبني عليها في الجزء الثاني الذي سيتناول تطبيقًا محسّنًا لهذا التطبيق. حيث سنعمل على دعم عرض جميع الأقسام المتاحة في الأكاديميّة وليس قسم مقالات البرمجة فحسب.
</p>
]]></description><guid isPermaLink="false">491</guid><pubDate>Sat, 27 May 2017 06:48:18 +0000</pubDate></item><item><title>&#x628;&#x646;&#x627;&#x621; &#x62A;&#x637;&#x628;&#x64A;&#x642; &#x62C;&#x647;&#x627;&#x62A; &#x627;&#x644;&#x627;&#x62A;&#x635;&#x627;&#x644; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; Xamarin - &#x627;&#x644;&#x62C;&#x632;&#x621; &#x627;&#x644;&#x62B;&#x651;&#x627;&#x644;&#x62B;</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D8%AC%D9%87%D8%A7%D8%AA-%D8%A7%D9%84%D8%A7%D8%AA%D8%B5%D8%A7%D9%84-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xamarin-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%AB%D9%91%D8%A7%D9%84%D8%AB-r487/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_05/main.png.6210e75b20e7e418ddadcaf5b8f92a93.png" /></p>

<p>
	هذا الدرس هو الجزء الثالث والأخير من <a href="https://academy.hsoub.com/tags/xamarin103/" rel="">سلسلة دروس</a> تُعنى بكيفيّة بناء تطبيق عملي بسيط لإدارة جهات اتصال ببيانات أوليّة وهو بطبيعة الحال جزء من <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/" rel="">سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms</a>. ستحتاج إلى قراءة الجزأين <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D8%AC%D9%87%D8%A7%D8%AA-%D8%A7%D9%84%D8%A7%D8%AA%D8%B5%D8%A7%D9%84-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xamarin-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%A3%D9%88%D9%91%D9%84-r434/" rel="">الأوّل</a> و<a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D8%AC%D9%87%D8%A7%D8%AA-%D8%A7%D9%84%D8%A7%D8%AA%D8%B5%D8%A7%D9%84-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xamarin-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%AB%D8%A7%D9%86%D9%8A-r480/" rel="">الثاني</a> السابقين لكي تستطيع المتابعة في هذا الدرس.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23302" data-unique="ys0xkq8rq" src="https://academy.hsoub.com/uploads/monthly_2017_05/main.png.339d15fc0deba02400bc801150648911.png"></p>

<p>
	<br>
	سنهتم في هذا الدرس ببناء واجهتي التطبيق:
</p>

<ul>
<li>
		الواجهة الرئيسيّة التي يمكن من خلالها البحث عن جهات الاتصال حسب الاسم والكنية، وأيضًا إضافة جهة اتصال جديدة.
	</li>
	<li>
		الواجهة الخاصة بعرض تفاصيل جهة الاتصال التي تمّ اختيارها من الواجهة الرئيسيّة، ومن ثمّ إمكانيّة تعديل بياناتها أو حتى حذفها.
	</li>
</ul>
<p>
	بالإضافة إلى تعديل الصنف App لكي يصبح التطبيق قابل للعمل.
</p>

<h2 id="الواجهة-الرئيسية-للتطبيق-contactspage">
	الواجهة الرئيسيّة للتطبيق ContactsPage
</h2>

<p>
	سنحتاج في البداية إلى إضافة مجلّد جديد سنسمّه Pages سنضع فيه أي صفحة جديدة للتطبيق، وهذا الإجراء هو من باب تنظيم مكوّنات التطبيق فحسب.<br>
	من نافذة مستكشف الحل Solution Explorer انقر بزر الفأرة الأيمن على اسم المشروع ContactsApp (Portal) ثم اختر من القائمة التي ستظهر الخيار Add. من القائمة الفرعية، اختر New Folder ثمّ سمّه Pages.<br>
	انقر بزر الفأرة الأيمن على المجلّد الذي أضفته توًا وهو Pages واختر من القائمة Add ثم اختر من القائمة الفرعية New Item لتظهر نافذة تسمح باختيار العنصر الجديد الذي تودّ إضافته. اختر صفحة محتوى تعتمد على الرماز كما وأن سبق لنا أن فعلنا ذلك في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xaml-r453/" rel="">هذا الدرس</a>. سمّ هذه الصفحة ContactsPage.<br>
	انتقل الآن إلى الملف ContactsPage.xaml واحرص على أن تكون محتوياته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6502_8" style="">
<span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
</span><span class="pun">&lt;</span><span class="typ">ContentPage</span><span class="pln"> xmlns</span><span class="pun">=</span><span class="str">"http://xamarin.com/schemas/2014/forms"</span><span class="pln">
             xmlns</span><span class="pun">:</span><span class="pln">x</span><span class="pun">=</span><span class="str">"http://schemas.microsoft.com/winfx/2009/xaml"</span><span class="pln">
             x</span><span class="pun">:</span><span class="typ">Class</span><span class="pun">=</span><span class="str">"ContactsApp.Pages.ContactsPage"</span><span class="pln">
             </span><span class="typ">Appearing</span><span class="pln"> </span><span class="pun">=</span><span class="str">"ContactsPage_Appearing"</span><span class="pun">&gt;</span><span class="pln">

  </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">
    </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pln"> </span><span class="typ">Padding</span><span class="pun">=</span><span class="str">"5,25,5,5"</span><span class="pun">&gt;</span><span class="pln">
      </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pln"> </span><span class="typ">Orientation</span><span class="pun">=</span><span class="str">"Horizontal"</span><span class="pun">&gt;</span><span class="pln">
        </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"First Name"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
        </span><span class="pun">&lt;</span><span class="typ">Editor</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"txtFirstName"</span><span class="pln">
                </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"FillAndExpand"</span><span class="pln">
                </span><span class="typ">TextChanged</span><span class="pun">=</span><span class="str">"Editor_TextChanged"</span><span class="pun">/&gt;</span><span class="pln">
      </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">

      </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pln"> </span><span class="typ">Orientation</span><span class="pun">=</span><span class="str">"Horizontal"</span><span class="pun">&gt;</span><span class="pln">
        </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"Last Name"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
        </span><span class="pun">&lt;</span><span class="typ">Editor</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"txtLastName"</span><span class="pln">
                </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"FillAndExpand"</span><span class="pln">
                </span><span class="typ">TextChanged</span><span class="pun">=</span><span class="str">"Editor_TextChanged"</span><span class="pun">/&gt;</span><span class="pln">
      </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">

      </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"Find"</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"btnFind"</span><span class="pln"> </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"btnFind_Clicked"</span><span class="pun">/&gt;</span><span class="pln">
    </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">

    </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">
      </span><span class="pun">&lt;</span><span class="typ">ListView</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"lsvContacts"</span><span class="pln">
                </span><span class="typ">ItemTapped</span><span class="pun">=</span><span class="str">"lsvContacts_ItemTapped"</span><span class="pun">/&gt;</span><span class="pln">
    </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">

    </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"+ New Contact"</span><span class="pln"> 
            </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"FillAndExpand"</span><span class="pln"> 
            </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"btnNewContact_Clicked"</span><span class="pun">/&gt;</span><span class="pln">
  </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">

</span><span class="pun">&lt;/</span><span class="typ">ContentPage</span><span class="pun">&gt;</span></pre>

<p>
	لقد استخدمنا أربعة أحداث مختلفة في هذه الصفحة سنورد وصفًا قصيرًا لكل منها فيما يلي:
</p>

<ol>
<li>
		حدث الظهور Appearing للصفحة ContactsPage وقد ربطناه بالمعالج <code>ContactsPage_Appearing</code> وذلك لتحديث بيانات الصفحة عند العودة من الصفحة المسؤولة عن عرض تفاصيل جهة الاتصال كما سنرى لاحقًا في هذا الدرس.
	</li>
	<li>
		حدث تغيّر النص TextChangedلكلّ من العنصرين txtFirstName و txtLastName وقد ربطناه بالمعالج Editor_TextChanged وذلك لمسح نتائج البحث التي تظهر ضمن القائمة lsvContacts عند أي تعديل يجريه المستخدم فيهما.
	</li>
	<li>
		حدث لمس المُدخل ضمن القائمة lsvContacts وربطناه بالمعالج <code>lsvContacts_ItemTapped</code> وذلك لكي ينتقل البرنامج إلى الواجهة المسؤولة عن عرض تفاصيل جهة الاتصال عند لمسها.
	</li>
	<li>
		حدث النقر Clicked لزر إضافة جهة اتصال جديدة وربطناه بالمعالج <code>btnNewContact_Clicked</code>.
	</li>
</ol>
<p>
	انتقل بعد ذلك إلى ملف الشيفرة البرمجيّة الموافق للملف السابق وهو ContactsPage.xaml.cs واحرص على أن تكون محتوياته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6502_8" style="">
<code class="hljs cs"><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">ContactsApp</span><span class="pun">.</span><span class="typ">Entities</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">ContactsApp</span><span class="pun">.</span><span class="typ">Pages</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">partial</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">class</span></span><span class="pln"> </span><span class="typ">ContactsPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">ContactsPage</span></span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">InitializeComponent</span><span class="pun">();</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">private</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">async</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">void</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">DoFind</span></span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pln"> firstName </span><span class="pun">=</span><span class="pln"> txtFirstName</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">null</span></span><span class="pln"> </span><span class="pun">?</span><span class="pln"> </span><span class="hljs-string"><span class="str">""</span></span><span class="pln"> </span><span class="pun">:</span><span class="pln"> txtFirstName</span><span class="pun">.</span><span class="typ">Text</span><span class="pun">;</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pln"> lastName </span><span class="pun">=</span><span class="pln"> txtLastName</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">null</span></span><span class="pln"> </span><span class="pun">?</span><span class="pln"> </span><span class="hljs-string"><span class="str">""</span></span><span class="pln"> </span><span class="pun">:</span><span class="pln"> txtLastName</span><span class="pun">.</span><span class="typ">Text</span><span class="pun">;</span><span class="pln">

            lsvContacts</span><span class="pun">.</span><span class="typ">ItemsSource</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">await</span></span><span class="pun">((</span><span class="typ">App</span><span class="pun">)</span><span class="typ">Application</span><span class="pun">.</span><span class="typ">Current</span><span class="pun">).</span><span class="typ">ContactsRepository</span><span class="pln">
                </span><span class="pun">.</span><span class="typ">GetContactsAsync</span><span class="pun">(</span><span class="pln">firstName</span><span class="pun">,</span><span class="pln"> lastName</span><span class="pun">);</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">private</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">void</span></span><span class="pln"> </span><span class="hljs-title"><span class="pln">btnFind_Clicked</span></span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">object</span></span><span class="pln"> sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">EventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">DoFind</span><span class="pun">();</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">private</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">void</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">Editor_TextChanged</span></span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">object</span></span><span class="pln"> sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">TextChangedEventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">if</span></span><span class="pln"> </span><span class="pun">(</span><span class="pln">lsvContacts</span><span class="pun">.</span><span class="typ">ItemsSource</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">null</span></span><span class="pun">)</span><span class="pln">
                lsvContacts</span><span class="pun">.</span><span class="typ">ItemsSource</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">null</span></span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">private</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">async</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">void</span></span><span class="pln"> </span><span class="hljs-title"><span class="pln">lsvContacts_ItemTapped</span></span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">object</span></span><span class="pln"> sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">ItemTappedEventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">Contact</span><span class="pln"> selectedContact </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">Contact</span><span class="pun">)</span><span class="pln">e</span><span class="pun">.</span><span class="typ">Item</span><span class="pun">;</span><span class="pln">
            </span><span class="typ">ContactDetailsPage</span><span class="pln"> </span><span class="typ">ContactDetailsPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln">
                </span><span class="typ">ContactDetailsPage</span><span class="pun">(</span><span class="pln">selectedContact</span><span class="pun">);</span><span class="pln">

            </span><span class="hljs-keyword"><span class="pln">await</span></span><span class="pln"> </span><span class="typ">Navigation</span><span class="pun">.</span><span class="typ">PushAsync</span><span class="pun">(</span><span class="typ">ContactDetailsPage</span><span class="pun">);</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">private</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">void</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">ContactsPage_Appearing</span></span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">object</span></span><span class="pln"> sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">EventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">DoFind</span><span class="pun">();</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">private</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">async</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">void</span></span><span class="pln"> </span><span class="hljs-title"><span class="pln">btnNewContact_Clicked</span></span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">object</span></span><span class="pln"> sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">EventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">ContactDetailsPage</span><span class="pln"> </span><span class="typ">ContactDetailsPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln">
                </span><span class="typ">ContactDetailsPage</span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">null</span></span><span class="pun">);</span><span class="pln">

            </span><span class="hljs-keyword"><span class="pln">await</span></span><span class="pln"> </span><span class="typ">Navigation</span><span class="pun">.</span><span class="typ">PushAsync</span><span class="pun">(</span><span class="typ">ContactDetailsPage</span><span class="pun">);</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>
	يحتوي هذا الملف على الصنف ContactsPage والذي يحتوي على معالجات الأحداث التي صرّحنا عنها في صفحة الرماز الموافقة له كما رأينا قبل قليل، بالإضافة إلى وجود تابع خدمي وهو DoFind ووظيفته إجراء عمليّة بحث وفقًا للمعايير التي يرغبها المستخدم (الاسم والكنية). الشيفرة البرمجيّة الموجودة ضمن معالجات الأحداث بسيطة وواضحة. ولكن أريد أن أتوقّف قليلًا عند الشيفرة البرمجيّة التي يستخدمها التابع الخدمي DoFind التي تنفّذ عمليّة البحث:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6502_8" style="">
<code class="hljs avrasm"><span class="kwd">string</span><span class="pln"> firstName </span><span class="pun">=</span><span class="pln"> txtFirstName</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="typ">Text</span></span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="kwd">null</span><span class="pln"> </span><span class="pun">?</span><span class="pln"> </span><span class="hljs-string"><span class="str">""</span></span><span class="pln"> </span><span class="pun">:</span><span class="pln"> txtFirstName</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="typ">Text</span></span><span class="hljs-comment"><span class="pun">;</span></span><span class="pln">
</span><span class="kwd">string</span><span class="pln"> lastName </span><span class="pun">=</span><span class="pln"> txtLastName</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="typ">Text</span></span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="kwd">null</span><span class="pln"> </span><span class="pun">?</span><span class="pln"> </span><span class="hljs-string"><span class="str">""</span></span><span class="pln"> </span><span class="pun">:</span><span class="pln"> txtLastName</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="typ">Text</span></span><span class="hljs-comment"><span class="pun">;</span></span><span class="pln">

lsvContacts</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="typ">ItemsSource</span></span><span class="pln"> </span><span class="pun">=</span><span class="pln"> await</span><span class="pun">((</span><span class="typ">App</span><span class="pun">)</span><span class="typ">Application</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="typ">Current</span></span><span class="pun">)</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="typ">ContactsRepository</span></span><span class="pln">
    </span><span class="hljs-preprocessor"><span class="pun">.</span><span class="typ">GetContactsAsync</span></span><span class="pun">(</span><span class="pln">firstName</span><span class="pun">,</span><span class="pln"> lastName</span><span class="pun">)</span><span class="hljs-comment"><span class="pun">;</span></span></code></pre>

<p>
	أوّل سطرين واضحان حيث يعملان على الحصول على معايير البحث التي يريدها المستخدم من مربّعي النص txtFirstName و txtLastName. أمّا السطر الأخير فهو يعمل على الاتصال بالمستودع لتنفيذ عمليّة البحث وإرجاع النتائج وذلك بإجراء استدعاء إلى التابع GetContactsAsync وتمرير معياري البحث إليه. انظر هذه العبارة:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6502_8" style="">
<code class="hljs avrasm"><span class="pln">await</span><span class="pun">((</span><span class="typ">App</span><span class="pun">)</span><span class="typ">Application</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="typ">Current</span></span><span class="pun">)</span><span class="hljs-preprocessor"><span class="pun">.</span><span class="typ">ContactsRepository</span></span><span class="pln">
    </span><span class="hljs-preprocessor"><span class="pun">.</span><span class="typ">GetContactsAsync</span></span><span class="pun">(</span><span class="pln">firstName</span><span class="pun">,</span><span class="pln"> lastName</span><span class="pun">)</span><span class="hljs-comment"><span class="pun">;</span></span></code></pre>

<p>
	تعمل الخاصية Application.Current على إرجاع كائن من النوع Application يمثّل التطبيق الحالي الذي نعمل من خلاله. والذي يحتاج بدوره إلى عملية تحويل cast باستخدام التحويل (App) إلى كائن من النوع App وهو الصنف الأساسي في التطبيق. في الحقيقة لقد صرّحت عن الخاصيّة ContactsRepository في الصنف App ليتم الوصول للمستودع من أيّ مكان من تطبيقنا. سنرى التصريح عن هذه الخاصيّة بعد قليل.
</p>

<h2 id="واجهة-تفاصيل-جهة-الاتصال-contactdetailspage">
	واجهة تفاصيل جهة الاتصال ContactDetailsPage
</h2>

<p>
	أضف هذه الواجهة بنفس الأسلوب الذي اتبعناه عند إضافة ملف الواجهة الرئيسيّة، أي إلى المجلّد Pages. على أن يكون اسمها ContactDetailsPage. سيصبح مستكشف الحل لديك شبيه بما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="23301" href="https://academy.hsoub.com/uploads/monthly_2017_05/fig01.png.9afac88f494a5af6f29aba4e12213727.png" rel=""><img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23301" data-unique="5t1miyyw2" src="https://academy.hsoub.com/uploads/monthly_2017_05/fig01.thumb.png.992c3a8137e8aaf664ebcb90ee99b804.png"></a>
</p>

<p>
	انتقل إلى ملف الرماز ContactDetailsPage.xaml واحرص على أن تكون محتوياته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6502_8" style="">
<code class="hljs xml"><span class="hljs-pi"><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span></span><span class="pln">
</span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">ContentPage</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">xmlns</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"http://xamarin.com/schemas/2014/forms"</span></span><span class="pln">
             </span><span class="hljs-attribute"><span class="atn">xmlns:x</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"http://schemas.microsoft.com/winfx/2009/xaml"</span></span><span class="pln">
             </span><span class="hljs-attribute"><span class="atn">x:Class</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"ContactsApp.Pages.ContactDetailsPage"</span></span><span class="tag">&gt;</span></span><span class="pln">

  </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">StackLayout</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">Orientation</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"Vertical"</span></span><span class="pln">
               </span><span class="hljs-attribute"><span class="atn">Padding</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"5,25,5,5"</span></span><span class="tag">&gt;</span></span><span class="pln">

    </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">Label</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">Text</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"FirstName"</span></span><span class="pln"> </span><span class="tag">/&gt;</span></span><span class="pln">
    </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">Entry</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">x:Name</span></span><span class="pln"> </span><span class="pun">=</span><span class="hljs-value"><span class="atv">"txtFirstName"</span></span><span class="tag">/&gt;</span></span><span class="pln">

    </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">Label</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">Text</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"LastName"</span></span><span class="pln"> </span><span class="tag">/&gt;</span></span><span class="pln">
    </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">Entry</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">x:Name</span></span><span class="pln"> </span><span class="pun">=</span><span class="hljs-value"><span class="atv">"txtLastName"</span></span><span class="tag">/&gt;</span></span><span class="pln">

    </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">Label</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">Text</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"Tel"</span></span><span class="pln"> </span><span class="tag">/&gt;</span></span><span class="pln">
    </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">Entry</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">x:Name</span></span><span class="pln"> </span><span class="pun">=</span><span class="hljs-value"><span class="atv">"txtTel"</span></span><span class="tag">/&gt;</span></span><span class="pln">

    </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">Label</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">Text</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"EMail"</span></span><span class="pln"> </span><span class="tag">/&gt;</span></span><span class="pln">
    </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">Entry</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">x:Name</span></span><span class="pln"> </span><span class="pun">=</span><span class="hljs-value"><span class="atv">"txtEMail"</span></span><span class="tag">/&gt;</span></span><span class="pln">

    </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">Label</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">Text</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"Hobbies"</span></span><span class="pln"> </span><span class="tag">/&gt;</span></span><span class="pln">
    </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">Editor</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">x:Name</span></span><span class="pln"> </span><span class="pun">=</span><span class="hljs-value"><span class="atv">"txtHobbies"</span></span><span class="tag">/&gt;</span></span><span class="pln">

    </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">StackLayout</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">Orientation</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"Horizontal"</span></span><span class="tag">&gt;</span></span><span class="pln">
      </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">Button</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">Text</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"Save"</span></span><span class="pln"> 
              </span><span class="hljs-attribute"><span class="atn">x:Name</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"btnSave"</span></span><span class="pln"> 
              </span><span class="hljs-attribute"><span class="atn">Clicked</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"btnSave_Clicked"</span></span><span class="tag">/&gt;</span></span><span class="pln">

      </span><span class="hljs-tag"><span class="tag">&lt;</span><span class="hljs-title"><span class="tag">Button</span></span><span class="pln"> </span><span class="hljs-attribute"><span class="atn">Text</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"Delete"</span></span><span class="pln">
              </span><span class="hljs-attribute"><span class="atn">x:Name</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"btnDelete"</span></span><span class="pln">
              </span><span class="hljs-attribute"><span class="atn">Clicked</span></span><span class="pun">=</span><span class="hljs-value"><span class="atv">"btnDelete_Clicked"</span></span><span class="tag">/&gt;</span></span><span class="pln">
    </span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">StackLayout</span></span><span class="tag">&gt;</span></span><span class="pln">
  </span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">StackLayout</span></span><span class="tag">&gt;</span></span><span class="pln">

</span><span class="hljs-tag"><span class="tag">&lt;/</span><span class="hljs-title"><span class="tag">ContentPage</span></span><span class="tag">&gt;</span></span></code></pre>

<p>
	واضح أنّه ملف بسيط. هناك حدثان قد صرّحنا عنهما في هذه الصفحة وهما:
</p>

<ol>
<li>
		حدث النقر لزر الحفظ Clicked وقد ربطناه بالمعالج btnSave_Clicked وهو مسؤول عن عمليتي الحفظ والإضافة.
	</li>
	<li>
		حدث النقر لزر الحذف Clicked وقد ربطناه بالمعالج btnDelete_Clicked وهو مسؤول عن حذف جهة الاتصال.
	</li>
</ol>
<p>
	انتقل إلى ملف الشيفرة البرمجيّة الموافق لملف الرماز السابق واسمه ContactDetailsPage.xaml.cs واحرص على أن تكون محتوياته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6502_8" style="">
<code class="hljs cs"><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">ContactsApp</span><span class="pun">.</span><span class="typ">Entities</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">ContactsApp</span><span class="pun">.</span><span class="typ">Pages</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">partial</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">class</span></span><span class="pln"> </span><span class="typ">ContactDetailsPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="hljs-keyword"><span class="kwd">private</span></span><span class="pln"> </span><span class="typ">Contact</span><span class="pln"> currentContact</span><span class="pun">;</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">ContactDetailsPage</span></span><span class="pun">(</span><span class="typ">Contact</span><span class="pln"> contact</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">InitializeComponent</span><span class="pun">();</span><span class="pln">

            </span><span class="hljs-keyword"><span class="kwd">this</span></span><span class="pun">.</span><span class="pln">currentContact </span><span class="pun">=</span><span class="pln"> contact</span><span class="pun">;</span><span class="pln">

            </span><span class="hljs-keyword"><span class="kwd">if</span></span><span class="pln"> </span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">this</span></span><span class="pun">.</span><span class="pln">currentContact </span><span class="pun">!=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">null</span></span><span class="pun">)</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                txtFirstName</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> contact</span><span class="pun">.</span><span class="typ">FirstName</span><span class="pun">;</span><span class="pln">
                txtLastName</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> contact</span><span class="pun">.</span><span class="typ">LastName</span><span class="pun">;</span><span class="pln">
                txtEMail</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> contact</span><span class="pun">.</span><span class="typ">EMail</span><span class="pun">;</span><span class="pln">
                txtTel</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> contact</span><span class="pun">.</span><span class="typ">Tel</span><span class="pun">;</span><span class="pln">
                txtHobbies</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> contact</span><span class="pun">.</span><span class="typ">Hobbies</span><span class="pun">;</span><span class="pln">

                </span><span class="typ">Title</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> contact</span><span class="pun">.</span><span class="typ">ToString</span><span class="pun">()</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="hljs-string"><span class="str">" Details"</span></span><span class="pun">;</span><span class="pln">

                btnDelete</span><span class="pun">.</span><span class="typ">IsVisible</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">true</span></span><span class="pun">;</span><span class="pln">
            </span><span class="pun">}</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">else</span></span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                </span><span class="typ">Title</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-string"><span class="str">"New Contact"</span></span><span class="pun">;</span><span class="pln">

                btnDelete</span><span class="pun">.</span><span class="typ">IsVisible</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">false</span></span><span class="pun">;</span><span class="pln">
            </span><span class="pun">}</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">private</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">async</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">void</span></span><span class="pln"> </span><span class="hljs-title"><span class="pln">btnSave_Clicked</span></span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">object</span></span><span class="pln"> sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">EventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pln"> firstName </span><span class="pun">=</span><span class="pln"> txtFirstName</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">null</span></span><span class="pln"> </span><span class="pun">?</span><span class="pln"> </span><span class="hljs-string"><span class="str">""</span></span><span class="pln"> </span><span class="pun">:</span><span class="pln"> txtFirstName</span><span class="pun">.</span><span class="typ">Text</span><span class="pun">;</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pln"> lastName </span><span class="pun">=</span><span class="pln"> txtLastName</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">null</span></span><span class="pln"> </span><span class="pun">?</span><span class="pln"> </span><span class="hljs-string"><span class="str">""</span></span><span class="pln"> </span><span class="pun">:</span><span class="pln"> txtLastName</span><span class="pun">.</span><span class="typ">Text</span><span class="pun">;</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pln"> tel </span><span class="pun">=</span><span class="pln"> txtTel</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">null</span></span><span class="pln"> </span><span class="pun">?</span><span class="pln"> </span><span class="hljs-string"><span class="str">""</span></span><span class="pln"> </span><span class="pun">:</span><span class="pln"> txtTel</span><span class="pun">.</span><span class="typ">Text</span><span class="pun">;</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pln"> email </span><span class="pun">=</span><span class="pln"> txtEMail</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">null</span></span><span class="pln"> </span><span class="pun">?</span><span class="pln"> </span><span class="hljs-string"><span class="str">""</span></span><span class="pln"> </span><span class="pun">:</span><span class="pln"> txtEMail</span><span class="pun">.</span><span class="typ">Text</span><span class="pun">;</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pln"> hobbies </span><span class="pun">=</span><span class="pln"> txtHobbies</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">null</span></span><span class="pln"> </span><span class="pun">?</span><span class="pln"> </span><span class="hljs-string"><span class="str">""</span></span><span class="pln"> </span><span class="pun">:</span><span class="pln"> txtHobbies</span><span class="pun">.</span><span class="typ">Text</span><span class="pun">;</span><span class="pln">

            </span><span class="hljs-keyword"><span class="kwd">if</span></span><span class="pln"> </span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">this</span></span><span class="pun">.</span><span class="pln">currentContact </span><span class="pun">!=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">null</span></span><span class="pun">)</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                </span><span class="hljs-keyword"><span class="kwd">this</span></span><span class="pun">.</span><span class="pln">currentContact</span><span class="pun">.</span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> firstName</span><span class="pun">;</span><span class="pln">
                </span><span class="hljs-keyword"><span class="kwd">this</span></span><span class="pun">.</span><span class="pln">currentContact</span><span class="pun">.</span><span class="typ">LastName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> lastName</span><span class="pun">;</span><span class="pln">
                </span><span class="hljs-keyword"><span class="kwd">this</span></span><span class="pun">.</span><span class="pln">currentContact</span><span class="pun">.</span><span class="typ">EMail</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> tel</span><span class="pun">;</span><span class="pln">
                </span><span class="hljs-keyword"><span class="kwd">this</span></span><span class="pun">.</span><span class="pln">currentContact</span><span class="pun">.</span><span class="typ">Tel</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> email</span><span class="pun">;</span><span class="pln">
                </span><span class="hljs-keyword"><span class="kwd">this</span></span><span class="pun">.</span><span class="pln">currentContact</span><span class="pun">.</span><span class="typ">Hobbies</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> hobbies</span><span class="pun">;</span><span class="pln">

                </span><span class="hljs-keyword"><span class="pln">await</span></span><span class="pln"> </span><span class="pun">((</span><span class="typ">App</span><span class="pun">)</span><span class="typ">Application</span><span class="pun">.</span><span class="typ">Current</span><span class="pun">).</span><span class="typ">ContactsRepository</span><span class="pln">
                    </span><span class="pun">.</span><span class="typ">UpdateContactAsync</span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">this</span></span><span class="pun">.</span><span class="pln">currentContact</span><span class="pun">);</span><span class="pln">

            </span><span class="pun">}</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">else</span></span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                </span><span class="typ">Contact</span><span class="pln"> contact </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">Contact</span><span class="pln">
                </span><span class="pun">{</span><span class="pln">
                    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> firstName</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">LastName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> lastName</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Tel</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> tel</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">EMail</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> email</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Hobbies</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> hobbies</span><span class="pun">,</span><span class="pln">
                </span><span class="pun">};</span><span class="pln">

                </span><span class="hljs-keyword"><span class="pln">await</span></span><span class="pln"> </span><span class="pun">((</span><span class="typ">App</span><span class="pun">)</span><span class="typ">Application</span><span class="pun">.</span><span class="typ">Current</span><span class="pun">).</span><span class="typ">ContactsRepository</span><span class="pln">
                    </span><span class="pun">.</span><span class="typ">AddContactAsync</span><span class="pun">(</span><span class="pln">contact</span><span class="pun">);</span><span class="pln">
            </span><span class="pun">}</span><span class="pln">

            </span><span class="hljs-keyword"><span class="pln">await</span></span><span class="pln"> </span><span class="typ">Navigation</span><span class="pun">.</span><span class="typ">PopAsync</span><span class="pun">();</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">private</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">async</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">void</span></span><span class="pln"> </span><span class="hljs-title"><span class="pln">btnDelete_Clicked</span></span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">object</span></span><span class="pln"> sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">EventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">var</span></span><span class="pln"> result </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">await</span></span><span class="pln"> 
                </span><span class="typ">DisplayAlert</span><span class="pun">(</span><span class="hljs-string"><span class="str">"Delete Confirmation"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="hljs-string"><span class="str">"Are you sure you want to delete this contact?"</span></span><span class="pun">,</span><span class="pln"> 
                    </span><span class="hljs-string"><span class="str">"Yes"</span></span><span class="pun">,</span><span class="pln"> </span><span class="hljs-string"><span class="str">"No"</span></span><span class="pun">);</span><span class="pln">

            </span><span class="hljs-keyword"><span class="kwd">if</span></span><span class="pln"> </span><span class="pun">(</span><span class="pln">result</span><span class="pun">)</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                </span><span class="hljs-keyword"><span class="pln">await</span></span><span class="pln"> </span><span class="pun">((</span><span class="typ">App</span><span class="pun">)</span><span class="typ">Application</span><span class="pun">.</span><span class="typ">Current</span><span class="pun">).</span><span class="typ">ContactsRepository</span><span class="pln">
                    </span><span class="pun">.</span><span class="typ">DeleteContactAsync</span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">this</span></span><span class="pun">.</span><span class="pln">currentContact</span><span class="pun">);</span><span class="pln">

                </span><span class="hljs-keyword"><span class="pln">await</span></span><span class="pln"> </span><span class="typ">Navigation</span><span class="pun">.</span><span class="typ">PopAsync</span><span class="pun">();</span><span class="pln">
            </span><span class="pun">}</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>
	كما وأوضحنا مسبقًا أنّ وظيفة هذه الواجهة هي عرض تفاصيل جهة اتصال وتعديلها، مع إمكانيّة حذفها، بالإضافة إلى استخدام هذه الواجهة في إضافة جهة اتصال جديدة أيضًا. تميّز هذه الواجهة الغرض المطلوب منها عن طريق كائن من النوع Contact يُمرّر كوسيط إلى بانيتها. إذا كان هذا الوسيط يحتوي على كائن صالح من النوع Contact فهذا يعني أنّنا نريد عرض جهة الاتصال التي يمثّلها هذا الكائن، ومن ثمّ تعديلها أو حذفها، ويقتضي ذلك بالطبع إظهار زر الحذف Delete. أمّا في حال تمّ تمرير null كوسيط إلى البانية، فهذا يعني أنّه تمّ استدعاء الصفحة لإنشاء جهة اتصال جديدة تمامًا، وبالتالي إخفاء زر الحذف Delete لأنّه لن يكون له معنى في هذه الحالة. يتم حفظ نسخة من الكائن الممرّر ضمن حقل خاص ضمن الصنف اسمه currentContact. ويتم تحديد الغاية من الواجهة ضمن البانية نفسها.<br>
	انظر إلى تعريف معالج الحدث btnSave_Clicked من الشيفرة السابقة وانظر كيف يتعامل مع الحالتين السابقتين (تعديل أو إضافة).
</p>

<h2 id="الصنف-app">
	الصنف App
</h2>

<p>
	انتقل إلى الملف App.cs واحرص على أن تكون محتوياته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6502_8" style="">
<code class="hljs cs"><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">ContactsApp</span><span class="pun">.</span><span class="typ">Abstract</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">ContactsApp</span><span class="pun">.</span><span class="typ">Concrete</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">ContactsApp</span><span class="pun">.</span><span class="typ">Pages</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">ContactsApp</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">class</span></span><span class="pln"> </span><span class="typ">App</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">Application</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="typ">IContactsRepository</span><span class="pln"> </span><span class="typ">ContactsRepository</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">get</span></span><span class="pun">;</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">set</span></span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">App</span></span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">ContactsRepository</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">MemoryContactsRepository</span><span class="pun">();</span><span class="pln">

            </span><span class="hljs-comment"><span class="com">// The root page of your application</span></span><span class="pln">
            </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">NavigationPage</span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">ContactsPage</span><span class="pun">());</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">protected</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">override</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">void</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">OnStart</span></span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="hljs-comment"><span class="com">// Handle when your app starts</span></span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">protected</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">override</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">void</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">OnSleep</span></span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="hljs-comment"><span class="com">// Handle when your app sleeps</span></span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">protected</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">override</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">void</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">OnResume</span></span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="hljs-comment"><span class="com">// Handle when your app resumes</span></span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>
	لاحظ بدايةّ الخاصيّة ContactsRepository من النوع IContactsRepository الموجود ضمن تعريف الصنف App:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6502_8" style="">
<code class="hljs cs"><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="typ">IContactsRepository</span><span class="pln"> </span><span class="typ">ContactsRepository</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">get</span></span><span class="pun">;</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">set</span></span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span></code></pre>

<p>
	في الحقيقة ستمثّل هذه الخاصيّة المستودع الذي سنتبادل البيانات من خلاله. سنعمل على إنشاء كائن جديد من النوع <code>MemoryContactsRepository</code> ومن ثمّ نسنده إلى هذه الخاصيّة وذلك ضمن بانية الصنف App كما يلي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6502_8" style="">
<code class="hljs fix"><span class="hljs-attribute"><span class="typ">ContactsRepository</span><span class="pln"> </span></span><span class="pun">=</span><span class="hljs-string"><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">MemoryContactsRepository</span><span class="pun">();</span></span></code></pre>

<p>
	وهذا الأمر جائز تمامًا لأنّ الصنف MemoryContactsRepositroy يحقّق الواجهة IContactsRepository فهو بمثابة وارث منها. بما أنّ هذه الخاصيّة عامّة public فسيكون بإمكان جميع أجزاء التطبيق الوصول للكائن ContactsRepository وبالتالي التعامل مع البيانات من خلال مكان واحد.<br>
	لاحظ أيضًا من بانية الصنف App كيف أنشأنا كائن جديد من الصنف <code>NavigationPage</code> وأسندناه إلى الخاصيّة MainPage للصنف App. وذلك لأنّنا نريد أن يدعم تطبيقنا ميزة التنقّل بين الصفحات التي تحدثنا عنها في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A7%D9%84%D8%AA%D9%86%D9%82%D9%91%D9%84-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%B5%D9%81%D8%AD%D8%A7%D8%AA-%D9%81%D9%8A-xamarin-r450/" rel="">هذا الدرس</a>.<br>
	يمكنك الآن تنفيذ التطبيق وتجربة جميع المزايا التي يتمتّع بها.
</p>

<blockquote class="ipsQuote" data-ipsquote="">
	<div class="ipsQuote_citation">
		Quote
	</div>

	<div class="ipsQuote_contents ipsClearfix">
		<p>
			ستبدو القوة التي يتمتّع بها نموذج المستودع جليّة عندما نرغب بتغيير مكان حفظ البيانات، حيث سنحتاج فقط إلى تغيير صنف المستودع (وليس الواجهة) مع بقاء باقي مكوّنات التطبيق دون أي تغيير. بمعنى أدق، سيكون التغيير في مكان واحد فقط وهو ضمن بانية الصنف App، حيث سنغيّر النوع الذي سننشئ منه الكائن الذي نُسنده إلى الخاصيّة ContactsRepository.
		</p>
	</div>
</blockquote>

<h2 id="الخلاصة">
	الخلاصة
</h2>

<p>
	نكون بهذا الدرس قد أنهينا بناء <a href="https://academy.hsoub.com/tags/xamarin103/" rel="">تطبيق جهات الاتصال</a>، حيث تحدثنا عن كيفيّة بناء واجهتي التطبيق، وكيفيّة التنقّل بين هاتين الواجهتين، وكيف تتصّلان بالمستودع عند الحاجة للتعامل مع مصدر البيانات الذي يكون في تطبيقنا هذا عبارة عن مجموعة تتكوّن من عناصر من النوع Contact موجودة في ذاكرة التطبيق.
</p>
]]></description><guid isPermaLink="false">487</guid><pubDate>Sat, 20 May 2017 13:51:58 +0000</pubDate></item><item><title>&#x628;&#x646;&#x627;&#x621; &#x62A;&#x637;&#x628;&#x64A;&#x642; &#x62C;&#x647;&#x627;&#x62A; &#x627;&#x644;&#x627;&#x62A;&#x635;&#x627;&#x644; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; Xamarin - &#x627;&#x644;&#x62C;&#x632;&#x621; &#x627;&#x644;&#x62B;&#x627;&#x646;&#x64A;</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D8%AC%D9%87%D8%A7%D8%AA-%D8%A7%D9%84%D8%A7%D8%AA%D8%B5%D8%A7%D9%84-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xamarin-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%AB%D8%A7%D9%86%D9%8A-r480/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_05/main.png.fcefb9dff14fbe6a9cadc3aa6697d339.png" /></p>

<p>
	سنتابع في هذا الدرس من <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/" rel="">سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms</a> العمل الذي بدأناه في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D8%AC%D9%87%D8%A7%D8%AA-%D8%A7%D9%84%D8%A7%D8%AA%D8%B5%D8%A7%D9%84-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xamarin-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%A3%D9%88%D9%91%D9%84-r434/" rel="">الدرس السابق</a> والمتمثّل ببناء تطبيق جهات الاتصال. قد أنهينا في الدرس السابق بناء نموذج المستودع من خلال التصريح عن  الواجهة IContactsRepository وتحقيقها من خلال الصنف MemoryContactsRepository. كما أنشأنا الصنف Contacts الذي يمثّل حجر البناء الأساسي في التطبيق.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="23171" data-unique="b7exp46oi" src="https://academy.hsoub.com/uploads/monthly_2017_05/main.png.09c2dd39ef0aa277e8e4261af323ba77.png"></p>

<p>
	سنضيف في هذا الدرس النواحي الوظيفيّة للصنف المستودع MemoryContactsRepository لكي يصبح تطبيقنا قابلًا للعمل.
</p>

<h3>
	تجهيز النواحي الوظيفيّة للمستودع
</h3>

<p>
	افتح الملف MemoryContactsRepository.cs واحرص على أن تكون محتوياته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8078_20" style="">
<span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Collections</span><span class="pun">.</span><span class="typ">Generic</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Linq</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Threading</span><span class="pun">.</span><span class="typ">Tasks</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Collections</span><span class="pun">.</span><span class="typ">ObjectModel</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">ContactsApp</span><span class="pun">.</span><span class="typ">Abstract</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">ContactsApp</span><span class="pun">.</span><span class="typ">Entities</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">ContactsApp</span><span class="pun">.</span><span class="typ">Concrete</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">MemoryContactsRepository</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">IContactsRepository</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">private</span><span class="pln"> </span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">Contact</span><span class="pun">&gt;</span><span class="pln"> contacts</span><span class="pun">;</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">MemoryContactsRepository</span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            contacts </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">Contact</span><span class="pun">&gt;()</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Contact</span><span class="pun">()</span><span class="pln">
                </span><span class="pun">{</span><span class="pln">
                    </span><span class="typ">Id</span><span class="pun">=</span><span class="lit">1</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Ahmad"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">LastName</span><span class="pun">=</span><span class="str">"Saeed"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Tel</span><span class="pun">=</span><span class="str">"123456"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">EMail</span><span class="pun">=</span><span class="str">"admin@example.com"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Hobbies</span><span class="pun">=</span><span class="str">"Swimming"</span><span class="pln">
                </span><span class="pun">},</span><span class="pln">
                </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Contact</span><span class="pun">()</span><span class="pln">
                </span><span class="pun">{</span><span class="pln">
                    </span><span class="typ">Id</span><span class="pun">=</span><span class="lit">2</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Mahmood"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">LastName</span><span class="pun">=</span><span class="str">"Maktabi"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Tel</span><span class="pun">=</span><span class="str">"852136"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">EMail</span><span class="pun">=</span><span class="str">"info@example.com"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Hobbies</span><span class="pun">=</span><span class="str">"Reading"</span><span class="pln">
                </span><span class="pun">},</span><span class="pln">
                </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Contact</span><span class="pun">()</span><span class="pln">
               </span><span class="pun">{</span><span class="pln">
                    </span><span class="typ">Id</span><span class="pun">=</span><span class="lit">3</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Mazen"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">LastName</span><span class="pun">=</span><span class="str">"Najem"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Tel</span><span class="pun">=</span><span class="str">"987456"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">EMail</span><span class="pun">=</span><span class="str">"it@example.com"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Hobbies</span><span class="pun">=</span><span class="str">"Swimming"</span><span class="pln">
                </span><span class="pun">},</span><span class="pln">
                </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Contact</span><span class="pun">()</span><span class="pln">
                </span><span class="pun">{</span><span class="pln">
                    </span><span class="typ">Id</span><span class="pun">=</span><span class="lit">4</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Sawsan"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">LastName</span><span class="pun">=</span><span class="str">"Hilal"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Tel</span><span class="pun">=</span><span class="str">"741258"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">EMail</span><span class="pun">=</span><span class="str">"sales@example.com"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Hobbies</span><span class="pun">=</span><span class="str">"Writing, Reading"</span><span class="pln">
                </span><span class="pun">},</span><span class="pln">
                </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Contact</span><span class="pun">()</span><span class="pln">
                </span><span class="pun">{</span><span class="pln">
                    </span><span class="typ">Id</span><span class="pun">=</span><span class="lit">5</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Musab"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">LastName</span><span class="pun">=</span><span class="str">"Aga"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Tel</span><span class="pun">=</span><span class="str">"357159"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">EMail</span><span class="pun">=</span><span class="str">"admin@example.com"</span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Hobbies</span><span class="pun">=</span><span class="str">"Sport"</span><span class="pln">
                </span><span class="pun">}</span><span class="pln">
            </span><span class="pun">};</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> async </span><span class="typ">Task</span><span class="pun">&lt;</span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">Contact</span><span class="pun">&gt;&gt;</span><span class="pln"> </span><span class="typ">GetContactsAsync</span><span class="pun">(</span><span class="pln">string firstName</span><span class="pun">,</span><span class="pln"> string lastName</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> await </span><span class="typ">Task</span><span class="pun">.</span><span class="typ">Factory</span><span class="pun">.</span><span class="typ">StartNew</span><span class="pun">(()</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                </span><span class="typ">IEnumerable</span><span class="pun">&lt;</span><span class="typ">Contact</span><span class="pun">&gt;</span><span class="pln"> result </span><span class="pun">=</span><span class="pln"> from contact in contacts </span><span class="kwd">where</span><span class="pln">
                                                contact</span><span class="pun">.</span><span class="typ">FirstName</span><span class="pln">
                                                    </span><span class="pun">.</span><span class="typ">ToUpper</span><span class="pun">()</span><span class="pln">
                                                    </span><span class="pun">.</span><span class="typ">Contains</span><span class="pun">(</span><span class="pln">firstName</span><span class="pun">.</span><span class="typ">ToUpper</span><span class="pun">())</span><span class="pln"> </span><span class="pun">&amp;&amp;</span><span class="pln">
                                                contact</span><span class="pun">.</span><span class="typ">LastName</span><span class="pln">
                                                    </span><span class="pun">.</span><span class="typ">ToUpper</span><span class="pun">()</span><span class="pln">
                                                    </span><span class="pun">.</span><span class="typ">Contains</span><span class="pun">(</span><span class="pln">lastName</span><span class="pun">.</span><span class="typ">ToUpper</span><span class="pun">())</span><span class="pln">
                                              select contact</span><span class="pun">;</span><span class="pln">

                </span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">Contact</span><span class="pun">&gt;</span><span class="pln"> tmp </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">Contact</span><span class="pun">&gt;(</span><span class="pln">result</span><span class="pun">);</span><span class="pln">
                </span><span class="kwd">return</span><span class="pln"> tmp</span><span class="pun">;</span><span class="pln">
            </span><span class="pun">});</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> async </span><span class="typ">Task</span><span class="str">&lt;bool&gt;</span><span class="pln"> </span><span class="typ">AddContactAsync</span><span class="pun">(</span><span class="typ">Contact</span><span class="pln"> contactToAdd</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> await </span><span class="typ">Task</span><span class="pun">.</span><span class="typ">Factory</span><span class="pun">.</span><span class="typ">StartNew</span><span class="pun">(()</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                contactToAdd</span><span class="pun">.</span><span class="typ">Id</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> contacts</span><span class="pun">.</span><span class="typ">Count</span><span class="pun">()</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pun">;</span><span class="pln">
                contacts</span><span class="pun">.</span><span class="typ">Add</span><span class="pun">(</span><span class="pln">contactToAdd</span><span class="pun">);</span><span class="pln">
                </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln">
            </span><span class="pun">});</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> async </span><span class="typ">Task</span><span class="str">&lt;bool&gt;</span><span class="pln"> </span><span class="typ">UpdateContactAsync</span><span class="pun">(</span><span class="typ">Contact</span><span class="pln"> contactToUpdate</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> await </span><span class="typ">Task</span><span class="pun">.</span><span class="typ">Factory</span><span class="pun">.</span><span class="typ">StartNew</span><span class="pun">(()</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                </span><span class="typ">Contact</span><span class="pln"> result </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">from contact in contacts
                                  </span><span class="kwd">where</span><span class="pln"> contact</span><span class="pun">.</span><span class="typ">Id</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> contactToUpdate</span><span class="pun">.</span><span class="typ">Id</span><span class="pln">
                                  select contact</span><span class="pun">).</span><span class="typ">FirstOrDefault</span><span class="pun">();</span><span class="pln">

                </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">result </span><span class="pun">!=</span><span class="pln"> null</span><span class="pun">)</span><span class="pln">
                </span><span class="pun">{</span><span class="pln">
                    contactToUpdate</span><span class="pun">.</span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> result</span><span class="pun">.</span><span class="typ">FirstName</span><span class="pun">;</span><span class="pln">
                    contactToUpdate</span><span class="pun">.</span><span class="typ">LastName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> result</span><span class="pun">.</span><span class="typ">LastName</span><span class="pun">;</span><span class="pln">
                    contactToUpdate</span><span class="pun">.</span><span class="typ">EMail</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> result</span><span class="pun">.</span><span class="typ">EMail</span><span class="pun">;</span><span class="pln">
                    contactToUpdate</span><span class="pun">.</span><span class="typ">Tel</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> result</span><span class="pun">.</span><span class="typ">Tel</span><span class="pun">;</span><span class="pln">
                    contactToUpdate</span><span class="pun">.</span><span class="typ">Hobbies</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> result</span><span class="pun">.</span><span class="typ">Hobbies</span><span class="pun">;</span><span class="pln">

                    </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln">
               </span><span class="pun">}</span><span class="pln">
               </span><span class="kwd">else</span><span class="pln">
                </span><span class="pun">{</span><span class="pln">
                    </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln">
                </span><span class="pun">}</span><span class="pln">
            </span><span class="pun">});</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> async </span><span class="typ">Task</span><span class="str">&lt;bool&gt;</span><span class="pln"> </span><span class="typ">DeleteContactAsync</span><span class="pun">(</span><span class="typ">Contact</span><span class="pln"> contactToDelete</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> await </span><span class="typ">Task</span><span class="pun">.</span><span class="typ">Factory</span><span class="pun">.</span><span class="typ">StartNew</span><span class="pun">(()</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                var result </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">from contact in contacts
                              </span><span class="kwd">where</span><span class="pln"> contact</span><span class="pun">.</span><span class="typ">Id</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> contactToDelete</span><span class="pun">.</span><span class="typ">Id</span><span class="pln">
                              select contact</span><span class="pun">);</span><span class="pln">

                </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">result </span><span class="pun">!=</span><span class="pln"> null</span><span class="pun">)</span><span class="pln">
                </span><span class="pun">{</span><span class="pln">
                    contacts </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">Contact</span><span class="pun">&gt;(</span><span class="pln">result</span><span class="pun">);</span><span class="pln">

                    contactToDelete </span><span class="pun">=</span><span class="pln"> null</span><span class="pun">;</span><span class="pln">
                    </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln">
                </span><span class="pun">}</span><span class="pln">
                </span><span class="kwd">else</span><span class="pln">
                </span><span class="pun">{</span><span class="pln">
                    </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln">
                </span><span class="pun">}</span><span class="pln">
            </span><span class="pun">});</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	 
</p>

<p>
	الجديد هنا أنّنا قد أسندنا شيفرة برمجيّة لكل من التوابع الأساسيّة الموجودة في المستودع. انظر إلى الفقرات التالية التي تشرح عمل الشيفرة البرمجيّة ضمن كل تابع.
</p>

<h3>
	تابع البحث GetContactsAsync
</h3>

<p>
	فيما يلي التابع GetContactsAsync والذي يتطلّب وسيطين من النوع string للبحث حسب الاسم والكنية لجهات الاتصال:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8078_18" style="">
<span class="kwd">public</span><span class="pln"> async </span><span class="typ">Task</span><span class="pun">&lt;</span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">Contact</span><span class="pun">&gt;&gt;</span><span class="pln"> </span><span class="typ">GetContactsAsync</span><span class="pun">(</span><span class="pln">string firstName</span><span class="pun">,</span><span class="pln"> string lastName</span><span class="pun">)</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> await </span><span class="typ">Task</span><span class="pun">.</span><span class="typ">Factory</span><span class="pun">.</span><span class="typ">StartNew</span><span class="pun">(()</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="typ">IEnumerable</span><span class="pun">&lt;</span><span class="typ">Contact</span><span class="pun">&gt;</span><span class="pln"> result </span><span class="pun">=</span><span class="pln"> from contact in contacts </span><span class="kwd">where</span><span class="pln">
                                        contact</span><span class="pun">.</span><span class="typ">FirstName</span><span class="pln">
                                            </span><span class="pun">.</span><span class="typ">ToUpper</span><span class="pun">()</span><span class="pln">
                                            </span><span class="pun">.</span><span class="typ">Contains</span><span class="pun">(</span><span class="pln">firstName</span><span class="pun">.</span><span class="typ">ToUpper</span><span class="pun">())</span><span class="pln"> </span><span class="pun">&amp;&amp;</span><span class="pln">
                                        contact</span><span class="pun">.</span><span class="typ">LastName</span><span class="pln">
                                            </span><span class="pun">.</span><span class="typ">ToUpper</span><span class="pun">()</span><span class="pln">
                                            </span><span class="pun">.</span><span class="typ">Contains</span><span class="pun">(</span><span class="pln">lastName</span><span class="pun">.</span><span class="typ">ToUpper</span><span class="pun">())</span><span class="pln">
                                        select contact</span><span class="pun">;</span><span class="pln">
        </span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">Contact</span><span class="pun">&gt;</span><span class="pln"> tmp </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">Contact</span><span class="pun">&gt;(</span><span class="pln">result</span><span class="pun">);</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> tmp</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">});</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	واضح أنّ هذه الشيفرة تقوم بإنشاء مهمة جديدة (تابع على شكل تعبير lambda) عن طريق التابع Task.Factory.StartNew (ستحتاج إلى إنعاش ذاكرتك <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D9%85%D9%82%D8%AF%D9%91%D9%85%D8%A9-%D8%A5%D9%84%D9%89-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D8%BA%D9%8A%D8%B1-%D8%A7%D9%84%D9%85%D8%AA%D8%B2%D8%A7%D9%85%D9%86%D8%A9-%D9%81%D9%8A-xamarin-r448/" rel="">بهذا الدرس</a>) وذلك باستخدام تقنية البرمجة غير المتزامنة لمنع جمود التطبيق كما نعلم. المتغيّر result الذي تراه في الشيفرة السابق هو من النوع IEnumerable&lt;Contact&gt; أي مجموعة قابلة للعد عناصرها من النوع Contact، وهو يحصل على هذه المجموعة من خلال استعلام LINQ To Objects بسيط:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8078_16" style="">
<span class="pln">from contact in contacts </span><span class="kwd">where</span><span class="pln">

        contact</span><span class="pun">.</span><span class="typ">FirstName</span><span class="pln">

            </span><span class="pun">.</span><span class="typ">ToUpper</span><span class="pun">()</span><span class="pln">

            </span><span class="pun">.</span><span class="typ">Contains</span><span class="pun">(</span><span class="pln">firstName</span><span class="pun">.</span><span class="typ">ToUpper</span><span class="pun">())</span><span class="pln"> </span><span class="pun">&amp;&amp;</span><span class="pln">

        contact</span><span class="pun">.</span><span class="typ">LastName</span><span class="pln">

            </span><span class="pun">.</span><span class="typ">ToUpper</span><span class="pun">()</span><span class="pln">

            </span><span class="pun">.</span><span class="typ">Contains</span><span class="pun">(</span><span class="pln">lastName</span><span class="pun">.</span><span class="typ">ToUpper</span><span class="pun">())</span><span class="pln">

        select contact</span><span class="pun">;</span></pre>

<p>
	تعمل هذه الشيفرة ببساطة على الاستعلام عن جميع جهات الاتصال الموجودة ضمن المتغير contacts والتي تحتوي على عبارتي البحث الخاصّتين بالاسم والكنية بنفس الوقت. إذا كان لديك خبرة باستعلامات SQL فستجد LINQ to Objects مألوفة.
</p>

<p>
	لاحظ وجود عبارتي return ضمن هذا التابع GetContactsAsync. العبارة التي تأتي أولًا هي العبارة المسؤولة عن إرجاع كائن من النوع Task&lt;ObservableCollection&lt;Contact&gt;&gt; أمّا العبارة الثانيّة التي تأتي في الأسفل فهي المسؤولة عن إرجاع كائن من النوع Task&lt;ObservableCollection&lt;Contact&gt;&gt; من التابع الداخلي وهو عبارة عن تعبير lambda والذي يتم تنفيذه من خلال التابع Task.Factory.StartNew كما هو واضح.
</p>

<p>
	في آخر سطرين من التابع الداخلي (تعبير lambda) نعمل على تقديم نتيجة البحث على شكل مجموعة عموميّة وهي ObservableCollection&lt;Contact&gt; حيث يتم تحويلها ضمنيًّا إلى كائن من النوع Task&lt;ObservableCollection&lt;Contact&gt;&gt;.
</p>

<p>
	 
</p>

<blockquote class="ipsQuote" data-ipsquote="">
	<div class="ipsQuote_citation">
		اقتباس
	</div>

	<div class="ipsQuote_contents ipsClearfix">
		<p>
			لمعرفة المزيد عن تقنية LINQ to Objects ألق نظرة على <a href="https://msdn.microsoft.com/en-us/library/mt693052.aspx" rel="external nofollow">هذا المقال</a>.
		</p>
	</div>
</blockquote>

<p>
	 
</p>

<h3>
	تابع إضافة جهة اتصال جديد AddContactAsync
</h3>

<p>
	التابع AddContactAsync يتطلّب وسيطًا واحدًا فقط من النوع Contact ويُرجع كائن من النوع Task&lt;bool&gt; للإشارة إلى نجاح عمليّة الإضافة:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8078_13" style="">
<span class="kwd">public</span><span class="pln"> async </span><span class="typ">Task</span><span class="str">&lt;bool&gt;</span><span class="pln"> </span><span class="typ">AddContactAsync</span><span class="pun">(</span><span class="typ">Contact</span><span class="pln"> contactToAdd</span><span class="pun">)</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> await </span><span class="typ">Task</span><span class="pun">.</span><span class="typ">Factory</span><span class="pun">.</span><span class="typ">StartNew</span><span class="pun">(()</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        contactToAdd</span><span class="pun">.</span><span class="typ">Id</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> contacts</span><span class="pun">.</span><span class="typ">Count</span><span class="pun">()</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pun">;</span><span class="pln">
        contacts</span><span class="pun">.</span><span class="typ">Add</span><span class="pun">(</span><span class="pln">contactToAdd</span><span class="pun">);</span><span class="pln">
        </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln">
    </span><span class="pun">});</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	تعمل هذه الشيفرة على إضافة جهة اتصال جديدة إلى جهات الاتصال الموجودة مسبقًا ضمن المتغيّر contacts مع الانتباه إلى هذه العبارة البرمجيّة:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8078_11" style="">
<span class="pln">contactToAdd</span><span class="pun">.</span><span class="typ">Id</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> contacts</span><span class="pun">.</span><span class="typ">Count</span><span class="pun">()</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="lit">1</span><span class="pun">;</span></pre>

<p>
	 
</p>

<p>
	ما تفعله هذه العبارة غير موجود في أيّ تطبيق عمليّ حقيقي. فهي تُسند قيمة للخاصيّة Id لجهة الاتصال الممرّرة إلى التابع. لا ينبغي لأي تطبيق أن يقوم بهذا العمل، فهذا الرقم ينبغي أن يتم توليده تلقائيًّا عند إضافة جهة الاتصال إلى قاعدة البيانات. وبما أنّ تطبيقنا يعتمد على بيانات وهمية موجودة في الذاكرة فكان لزامًا علينا القيام بمثل هذا الأمر لتمييز جهات الاتصال المضافة حديثًا.
</p>

<h3>
	تابع الحذف DeleteContactAsync
</h3>

<p>
	التابع DeleteContactAsync  يتطلّب وسيطًا واحدًا فقط من النوع Contact ويُرجع كائن من النوع Task&lt;bool&gt; للإشارة إلى نجاح عمليّة الحذف:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8078_9" style="">
<span class="kwd">public</span><span class="pln"> async </span><span class="typ">Task</span><span class="str">&lt;bool&gt;</span><span class="pln"> </span><span class="typ">DeleteContactAsync</span><span class="pun">(</span><span class="typ">Contact</span><span class="pln"> contactToDelete</span><span class="pun">)</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> await </span><span class="typ">Task</span><span class="pun">.</span><span class="typ">Factory</span><span class="pun">.</span><span class="typ">StartNew</span><span class="pun">(()</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        var result </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">from contact in contacts
                        </span><span class="kwd">where</span><span class="pln"> contact</span><span class="pun">.</span><span class="typ">Id</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> contactToDelete</span><span class="pun">.</span><span class="typ">Id</span><span class="pln">
                        select contact</span><span class="pun">);</span><span class="pln">
        </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">result </span><span class="pun">!=</span><span class="pln"> null</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            contacts </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">Contact</span><span class="pun">&gt;(</span><span class="pln">result</span><span class="pun">);</span><span class="pln">
            contactToDelete </span><span class="pun">=</span><span class="pln"> null</span><span class="pun">;</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">else</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">});</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	تعمل الشيفرة السابقة في الواقع على فلترة جهة الاتصال المراد حذفها مما يعني ببساطة أنّ استعلام LINQ to Objects سيعمل على إرجاع جميع جهات الاتصال باستثناء تلك التي يكون قيمة الخاصية Id لها مطابقة لقيمة الخاصيّة Id لجهة الاتصال التي نرغب بحذفها. ومن ثمّ يتم إسناد النتيجة إلى المتغيّر contacts مما يعني فعليًّا أنّنا قد حذفنا جهة الاتصال هذه من الذاكرة.
</p>

<h3>
	تابع التحديث UpdateContactAsync
</h3>

<p>
	التابع UpdateContactAsync والذي يتطلّب وسيطًا واحدًا فقط من النوع Contact ويُرجع كائن من النوع Task&lt;bool&gt; للإشارة إلى نجاح عمليّة الحذف:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_8078_7" style="">
<span class="kwd">public</span><span class="pln"> async </span><span class="typ">Task</span><span class="str">&lt;bool&gt;</span><span class="pln"> </span><span class="typ">UpdateContactAsync</span><span class="pun">(</span><span class="typ">Contact</span><span class="pln"> contactToUpdate</span><span class="pun">)</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">return</span><span class="pln"> await </span><span class="typ">Task</span><span class="pun">.</span><span class="typ">Factory</span><span class="pun">.</span><span class="typ">StartNew</span><span class="pun">(()</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="typ">Contact</span><span class="pln"> result </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">from contact in contacts
                            </span><span class="kwd">where</span><span class="pln"> contact</span><span class="pun">.</span><span class="typ">Id</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> contactToUpdate</span><span class="pun">.</span><span class="typ">Id</span><span class="pln">
                            select contact</span><span class="pun">).</span><span class="typ">FirstOrDefault</span><span class="pun">();</span><span class="pln">
        </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">result </span><span class="pun">!=</span><span class="pln"> null</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            contactToUpdate</span><span class="pun">.</span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> result</span><span class="pun">.</span><span class="typ">FirstName</span><span class="pun">;</span><span class="pln">
            contactToUpdate</span><span class="pun">.</span><span class="typ">LastName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> result</span><span class="pun">.</span><span class="typ">LastName</span><span class="pun">;</span><span class="pln">
            contactToUpdate</span><span class="pun">.</span><span class="typ">EMail</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> result</span><span class="pun">.</span><span class="typ">EMail</span><span class="pun">;</span><span class="pln">
            contactToUpdate</span><span class="pun">.</span><span class="typ">Tel</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> result</span><span class="pun">.</span><span class="typ">Tel</span><span class="pun">;</span><span class="pln">
            contactToUpdate</span><span class="pun">.</span><span class="typ">Hobbies</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> result</span><span class="pun">.</span><span class="typ">Hobbies</span><span class="pun">;</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">else</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">});</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	تخضع هذه الشيفرة البرمجيّة لنفس المبدأ: يبحث استعلام LINQ to Objects عن جهة الاتصال مطلوبة ضمن جهات الاتصال الموجودة ضمن المتغيّر contacts حسب قيمة الخاصيّة Id لجهة الاتصال، وبعد الحصول عليها، يتم تحديث قيم الخصائص الأخرى كما هو واضح.
</p>

<p>
	بهذه الطريقة أصبح نموذج المستودع جاهزًا لوضعه في الاستخدام. حيث ستتعامل معه جميع مكوّنات التطبيق لإنجاز أربعة أنواع مختلفة من العمليّات على البيانات: البحث، والإضافة، والتعديل، والحذف.
</p>

<h3>
	الخلاصة
</h3>

<p>
	تناولنا في هذا الدرس كيفيّة بناء نموذج المستودع الذي يمثّله الصنف MemoryContactsRepository والذي يحقّق كما نعلم الواجهة IContactsRepository حيث تعرّفنا على التوابع الأربعة ضمنه التي تسمح لمكوّنات التطبيق بالتعامل مع البيانات دون الاهتمام بمكان وجود هذه البيانات. اطلعنا أيضًا على كيفيّة توظيف تقنيّة الاستعلام LINQ to Objects ضمن التوابع الأربعة لتنفيذ المهام المطلوبة من هذا المستودع. سنبدأ في الدرس التالي ببناء واجهات التطبيق.
</p>

<p>
	 
</p>

<p>
	حقوق الصورة البارزة محفوظة لـ <a href="http://www.freepik.com/free-vector/smartphone-with-bubble-avatars_1086749.htm" rel="external nofollow">Freepik</a>
</p>
]]></description><guid isPermaLink="false">480</guid><pubDate>Tue, 09 May 2017 21:00:00 +0000</pubDate></item><item><title>&#x628;&#x646;&#x627;&#x621; &#x62A;&#x637;&#x628;&#x64A;&#x642; &#x62C;&#x647;&#x627;&#x62A; &#x627;&#x644;&#x627;&#x62A;&#x635;&#x627;&#x644; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; Xamarin - &#x627;&#x644;&#x62C;&#x632;&#x621; &#x627;&#x644;&#x623;&#x648;&#x651;&#x644;</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D8%AC%D9%87%D8%A7%D8%AA-%D8%A7%D9%84%D8%A7%D8%AA%D8%B5%D8%A7%D9%84-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xamarin-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%A3%D9%88%D9%91%D9%84-r434/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.9e37aebf8b8afb560707f4fe9b6a2ffe.png" /></p>

<p id="بناء-تطبيق-جهات-الاتصال-باستخدام-xamarin-الجزء-الأول">
	سنبدأ في هذا الدرس من <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/" rel="">سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms</a> ببناء تطبيق عملي بمعايير تقنيّة عالية. حيث سنستخدم المعارف التي حصلنا عليها من الدروس السابقة في بناء تطبيق جهات اتصال بسيط لكنّه يستخدم تقنيّات ومفاهيم متقدّمة نسبيًّا.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22718" data-unique="ussi18ycg" src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.74572450d4f09dd69f2697e8b0af106b.png"><br>
	سنتناول هذا التطبيق على ثلاثة أجزاء متتالية، إليك وصف مختصر لمحتوى كلّ منها:
</p>

<ol>
<li>
		الجزء الأوّل: شرح الغاية من التطبيق، وتوضيح فكرة نموذج المستودع Repository في بناء التطبيقات، مع بناء الهيكل العام للتطبيق، وهذا هو محتوى هذا الدرس.
	</li>
	<li>
		الجزء الثاني: تجهيز النواحي الوظيفيّة للمستودع وجعله قابلًا للاستخدام.
	</li>
	<li>
		الجزء الثالث: تنفيذ واجهتي التطبيق الرئيسية والفرعيّة الخاصّة بعرض التفاصيل. وتنفيذ عمليّة التنقّل بين الواجهتين
	</li>
</ol>
<p>
	الغاية من التطبيق وكيف يعمل<br>
	فكرة التطبيق بسيطة للغاية، تتلخّص بعرض جهات اتصال موجودة مسبقًا وإمكانية البحث ضمنها، مع إمكانيّة إضافة جهات اتصال جديدة وتحريرها وحذفها. يعتمد التطبيق على وجود واجهتين. الواجهة الأولى هي الواجهة الرئيسيّة وتحتوي على قسم خاص بالبحث حسب الاسم أو الكنية عن أيّ جهة اتصال موجودة مسبقًا، بالإضافة إلى قائمة لعرض جهات الاتصال الناتجة عن عمليّة البحث، وأخيرًا زر خاص بإضافة جهات اتصال جديدة. انظر الشكل التالي الذي ينتج عند ضغط زر البحث FIND عند عدم تحديد أي معيار للبحث:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22716" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.png.947be5f927c573d0d354fe29a593adc6.png" rel=""><img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22716" data-unique="u4sxq60bb" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.thumb.png.7dced80560687d35a8cd913cb8ffd67e.png"></a>
</p>

<p>
	عندما يقوم المستخدم بنقر زر البحث FIND دون أن يحدّد أي معيار، سيقوم التطبيق بعرض جميع جهات الاتصال الموجودة لديه، والتي ستكون في هذه النسخة من البرنامج عبارة عن بيانات وهمية موجودة ضمن ذاكرة التطبيق. أمّا عند تحديد المستخدم للاسم أو الكنيّة فسيعمل التطبيق على البحث مستخدمًا منطق AND.<br>
	أمّا الواجهة الثانية، فتظهر عندما يلمس المستخدم إحدى جهات الاتصال من القائمة السابقة، حيث تعرض هذه الواجهة بيانات تفصيليّة حول جهة الاتصال هذه: الاسم والكنية ورقم الهاتف وعنوان البريد الإلكتروني والهوايات. انظر إلى الشكل التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22717" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.png.6fd67ca66861b7e20b09440d197b18ec.png" rel=""><img alt="fig02.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22717" data-unique="0bkkdkdt2" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.thumb.png.c12b3ed9033a078f1a4b56681026af91.png"></a>
</p>

<p>
	من الممكن تعديل أيّ من هذه البيانات ثم ينقر المستخدم زر الحفظ لحفظها، أو أن ينقر زر الرجوع إلى الواجهة السابقة الموجود في الأعلى بجانب أيقونة البرنامج في حال لم يرغب بتعديل البيانات. كما يمكن للمستخدم أن يحذف جهة الاتصال هذه بنقره على زر الحذف Delete كما يظهر من الشكل السابق. وهذه ببساطة فكرة التطبيق.
</p>

<h3 id="نموذج-المستودع-repository">
	نموذج المستودع Repository
</h3>

<p>
	عندما تكبر التطبيقات وتتنوّع المهام المطلوبة منها تبرز الحاجة لوسيلة لتنظيم العمل داخل التطبيق. في الحقيقة توجد العديد من النماذج التي تدعمها Xamarin لهذه الغاية مثل نموذج MVVM الذي يستخدم بفعالية ضمن Xamarin لتنظيم وفصل الأجزاء المسؤولة عن الواجهات عن الأجزاء المسؤولة عن منطق العمل عن تلك المسؤولة عن التعامل مع مزودات البيانات البعيدة أو المحلية باختلاف أنواعها.
</p>

<p>
	من النماذج التي أفضلها شخصيًّا هو نموذج المستودع Repository الذي أستخدمه على نحو واسع في جميع أنواع التطبيقات التي أعمل عليها. فهو أسلوب جميل ومنطقي ويسمح بتطوير التطبيق بشكل سلس وسريع للعمل في مختلف أنواع البيئات، وهو متوافق للعمل مع نموذج MVVM.
</p>

<p>
	يسمح نموذج المستودع بعزل الشيفرة البرمجيّة المسؤولة عن التعامل مع البيانات عن منطق البرنامج business logic. وفي هذا الأمر عدة فوائد من أهمّها:
</p>

<ol>
<li>
		تنظيم البرنامج، وجعله أكثر قابليّة للفهم والتطوير.
	</li>
	<li>
		إجراء تطوير على أسلوب التعامل مع البيانات دون إجراء أي تغيير في منطق عمل البرنامج.
	</li>
	<li>
		إمكانيّة إجراء تغيير جذري لنوع الخدمة التي نستخدمها لتخزين البيانات دون تغيير يُذكر في منطق العمل.
	</li>
</ol>
<p>
	سأخوض مباشرةً في كيفية اعتماد هذا النموذج في تطبيقنا هذا. حيث سنحتاج إلى استخدام واجهة واحدة Interface مع صنف واحد يُحقّقها. لتنعش ذاكرتك حول الواجهات انظر <a href="https://academy.hsoub.com/programming/c-sharp/%D8%A7%D9%84%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-interfaces-%D9%88%D8%A7%D9%84%D9%85%D8%AC%D9%85%D9%88%D8%B9%D8%A7%D8%AA-collections-%D9%81%D9%8A-%D9%84%D8%BA%D8%A9-%D8%B3%D9%8A-%D8%B4%D8%A7%D8%B1%D8%A8-c-r348/" rel="">هذا الدرس</a>. لنبدأ الآن في بناء هذا التطبيق وذلك في الفقرة التالية.
</p>

<h3 id="بناء-التطبيق">
	بناء التطبيق
</h3>

<p>
	ابدأ بإنشاء مشروع جديد من النوع Blank App (Xamarin.Forms Portable) وسمّه ContactsApp ثم أبق فقط على المشروعين ContactsApp (Portable) و ContactsApp.Droid كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-visual-studio-2015-community-%D9%88%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-xamarin-%D9%84%D9%84%D8%B9%D9%85%D9%84-r373/" rel="">هذا الدرس</a>.<br>
	من نافذة مستكشف الحل Solution Explorer انقر بزر الفأرة الأيمن على المشروع ContactsApp واختر من القائمة التي ستظهر الخيار Add ثم من القائمة الفرعية الخيار New Folder لإضافة مجلّد جديد. سمّ هذا المجلّد بالاسم Entities، وبعد أن يظهر في نافذة الحل Solution Explore انقر عليه بزر الفأرة الأيمن واختر الخيار Add ومن القائمة الفرعية اختر Class. ستظهر نافذة تسمح لك بتعيين اسم لهذا الصنف. اختر الاسم Contact له. هذا الصنف هو حجر البناء الأساسي لهذا البرنامج والذي يمثّل منطق العمل فيه. احرص على جعل محتويات الملف Contact.cs كما يلي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9330_7">
<span class="kwd">namespace</span><span class="pln"> </span><span class="typ">ContactsApp</span><span class="pun">.</span><span class="typ">Entities</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">Contact</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">int</span><span class="pln"> </span><span class="typ">Id</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> get</span><span class="pun">;</span><span class="pln"> </span><span class="typ">set</span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> string </span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> get</span><span class="pun">;</span><span class="pln"> </span><span class="typ">set</span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> string </span><span class="typ">LastName</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> get</span><span class="pun">;</span><span class="pln"> </span><span class="typ">set</span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> string </span><span class="typ">Tel</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> get</span><span class="pun">;</span><span class="pln"> </span><span class="typ">set</span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> string </span><span class="typ">EMail</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> get</span><span class="pun">;</span><span class="pln"> </span><span class="typ">set</span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> string </span><span class="typ">Hobbies</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> get</span><span class="pun">;</span><span class="pln"> </span><span class="typ">set</span><span class="pun">;</span><span class="pln"> </span><span class="pun">}</span><span class="pln">

        </span><span class="kwd">public</span><span class="pln"> override string </span><span class="typ">ToString</span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="kwd">return</span><span class="pln"> string</span><span class="pun">.</span><span class="typ">Concat</span><span class="pun">(</span><span class="typ">FirstName</span><span class="pun">,</span><span class="pln"> </span><span class="str">" "</span><span class="pun">,</span><span class="pln"> </span><span class="typ">LastName</span><span class="pun">);</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	يحتوي الصنف Contact كما يظهر من الشكل السابق على البيانات الأساسيّة التي تحتاجها أيّة جهة اتصال، بالإضافة إلى خاصيّة الهوايات Hobbies التي قد تبدو غريبة قليلًا بالنسبة لجهة اتصال.<br>
	انقر مرّة أخرى بزر الفأرة الأيمن على المشروع ContactsApp ثم اختر من القائمة التي ستظهر الخيار Add ثم من القائمة الفرعية الخيار New Folder لإضافة مجلّد جديد. سمّ هذا المجلّد بالاسم Abstract، وبعد أن يظهر في نافذة الحل Solution Explore انقر عليه بزر الفأرة الأيمن واختر الخيار Add ومن القائمة الفرعية اختر New Item. ستظهر نافذة تسمح لك بتعيين نوع العنصر المراد إضافته. اختر واجهة Interface وعيّن الاسم IContactsRepository لها. واحرص على أن تكون محتويات الملف IContactsRepository.cs كما يلي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9330_7">
<code class="hljs cs"><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Threading</span><span class="pun">.</span><span class="typ">Tasks</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Collections</span><span class="pun">.</span><span class="typ">ObjectModel</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">ContactsApp</span><span class="pun">.</span><span class="typ">Entities</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">ContactsApp</span><span class="pun">.</span><span class="typ">Abstract</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">interface</span></span><span class="pln"> </span><span class="typ">IContactsRepository</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="typ">Task</span><span class="pun">&lt;</span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">Contact</span><span class="pun">&gt;&gt;</span><span class="pln"> </span><span class="typ">GetContactsAsync</span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pln"> firstName</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pln"> lastName</span><span class="pun">);</span><span class="pln">

        </span><span class="typ">Task</span><span class="str">&lt;</span><span class="hljs-keyword"><span class="str">bool</span></span><span class="str">&gt;</span><span class="pln"> </span><span class="typ">AddContactAsync</span><span class="pun">(</span><span class="typ">Contact</span><span class="pln"> contactToAdd</span><span class="pun">);</span><span class="pln">

        </span><span class="typ">Task</span><span class="str">&lt;</span><span class="hljs-keyword"><span class="str">bool</span></span><span class="str">&gt;</span><span class="pln"> </span><span class="typ">UpdateContactAsync</span><span class="pun">(</span><span class="typ">Contact</span><span class="pln"> contactToUpdate</span><span class="pun">);</span><span class="pln">

        </span><span class="typ">Task</span><span class="str">&lt;</span><span class="hljs-keyword"><span class="str">bool</span></span><span class="str">&gt;</span><span class="pln"> </span><span class="typ">DeleteContactAsync</span><span class="pun">(</span><span class="typ">Contact</span><span class="pln"> contactToDelete</span><span class="pun">);</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>
	تُستَخدَم الواجهات عمومًا عندما نرغب بتجريد Abstraction الأمور وجعلها عموميّةً وفي ذلك فائدة كبيرة في جعل الشيفرة البرمجيّة أكثر قابليّة للفهم ولإعادة الاستخدام. وهذا سبب إضافة هذه الواجهة إلى المجلّد Abstract. لا تحتوي الواجهات على أيّة شيفرة برمجيّة كما نعلم، فكل ما تحتويه هو عبارة عن تصاريح لتوابع يجب تحقيقها ضمن أيّ صنف يرغب بتحقيق هذه الواجهة. تحتوي هذه الواجهة باختصار على العمليّات الأساسيّة التي يحتاجها تطبيقنا لإنجاز المهام المنوطة به وهي: الحصول على جهات الاتصال حسب الاسم والكنية GetContactsAsync، وإضافة جهة اتصال جديدة AddContactAsync، وتحديث جهة اتصال موجودة مسبقًا UpdateContactAsync، وحذف جهة اتصال DeleteContactAsync. أمّا سبب وجود الكلمة Async في كلّ من هذه التوابع فهو للإشارة إلى أنّه يُفترض بها أن تستخدم تقنيّة البرمجة غير المتزامنة Asynchronous Programming التي تحدثنا عنها في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D9%85%D9%82%D8%AF%D9%91%D9%85%D8%A9-%D8%A5%D9%84%D9%89-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D8%BA%D9%8A%D8%B1-%D8%A7%D9%84%D9%85%D8%AA%D8%B2%D8%A7%D9%85%D9%86%D8%A9-%D9%81%D9%8A-xamarin-r448/" rel="">هذا الدرس</a>. المثير في الأمر أنّ هذه الواجهة لا تهتم بمكان وجود البيانات أو كيفيّة الحصول عليها والتعامل معها. إنّما تهتم فقط بما يحتاجه التطبيق وبشكل مجرّد.
</p>

<p>
	سنكرّر الآن نفس العمليّة لإضافة مجلّد جديد ضمن المشروع ContactsApp.cs واسمه Concrete وهو الذي سيحتوي على الصنف الذي سيحقّق الواجهة IContactsRepository السابقة. انقر بزر الفأرة الأيمن على هذا المجلّد واختر Add. ومن القائمة الفرعية اختر Class. سمّ هذا الصنف بالاسم MemoryContactsRepository واحرص على أن تكون محتوياته كما يلي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9330_7">
<code class="hljs cs"><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Collections</span><span class="pun">.</span><span class="typ">Generic</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Linq</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Threading</span><span class="pun">.</span><span class="typ">Tasks</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Collections</span><span class="pun">.</span><span class="typ">ObjectModel</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">ContactsApp</span><span class="pun">.</span><span class="typ">Abstract</span><span class="pun">;</span><span class="pln">
</span><span class="hljs-keyword"><span class="kwd">using</span></span><span class="pln"> </span><span class="typ">ContactsApp</span><span class="pun">.</span><span class="typ">Entities</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">ContactsApp</span><span class="pun">.</span><span class="typ">Concrete</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">class</span></span><span class="pln"> </span><span class="typ">MemoryContactsRepository</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">IContactsRepository</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="hljs-keyword"><span class="kwd">private</span></span><span class="pln"> </span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">Contact</span><span class="pun">&gt;</span><span class="pln"> contacts</span><span class="pun">;</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-title"><span class="typ">MemoryContactsRepository</span></span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            contacts </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">Contact</span><span class="pun">&gt;()</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">Contact</span><span class="pun">()</span><span class="pln">
                </span><span class="pun">{</span><span class="pln">
                    </span><span class="typ">Id</span><span class="pun">=</span><span class="hljs-number"><span class="lit">1</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-string"><span class="str">"Ahmad"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">LastName</span><span class="pun">=</span><span class="hljs-string"><span class="str">"Saeed"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Tel</span><span class="pun">=</span><span class="hljs-string"><span class="str">"123456"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">EMail</span><span class="pun">=</span><span class="hljs-string"><span class="str">"admin@example.com"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Hobbies</span><span class="pun">=</span><span class="hljs-string"><span class="str">"Swimming"</span></span><span class="pln">
                </span><span class="pun">},</span><span class="pln">
                </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">Contact</span><span class="pun">()</span><span class="pln">
                </span><span class="pun">{</span><span class="pln">
                    </span><span class="typ">Id</span><span class="pun">=</span><span class="hljs-number"><span class="lit">2</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-string"><span class="str">"Mahmood"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">LastName</span><span class="pun">=</span><span class="hljs-string"><span class="str">"Maktabi"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Tel</span><span class="pun">=</span><span class="hljs-string"><span class="str">"852136"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">EMail</span><span class="pun">=</span><span class="hljs-string"><span class="str">"info@example.com"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Hobbies</span><span class="pun">=</span><span class="hljs-string"><span class="str">"Reading"</span></span><span class="pln">
                </span><span class="pun">},</span><span class="pln">
                </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">Contact</span><span class="pun">()</span><span class="pln">
                </span><span class="pun">{</span><span class="pln">
                    </span><span class="typ">Id</span><span class="pun">=</span><span class="hljs-number"><span class="lit">3</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-string"><span class="str">"Mazen"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">LastName</span><span class="pun">=</span><span class="hljs-string"><span class="str">"Najem"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Tel</span><span class="pun">=</span><span class="hljs-string"><span class="str">"987456"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">EMail</span><span class="pun">=</span><span class="hljs-string"><span class="str">"it@example.com"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Hobbies</span><span class="pun">=</span><span class="hljs-string"><span class="str">"Swimming"</span></span><span class="pln">
                </span><span class="pun">},</span><span class="pln">
                </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">Contact</span><span class="pun">()</span><span class="pln">
                </span><span class="pun">{</span><span class="pln">
                    </span><span class="typ">Id</span><span class="pun">=</span><span class="hljs-number"><span class="lit">4</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-string"><span class="str">"Sawsan"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">LastName</span><span class="pun">=</span><span class="hljs-string"><span class="str">"Hilal"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Tel</span><span class="pun">=</span><span class="hljs-string"><span class="str">"741258"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">EMail</span><span class="pun">=</span><span class="hljs-string"><span class="str">"sales@example.com"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Hobbies</span><span class="pun">=</span><span class="hljs-string"><span class="str">"Writing, Reading"</span></span><span class="pln">
                </span><span class="pun">},</span><span class="pln">
                </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">Contact</span><span class="pun">()</span><span class="pln">
                </span><span class="pun">{</span><span class="pln">
                    </span><span class="typ">Id</span><span class="pun">=</span><span class="hljs-number"><span class="lit">5</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">FirstName</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="hljs-string"><span class="str">"Musab"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">LastName</span><span class="pun">=</span><span class="hljs-string"><span class="str">"Aga"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Tel</span><span class="pun">=</span><span class="hljs-string"><span class="str">"357159"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">EMail</span><span class="pun">=</span><span class="hljs-string"><span class="str">"admin@example.com"</span></span><span class="pun">,</span><span class="pln">
                    </span><span class="typ">Hobbies</span><span class="pun">=</span><span class="hljs-string"><span class="str">"Sport"</span></span><span class="pln">
                </span><span class="pun">}</span><span class="pln">
            </span><span class="pun">};</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">async</span></span><span class="pln"> </span><span class="typ">Task</span><span class="pun">&lt;</span><span class="typ">ObservableCollection</span><span class="pun">&lt;</span><span class="typ">Contact</span><span class="pun">&gt;&gt;</span><span class="pln"> </span><span class="hljs-title"><span class="typ">GetContactsAsync</span></span><span class="pun">(</span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pln"> firstName</span><span class="pun">,</span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">string</span></span><span class="pln"> lastName</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">throw</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">NotImplementedException</span><span class="pun">();</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">async</span></span><span class="pln"> </span><span class="typ">Task</span><span class="str">&lt;</span><span class="hljs-keyword"><span class="str">bool</span></span><span class="str">&gt;</span><span class="pln"> </span><span class="hljs-title"><span class="typ">AddContactAsync</span></span><span class="pun">(</span><span class="typ">Contact</span><span class="pln"> contactToAdd</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">throw</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">NotImplementedException</span><span class="pun">();</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">async</span></span><span class="pln"> </span><span class="typ">Task</span><span class="str">&lt;</span><span class="hljs-keyword"><span class="str">bool</span></span><span class="str">&gt;</span><span class="pln"> </span><span class="hljs-title"><span class="typ">UpdateContactAsync</span></span><span class="pun">(</span><span class="typ">Contact</span><span class="pln"> contactToUpdate</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">throw</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">NotImplementedException</span><span class="pun">();</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
        </span><span class="hljs-keyword"><span class="kwd">public</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="pln">async</span></span><span class="pln"> </span><span class="typ">Task</span><span class="str">&lt;</span><span class="hljs-keyword"><span class="str">bool</span></span><span class="str">&gt;</span><span class="pln"> </span><span class="hljs-title"><span class="typ">DeleteContactAsync</span></span><span class="pun">(</span><span class="typ">Contact</span><span class="pln"> contactToDelete</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="hljs-keyword"><span class="kwd">throw</span></span><span class="pln"> </span><span class="hljs-keyword"><span class="kwd">new</span></span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">NotImplementedException</span><span class="pun">();</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></code></pre>

<p>
	الأمر الملفت للنظر هنا أنّ بيانات جهات الاتصال موجودة ضمن هذا الصنف بالفعل وتحديدًا ضمن بانيته. وهي مخزّنة ضمن المتغيّر contacts وهو معرّف على مستوى الصنف ومن النوع العمومي ObservableCollection الذي سنتحدّث عنه في الدرس التالي. يكفي الآن أن تعرف أنّه عبارة عن مجموعة عناصرها كائنات من النوع Contact وهي تُفيد في التطبيقات التي تُستخدَم فيها البرمجة غير المتزامنة. من غير الواقعي بكل تأكيد وجود البيانات مخزّنة في الصنف بهذه الطريقة، فالمفترض أن تكون ضمن قاعدة بيانات محليّة أو بعيدة أو حتى ضمن ملف عادي. في الواقع تبرز هنا قوّة نموذج المستودع Repository في عزل أسلوب الحصول على البيانات عن البرنامج الفعلي.
</p>

<p>
	من الواضح أيضًا أنّ التوابع الموجودة هنا تحتوي في الحقيقة على شيفرة برمجيّة تؤدّي إلى رمي الاستثناء NotImplementedException وذلك لتذكرينا بعدم جاهزيتها بعد.<br>
	سيبدو مستكشف الحل في نهاية المطاف شبيهًا بالشكل التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22715" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig03.png.af80daa35437bf5ebc0ab9948cc583da.png" rel=""><img alt="fig03.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22715" data-unique="jrgt3mb96" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig03.thumb.png.3c4ebb854d72069bff6a7976c82e2c51.png"></a>
</p>

<h3 id="الخلاصة">
	الخلاصة
</h3>

<p>
	هذا الدرس هو المقدّمة لتطبيق جهات الاتصال الذي سنتابع بناءه على مدى الدرسين التاليين. تناولنا في هذا الدرس فكرة التطبيق الأساسيّة، وتوضيح فكرة نموذج المستودع Repository من خلال بناء واجهة تمثّله بالإضافة إلى صنف يحقّقها. سيمكننا من خلال هذا الصنف (صنف المستودع) التعامل مع بيانات موجودة ضمن ذاكرة التطبيق فقط. ورغم كون هذا الأسلوب غير واقعي، إلَّا أنّه ضروري في تبسيط الأمور وجعلها أسهل للفهم. كما أنشأنا صنف يمثّل جهة الاتصال في التطبيق. ورأينا ماهية العلاقة بينه وبين صنف المستودع، من خلال الاستدعاءات إلى التوابع الموجودة ضمن الصنف الأخير.
</p>

<p>
	 
</p>

<p>
	حقوق الصورة البارزة محفوظة لـ <a href="http://www.freepik.com/free-vector/smartphone-with-bubble-avatars_1086749.htm" rel="external nofollow">Freepik</a>
</p>
]]></description><guid isPermaLink="false">434</guid><pubDate>Tue, 25 Apr 2017 21:01:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x62A;&#x62D;&#x648;&#x64A;&#x644;&#x627;&#x62A; &#x627;&#x644;&#x647;&#x646;&#x62F;&#x633;&#x64A;&#x629; &#x627;&#x644;&#x623;&#x633;&#x627;&#x633;&#x64A;&#x651;&#x629; &#x641;&#x64A; &#x62A;&#x637;&#x628;&#x64A;&#x642;&#x627;&#x62A; Xamarin</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%A7%D9%84%D8%AA%D8%AD%D9%88%D9%8A%D9%84%D8%A7%D8%AA-%D8%A7%D9%84%D9%87%D9%86%D8%AF%D8%B3%D9%8A%D8%A9-%D8%A7%D9%84%D8%A3%D8%B3%D8%A7%D8%B3%D9%8A%D9%91%D8%A9-%D9%81%D9%8A-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-r452/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.4fd94661899fdf901e755d7ac1f75359.png" /></p>

<p>
	تُعتبر التحويلات الهندسيّة Transforms من المفاهيم الرياضيّة الضروريّة في عالم البرمجة الرسوميّة. هناك ثلاثة أنواع من التحويلات الهندسيّة:
</p>

<ol>
<li>
		الانسحاب Translation 
	</li>
	<li>
		الدوران Rotation 
	</li>
	<li>
		التحاكي Scale
	</li>
</ol>
<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22569" data-unique="56xhk6ikj" src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.0c2b1430d4eb4ed72b21d2b6bdbfaf8a.png"></p>

<p>
	تعتمد التحويلات الهندسيّة في الأساس على المصفوفات Matrices. وهي بنى رياضيّة مهمّة تُعتبر العمود الفقري لأيّ تحويل هندسي. لحسن الحظ تبسّط Xamarin الأمر، وتجعل من استخدام التحويلات الثلاثة السابقة أمرًا يسيرًا. سنتحدث في هذا الدرس من <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/" rel="">سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms</a> عن كلّ نوع من الأنواع الثلاثة السابقة وكيفيّة تطبيقه ضمن مثال عملي بسيط.
</p>

<h3>
	الانسحاب Translation
</h3>

<p>
	الانسحاب هو الانتقال دون التغيير في حجم الجسم، أو إجراء أي عمليّة تدوير له. يتم تدوير أي عنصر من الصنف VisualElement عن طريق الخاصيّتين TranslationX و TranslationY. عند إسناد قيمة موجبة للخاصيّة TranslationX فإنّ ذلك سيؤدّي إلى نقل الجسم أفقيًّا إلى اليمين (بالنسبة إلى موقعه الحالي). وعند إسناد قيمة موجبة للخاصيّة TranslationY فإنّ ذلك سيؤدّي إلى نقل الجسم عاموديًّا إلى الأسفل (بالنسبة إلى موقعه الحالي). لنبدأ باختبار هذا النوع من التحويلات. ابدأ بإنشاء مشروع جديد من النوع Blank App (Xamarin.Forms Portable) وسمّه TransformsApp، ثم أبق فقط على المشروعين TransformsApp (Portable) و TransformsApp.Droid كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-visual-studio-2015-community-%D9%88%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-xamarin-%D9%84%D9%84%D8%B9%D9%85%D9%84-r373/" rel="">هذا الدرس</a>. بعد ذلك سنضيف صفحة محتوى تعتمد على رُماز XAML كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xaml-r453/" rel="">هذا الدرس</a> سنسمّها TranslationPage. احرص على أن تكون محتويات هذه الصفحة على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1804_7">
<span class="pun">&lt;</span><span class="typ">ContentPage</span><span class="pln"> xmlns</span><span class="pun">=</span><span class="str">"http://xamarin.com/schemas/2014/forms"</span><span class="pln"> xmlns</span><span class="pun">:</span><span class="pln">x</span><span class="pun">=</span><span class="str">"http://schemas.microsoft.com/winfx/2009/xaml"</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Class</span><span class="pun">=</span><span class="str">"TransformsApp.TranslationPage"</span><span class="pun">&gt;</span><span class="pln">
  </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pln"> </span><span class="typ">Padding</span><span class="pun">=</span><span class="str">"20, 10"</span><span class="pun">&gt;</span><span class="pln">
    </span><span class="pun">&lt;</span><span class="typ">Frame</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"frame"</span><span class="pln"> </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln"> </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"CenterAndExpand"</span><span class="pln"> </span><span class="typ">OutlineColor</span><span class="pun">=</span><span class="str">"Accent"</span><span class="pun">&gt;</span><span class="pln">
      </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"TEXT"</span><span class="pln"> </span><span class="typ">FontSize</span><span class="pun">=</span><span class="str">"Large"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
    </span><span class="pun">&lt;/</span><span class="typ">Frame</span><span class="pun">&gt;</span><span class="pln">
    </span><span class="pun">&lt;</span><span class="typ">Slider</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"xSlider"</span><span class="pln"> </span><span class="typ">Minimum</span><span class="pun">=</span><span class="str">"-200"</span><span class="pln"> </span><span class="typ">Maximum</span><span class="pun">=</span><span class="str">"200"</span><span class="pln"> </span><span class="typ">Value</span><span class="pun">=</span><span class="str">"{Binding Source={x:Reference frame}, Path=TranslationX}"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
    </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"{Binding Source={x:Reference xSlider}, Path=Value, StringFormat='TranslationX = {0:F0}'}"</span><span class="pln"> </span><span class="typ">HorizontalTextAlignment</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
    </span><span class="pun">&lt;</span><span class="typ">Slider</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"ySlider"</span><span class="pln">
            </span><span class="typ">Minimum</span><span class="pun">=</span><span class="str">"-200"</span><span class="pln"> </span><span class="typ">Maximum</span><span class="pun">=</span><span class="str">"200"</span><span class="pln"> </span><span class="typ">Value</span><span class="pun">=</span><span class="str">"{Binding Source={x:Reference frame}, Path=TranslationY }"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
    </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"{Binding Source={x:Reference ySlider}, Path=Value, StringFormat='TranslationY = {0:F0}'}"</span><span class="pln"> </span><span class="typ">HorizontalTextAlignment</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
  </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">    
</span><span class="pun">&lt;/</span><span class="typ">ContentPage</span><span class="pun">&gt;</span></pre>

<p>
	يستخدم الرماز السابق تقنية ربط البيانات التي تحدثنا عنها في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%B1%D8%A8%D8%B7-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-xamarin-r458/" rel="">هذا الدرس</a>. حيث يتحكّم بموقع عنصر frame يحتوي على لصيقة ضمنه، وذلك عن طريق عنصري Slider. يتحكم العنصر العلوي بالانسحاب الأفقي، أمّا العنصر السفلي فيتحكم بالانسحاب الشاقولي. تتم هذه العملية من خلال ربط الخاصيّة Value من عنصر Slider المسمى xSlider بالخاصيّة TranslationX لعنصر frame. وكذلك الأمر بالنسبة لعنصر Slider المسمى ySlider حيث ترتبط الخاصية Value له بالخاصية TranslationY لعنصر frame. عدّل بانية الصنف App الموجودة في الملف App.cs لتصبح على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1804_9">
<span class="kwd">public</span><span class="pln"> </span><span class="typ">App</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="com">// The root page of your application</span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">TranslationPage</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	نفّذ البرنامج لتحصل على خرج شبيه بما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22531" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.png.85a62e22caa643c02a5fd9388b060369.png" rel=""><img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22531" data-unique="1472y56tx" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.thumb.png.fb9960d6aa92a47db4e04e81af164eea.png"></a>
</p>

<p>
	أجر بعض التجارب ولاحظ الانسيابية في هذه الحركة.
</p>

<h3>
	الدوران Rotation
</h3>

<p>
	يمكن تدوير أي عنصر مرئي في Xamarin وذلك بتحديد مركز الدوران وزاوية الدوران. يتم تحديد زاوية الدوران بالدرجات، وتشير القيم الموجبة لزاوية الدوران إلى الدوران باتجاه عقارب الساعة. يتم تحديد مركز دوران أي عنصر عن طريق الخاصيتين AnchorX و AnchorY له. كما يمكن تحديد زاوية الدوران من خلال الخاصيّة Rotation. إذا لم يتم تحديد قيمة للخاصيتين AnchorX و AnchorY فسيكون مركز الدوران هو نفسه مركز العنصر المرئي بشكل افتراضي. لنرى كيف يعمل ذلك عن طريق مثال بسيط. أضف إلى المشروع الحالي صفحة محتوى تعتمد على رُماز XAML كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xaml-r453/" rel="">هذا الدرس</a> سنسمّها RotationPage. احرص على أن تكون محتويات هذه الصفحة على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1804_11">
<span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
</span><span class="pun">&lt;</span><span class="typ">ContentPage</span><span class="pln"> xmlns</span><span class="pun">=</span><span class="str">"http://xamarin.com/schemas/2014/forms"</span><span class="pln">
             xmlns</span><span class="pun">:</span><span class="pln">x</span><span class="pun">=</span><span class="str">"http://schemas.microsoft.com/winfx/2009/xaml"</span><span class="pln">
             x</span><span class="pun">:</span><span class="typ">Class</span><span class="pun">=</span><span class="str">"TransformsApp.RotationPage"</span><span class="pun">&gt;</span><span class="pln">
  </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pln"> </span><span class="typ">Padding</span><span class="pun">=</span><span class="str">"20, 10"</span><span class="pun">&gt;</span><span class="pln">
    </span><span class="pun">&lt;</span><span class="typ">Frame</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"frame"</span><span class="pln"> </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln"> </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"CenterAndExpand"</span><span class="pln"> </span><span class="typ">OutlineColor</span><span class="pun">=</span><span class="str">"Accent"</span><span class="pun">&gt;</span><span class="pln">
      </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"TEXT"</span><span class="pln"> </span><span class="typ">FontSize</span><span class="pun">=</span><span class="str">"Large"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
    </span><span class="pun">&lt;/</span><span class="typ">Frame</span><span class="pun">&gt;</span><span class="pln">
    
    </span><span class="pun">&lt;</span><span class="typ">Slider</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"rotationSlider"</span><span class="pln"> </span><span class="typ">Maximum</span><span class="pun">=</span><span class="str">"360"</span><span class="pln"> </span><span class="typ">Value</span><span class="pun">=</span><span class="str">"{Binding Source={x:Reference frame}, Path=Rotation}"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
    
    </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"{Binding Source={x:Reference rotationSlider}, Path=Value, StringFormat='Rotation = {0:F0}'}"</span><span class="pln"> </span><span class="typ">HorizontalTextAlignment</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
    
    </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pln"> </span><span class="typ">Orientation</span><span class="pun">=</span><span class="str">"Horizontal"</span><span class="pln"> </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pun">&gt;</span><span class="pln">
      </span><span class="pun">&lt;</span><span class="typ">Stepper</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"anchorXStepper"</span><span class="pln"> </span><span class="typ">Minimum</span><span class="pun">=</span><span class="str">"-1"</span><span class="pln"> </span><span class="typ">Maximum</span><span class="pun">=</span><span class="str">"2"</span><span class="pln"> </span><span class="typ">Increment</span><span class="pun">=</span><span class="str">"0.25"</span><span class="pln"> </span><span class="typ">Value</span><span class="pun">=</span><span class="str">"{Binding Source={x:Reference frame}, Path=AnchorX}"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
      </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"{Binding Source={x:Reference anchorXStepper}, Path=Value, StringFormat='AnchorX = {0:F2}'}"</span><span class="pln"> </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pun">/&gt;</span><span class="pln">
    </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">
    
    </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pln"> </span><span class="typ">Orientation</span><span class="pun">=</span><span class="str">"Horizontal"</span><span class="pln"> </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pun">&gt;</span><span class="pln">
      </span><span class="pun">&lt;</span><span class="typ">Stepper</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"anchorYStepper"</span><span class="pln">
               </span><span class="typ">Minimum</span><span class="pun">=</span><span class="str">"-1"</span><span class="pln"> </span><span class="typ">Maximum</span><span class="pun">=</span><span class="str">"2"</span><span class="pln"> </span><span class="typ">Increment</span><span class="pun">=</span><span class="str">"0.25"</span><span class="pln"> </span><span class="typ">Value</span><span class="pun">=</span><span class="str">"{Binding Source={x:Reference frame}, Path=AnchorY}"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
      </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"{Binding Source={x:Reference anchorYStepper}, Path=Value, StringFormat='AnchorY = {0:F2}'}"</span><span class="pln"> </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pun">/&gt;</span><span class="pln">
    </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">
    
  </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">
</span><span class="pun">&lt;/</span><span class="typ">ContentPage</span><span class="pun">&gt;</span></pre>

<p>
	يعتمد البرنامج السابق على تدوير عنصر frame يحتوي على لصيقة. سنستخدم لهذا الغرض عنصر Slider اسمه rotationSlider للتحكم بزاوية الدوران (عن طريق الربط مع الخاصية Rotation لعنصر frame). وسنستخدم أيضًا عنصري Stepper وهما anchorXStepper و anchorYStepper للتحكم بإحداثيي مركز الدوران (عن طريق الربط مع الخاصيّتين AnchorX و AnchorY لعنصر frame). لتنفيذ هذا البرنامج اذهب إلى بانية الصنف App الموجودة ضمن الملف App.cs واحرص على أن تكون على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1804_13">
<span class="kwd">public</span><span class="pln"> </span><span class="typ">App</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="com">// The root page of your application</span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">RotationPage</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	نفّذ البرنامج لتحصل على شكل شبيه بما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22532" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.png.5a9638d7a750c3c9f16c47b7ddc79587.png" rel=""><img alt="fig02.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22532" data-unique="hyw73h9kb" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.thumb.png.c3f4fcf1e708e4948f10f2da8f27d886.png"></a>
</p>

<p>
	أجر بعض التجارب واستمتع بالبرنامج!
</p>

<h3>
	التحاكي Scale
</h3>

<p>
	التحاكي هو تحويل هندسي يؤدّي إلى التغيير في الأحجام. يمكن استخدام التحاكي للتحكم بأحجام العناصر المرئيّة عن طريق الخاصية Scale لها. لهذه الخاصيّة القيمة الافتراضيّة 1. عند استخدام أي قيمة أصغر من 1 يعني ذلك أنّنا سنعمل على تصغير الحجم. وعند استخدام أي قيمة أكبر من 1 يعني ذلك أنّنا سنكبّر الحجم. فمثًل القيمة 3 تعني أنّنا سنكبّر الحجم 3 مرات، وهكذا. القيمة 0 للخاصيّة Scale مسموحة ولكن ستؤدّي إلى اختفاء العنصر. كما يمكن استخدام القيم السالبة للخاصيّة Scale ولكن سيؤدّي ذلك إلى قلب العنصر مع بقاء المفهوم السابق على ما هو عليه. أي أنّ القيمة -1 ستؤدّي إل قلب العنصر لكن مع بقاء الحجم نفسه. لتجربة التحاكي أضف إلى المشروع الحالي صفحة محتوى تعتمد على رُماز XAML كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xaml-r453/" rel="">هذا الدرس</a> سنسمّها ScalePage. احرص على أن تكون محتويات هذه الصفحة على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1804_15">
<span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
</span><span class="pun">&lt;</span><span class="typ">ContentPage</span><span class="pln"> xmlns</span><span class="pun">=</span><span class="str">"http://xamarin.com/schemas/2014/forms"</span><span class="pln">
             xmlns</span><span class="pun">:</span><span class="pln">x</span><span class="pun">=</span><span class="str">"http://schemas.microsoft.com/winfx/2009/xaml"</span><span class="pln">
             x</span><span class="pun">:</span><span class="typ">Class</span><span class="pun">=</span><span class="str">"TransformsApp.ScalePage"</span><span class="pun">&gt;</span><span class="pln">

  </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pln"> </span><span class="typ">Padding</span><span class="pun">=</span><span class="str">"20, 10"</span><span class="pun">&gt;</span><span class="pln">
    </span><span class="pun">&lt;</span><span class="typ">Frame</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"frame"</span><span class="pln"> </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln"> </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"CenterAndExpand"</span><span class="pln"> </span><span class="typ">OutlineColor</span><span class="pun">=</span><span class="str">"Accent"</span><span class="pun">&gt;</span><span class="pln">
      </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"TEXT"</span><span class="pln"> </span><span class="typ">FontSize</span><span class="pun">=</span><span class="str">"Large"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
    </span><span class="pun">&lt;/</span><span class="typ">Frame</span><span class="pun">&gt;</span><span class="pln">
    
    </span><span class="pun">&lt;</span><span class="typ">Slider</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"scaleSlider"</span><span class="pln"> </span><span class="typ">Minimum</span><span class="pun">=</span><span class="str">"-10"</span><span class="pln"> </span><span class="typ">Maximum</span><span class="pun">=</span><span class="str">"10"</span><span class="pln"> </span><span class="typ">Value</span><span class="pun">=</span><span class="str">"{Binding Source={x:Reference frame}, Path=Scale}"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
    
    </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"{Binding Source={x:Reference scaleSlider}, Path=Value, StringFormat='Scale = {0:F1}'}"</span><span class="pln"> </span><span class="typ">HorizontalTextAlignment</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
  </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">
  
</span><span class="pun">&lt;/</span><span class="typ">ContentPage</span><span class="pun">&gt;</span></pre>

<p>
	اذهب إلى بانية الصنف App الموجودة ضمن الملف App.cs واحرص على أن تكون على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1804_17">
<span class="kwd">public</span><span class="pln"> </span><span class="typ">App</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="com">// The root page of your application</span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ScalePage</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	نفّذ البرنامج لتحصل على شكل شبيه بما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22533" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig03.png.dd0a40f22adf6555c1031ae311382bf7.png" rel=""><img alt="fig03.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22533" data-unique="uxywcc2xx" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig03.thumb.png.c871ea1af7ecbc360f82be2a5b24622a.png"></a>
</p>

<h2>
	الخلاصة
</h2>

<p>
	تحدثنا في هذا الدرس عن التحويلات الهندسية الأساسيّة: الانسحاب Translation والدوران Rotation والتحاكي Scale وكيفية التعامل معها من خلال Xamarin. في الحقيقة تكمن الحاجة لمثل هذه التحويلات غالبًا في تطبيقات الألعاب أو تلك التي تعتمد على الجانب الرسومي. سنعمل على تطبيق بعض من هذه التحويلات في الدروس القادمة من هذه السلسلة.
</p>
]]></description><guid isPermaLink="false">452</guid><pubDate>Thu, 13 Apr 2017 16:03:25 +0000</pubDate></item><item><title>&#x627;&#x644;&#x62A;&#x646;&#x642;&#x651;&#x644; &#x628;&#x64A;&#x646; &#x627;&#x644;&#x635;&#x641;&#x62D;&#x627;&#x62A; &#x641;&#x64A; Xamarin</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%A7%D9%84%D8%AA%D9%86%D9%82%D9%91%D9%84-%D8%A8%D9%8A%D9%86-%D8%A7%D9%84%D8%B5%D9%81%D8%AD%D8%A7%D8%AA-%D9%81%D9%8A-xamarin-r450/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.dc74dd7193a4966dbcb4a4a31e0d8b9c.png" /></p>

<p>
	تتكوّن تطبيقات الأجهزة المحمولة عادةً من صفحات منفصلة يتنقّل بينها المستخدم لاستفادة من الإمكانيات التي يقدمها التطبيق. بالنسبة لتطبيقات أندرويد فإنّ زر الرجوع إلى الخلف يُعتبر أساسيًا في عمليّة التنقّل هذه. سنتعرّف في هذا الدرس من سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms على كيفيّة التنقّل بين صفحات التطبيق. سنتحدّث أولًا عن مفهوم التنقّل بين الصفحات في التطبيق الواحد، ثمّ سنتحدّث عن أنواع صفحات المحتوى المستخدمة في التنقّل وذلك عن طريق مثال عملي بسيط.
</p>

<h3>
	مفهوم التنقّل بين صفحات التطبيق
</h3>

<p>
	يشبه التنقّل بين صفحات التطبيق مبدأ عمل المكدّس Stack إلى حدّ كبير. والمكدّس كما هو معلوم هو بنية معطيات تدعم مفهوم LIFO (الذي يدخل أخيرًا يخرج أولًا). فعند الانتقال من الصفحة A إلى الصفحة B، تُدفع pushed الصفحة B إلى أعلى المكدّس مما يؤدّي إلى ظهورها أمام المستخدم. وكذلك الأمر عند الانتقال من الصفحة B إلى الصفحة C يتم دفع الصفحة C إلى المكدّس ليتم إظهارها إلى المستخدم. أمّا عندما نريد العودة إلى الصفحة A الأصلية فيجب عندها أن تُخرج popped الصفحة C من المكدّس فتصبح الصفحة B أعلى المكدّس (أي تظهر للمستخدم) ثم تُخرج الصفحة B من المكدّس فتصبح الصفحة A أعلى المكدّس (أي تظهر للمستخدم). انظر الشكل التالي لتوضيح هذه الفكرة:
</p>

<p style="text-align: center;">
	<img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22501" data-unique="spzc1i0ju" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.png.3fc5087da071c4daf64d8a321dab8890.png"></p>

<h3>
	صفحات Modal و Modeless
</h3>

<p>
	يحتوي على كل تطبيق على صفحة رئيسيّة main page (ستكون من الصنف NavigationPage) تُعتبر العقدة الرئيسيّة التي يمكن الوصول من خلالها إلى جميع الصفحات الأخرى مهما كان عددها ومستواها. كما تميّز Xamarin بين نوعين من صفحات المحتوى التي تُستَخدم ضمن بنية التنقّل هذه وهي: الصفحات الجامدة Modal Pages والصفحات غير الجامدة Modeless Pages. الفرق بين هذين النوعين بالنسبة لتطبيقات أندرويد بسيط. وهو أنّه في الصفحات من النوع Modal لن يتم عرض عنوان الصفحة في الأعلى كما سنرى في المثال بعد قليل. أمّا في الصفحة من النوع Modeless فسيتم عنوان الصفحة في الأعلى في حال تمّ تحديده باستخدام الخاصيّة Title لصفحة المحتوى. لمعاينة الفرق بين هذه الأنواع لننشئ تطبيق عملي بسيط يوضّح هذا الأمر. ابدأ بإنشاء مشروع جديد من النوع Blank App (Xamarin.Forms Portable) وسمّه ModelessAndModal، ثم أبق فقط على المشروعين ModelessAndModal (Portable) و ModelessAndModal.Droid كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-visual-studio-2015-community-%D9%88%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-xamarin-%D9%84%D9%84%D8%B9%D9%85%D9%84-r373/" rel="">هذا الدرس</a>. بعد ذلك سنضيف ثلاث صفحات محتوى عادية (Forms ContentPage) وهي: MainPage و ModalPage و ModelessPage. عدّل محتويات الملف MainPage ليكون مماثلًا لما يلي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1468_9">
<span class="lit">1</span><span class="pln">   </span><span class="kwd">using</span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">
</span><span class="lit">2</span><span class="pln">   
</span><span class="lit">3</span><span class="pln">   </span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">ModelessAndModal</span><span class="pln">
</span><span class="lit">4</span><span class="pln">   </span><span class="pun">{</span><span class="pln">
</span><span class="lit">5</span><span class="pln">       </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
</span><span class="lit">6</span><span class="pln">       </span><span class="pun">{</span><span class="pln">
</span><span class="lit">7</span><span class="pln">           </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">MainPage</span><span class="pun">()</span><span class="pln">
</span><span class="lit">8</span><span class="pln">           </span><span class="pun">{</span><span class="pln">
</span><span class="lit">9</span><span class="pln">               </span><span class="typ">Title</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Main Page"</span><span class="pun">;</span><span class="pln">
</span><span class="lit">10</span><span class="pln">  
</span><span class="lit">11</span><span class="pln">              </span><span class="typ">Button</span><span class="pln"> gotoModelessButton </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">
</span><span class="lit">12</span><span class="pln">              </span><span class="pun">{</span><span class="pln">
</span><span class="lit">13</span><span class="pln">                  </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Go to Modeless Page"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">14</span><span class="pln">                  </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">Center</span><span class="pun">,</span><span class="pln">
</span><span class="lit">15</span><span class="pln">                  </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">CenterAndExpand</span><span class="pln">
</span><span class="lit">16</span><span class="pln">              </span><span class="pun">};</span><span class="pln">
</span><span class="lit">17</span><span class="pln">  
</span><span class="lit">18</span><span class="pln">              gotoModelessButton</span><span class="pun">.</span><span class="typ">Clicked</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> async </span><span class="pun">(</span><span class="pln">sender</span><span class="pun">,</span><span class="pln"> args</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
</span><span class="lit">19</span><span class="pln">              </span><span class="pun">{</span><span class="pln">
</span><span class="lit">20</span><span class="pln">                  await </span><span class="typ">Navigation</span><span class="pun">.</span><span class="typ">PushAsync</span><span class="pun">(</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ModelessPage</span><span class="pun">());</span><span class="pln">
</span><span class="lit">21</span><span class="pln">              </span><span class="pun">};</span><span class="pln">
</span><span class="lit">22</span><span class="pln">  
</span><span class="lit">23</span><span class="pln">              </span><span class="typ">Button</span><span class="pln"> gotoModalButton </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">
</span><span class="lit">24</span><span class="pln">              </span><span class="pun">{</span><span class="pln">
</span><span class="lit">25</span><span class="pln">                  </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Go to Modal Page"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">26</span><span class="pln">                  </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">Center</span><span class="pun">,</span><span class="pln">
</span><span class="lit">27</span><span class="pln">                  </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">CenterAndExpand</span><span class="pln">
</span><span class="lit">28</span><span class="pln">              </span><span class="pun">};</span><span class="pln">
</span><span class="lit">29</span><span class="pln">  
</span><span class="lit">30</span><span class="pln">              gotoModalButton</span><span class="pun">.</span><span class="typ">Clicked</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> async </span><span class="pun">(</span><span class="pln">sender</span><span class="pun">,</span><span class="pln"> args</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
</span><span class="lit">31</span><span class="pln">              </span><span class="pun">{</span><span class="pln">
</span><span class="lit">32</span><span class="pln">                  await </span><span class="typ">Navigation</span><span class="pun">.</span><span class="typ">PushModalAsync</span><span class="pun">(</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ModalPage</span><span class="pun">());</span><span class="pln">
</span><span class="lit">33</span><span class="pln">              </span><span class="pun">};</span><span class="pln">
</span><span class="lit">34</span><span class="pln">  
</span><span class="lit">35</span><span class="pln">              </span><span class="typ">Content</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StackLayout</span><span class="pln">
</span><span class="lit">36</span><span class="pln">              </span><span class="pun">{</span><span class="pln">
</span><span class="lit">37</span><span class="pln">                  </span><span class="typ">Children</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> gotoModelessButton</span><span class="pun">,</span><span class="pln"> gotoModalButton </span><span class="pun">}</span><span class="pln">
</span><span class="lit">38</span><span class="pln">              </span><span class="pun">};</span><span class="pln">
</span><span class="lit">39</span><span class="pln">          </span><span class="pun">}</span><span class="pln">
</span><span class="lit">40</span><span class="pln">      </span><span class="pun">}</span><span class="pln">
</span><span class="lit">41</span><span class="pln">  </span><span class="pun">}</span></pre>

<p>
	ستعرض الصفحة الرئيسية MainPage زرّين فقط. الزر الأوًل هو gotoModelessButton ووظيفته إنشاء صفحة غير جامدة modeless والانتقال اليها. أمّا الزر الثاني فهو gotoModalButton ووظيفته إنشاء صفحة جامدة modal والانتقال إليها. بالنسبة للزر الأوّل gotoModelessButton انظر إلى الأسطر من 11 حتى 21:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1468_11">
<span class="pln">
</span><span class="typ">Button</span><span class="pln"> gotoModelessButton </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Go to Modeless Page"</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">Center</span><span class="pun">,</span><span class="pln">
    </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">CenterAndExpand</span><span class="pln">
</span><span class="pun">};</span><span class="pln">

gotoModelessButton</span><span class="pun">.</span><span class="typ">Clicked</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> async </span><span class="pun">(</span><span class="pln">sender</span><span class="pun">,</span><span class="pln"> args</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    await </span><span class="typ">Navigation</span><span class="pun">.</span><span class="typ">PushAsync</span><span class="pun">(</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ModelessPage</span><span class="pun">());</span><span class="pln">
</span><span class="pun">};</span></pre>

<p>
	ننشئ في البداية كائنًا من النوع Button ونسنده إلى المتغيّر gotoModelessButton ثمّ نعيّن معالج لحدث النقر Clicked وهو عبارة عن تعبير lambda بسيط يمثّل تابع يحتاج إلى وسيطين sender و e وهو مسبوق بالكلمة المحجوزة async كما هو واضح من الشيفرة السابقة. سبب وجود الكلمة async هو أنّنا سنستخدم استدعاءً غير متزامنًا ضمن معالج الحدث هذا وهو:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1468_13">
<span class="pln">await </span><span class="typ">Navigation</span><span class="pun">.</span><span class="typ">PushAsync</span><span class="pun">(</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ModelessPage</span><span class="pun">());</span></pre>

<p>
	يعمل التابع PushAsync المُستدعى من الخاصيّة Navigation للصفحة الحالية على دفع صفحة جديدة ضمن المكدّس الخاص بالتنقّل بين الصفحات، بمعنى آخر، سيعمل هذا التابع على إظهار صفحة جديدة من النمط modeless. في السطر السابق سيتم إنشاء صفحة جديدة من النوع ModelessPage ومن ثمّ تمريرها إلى التابع PushAsync. أنصحك بمراجعة <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D9%85%D9%82%D8%AF%D9%91%D9%85%D8%A9-%D8%A5%D9%84%D9%89-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D8%BA%D9%8A%D8%B1-%D8%A7%D9%84%D9%85%D8%AA%D8%B2%D8%A7%D9%85%D9%86%D8%A9-%D9%81%D9%8A-xamarin-r448/" rel="">هذا الدرس</a> لكي تنعش ذاكرتك حول موضوع الاستدعاءات غير المتزامنة. نفس الأمر سيجري تمامًا بالنسبة للزر الخاص بالانتقال إلى الصفحة الجامدة مع فارق بسيط. وهو أنّ الاستدعاء هذه المرة سيكون من خلال التابع PushModalAsync (السطر 32) وذلك للانتقال إلى صفحة جامدة (ستكون من الصنف ModalPage). في كلّ من الحالتين السابقتين كان من الممكن أن نجعل معالجي حدثي النقر ضمن تابعين مستقلين وليس كما هو الحال من خلال تعبيري Lambda. الأمر الجدير بالملاحظة بالنسبة للصنف MainPage أيضًا هو تعيين الخاصيّة Title (السطر 9). في الحقيقة لم يكن لهذه الخاصيّة أي معنى في جميع البرامج التي أنشأناها في هذه السلسلة حتى الآن. إذ تعيين هذه الخاصيّة من عدمه لن يُحدث أيّ فرق! الجديد هنا هو في كيفيّة إنشاء الصفحة MainPage بحد ذاتها، والتي سننشئها كم جرت العادة ضمن الصنف App. انتقل إلى الملف App.cs واحرص على أن تكون بانيته مطابقة لما يلي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1468_15">
<span class="kwd">public</span><span class="pln"> </span><span class="typ">App</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="com">// The root page of your application</span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">NavigationPage</span><span class="pun">(</span><span class="kwd">new</span><span class="pln"> </span><span class="typ">MainPage</span><span class="pun">());</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	لاحظ معي الأمر الجديد هنا. نحن لا ننشئ صفحة محتوى ونسندها للخاصيّة MainPage مباشرةً كما كنّا نفعل من قبل. إنّما ننشئ صفحة محتوى (في مثالنا هي من الصنف MainPage) ثم نمرّر هذه الصفحة كوسيط إلى بانية الصنف NavigationPage. أي أنّنا في الواقع ننشئ صفحة محتوى تدعم التنقّل navigation. وهذا ما سيجعل عنوان الصفحة الرئيسيّة المُعيّن باستخدام الخاصيّة Title يظهر أعلى الصفحة كما سنرى بعد قليل. يمكننا الآن أن نجرّب هذا التطبيق. نفّذ التطبيق لتحصل على شكل شبيه بما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22500" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.png.1b7b1af30120312cf90ddeab7c57cb6f.png" rel=""><img alt="fig02.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22500" data-unique="3hg2kqoke" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.thumb.png.079d9dac3e9718dad15d40f939d165a5.png"></a>
</p>

<p>
	أوقف تنفيذ البرنامج لنبدأ بالمرحلة الأخيرة وهي تجهيز صفحتي المحتوى ModalPage و ModelessPage. انتقل إلى الملف ModalPage.cs واحرص على أن تكون محتوياته مطابقة لما يلي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1468_18">
<span class="kwd">using</span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">ModelessAndModal</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">ModalPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">ModalPage</span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">Title</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Modal Page"</span><span class="pun">;</span><span class="pln">
            </span><span class="typ">Button</span><span class="pln"> goBackButton </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Back to Main"</span><span class="pun">,</span><span class="pln">
                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">Center</span><span class="pun">,</span><span class="pln">
                </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">Center</span><span class="pln">
            </span><span class="pun">};</span><span class="pln">

            goBackButton</span><span class="pun">.</span><span class="typ">Clicked</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> async </span><span class="pun">(</span><span class="pln">sender</span><span class="pun">,</span><span class="pln"> args</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                await </span><span class="typ">Navigation</span><span class="pun">.</span><span class="typ">PopModalAsync</span><span class="pun">();</span><span class="pln">
            </span><span class="pun">};</span><span class="pln">

            </span><span class="typ">Content</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> goBackButton</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	ثمّ انتقل إلى الملف ModelessPage.cs واحرص على أن تكون محتوياته كما يلي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1468_20">
<span class="kwd">using</span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">ModelessAndModal</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">ModelessPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">ModelessPage</span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">Title</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Modeless Page"</span><span class="pun">;</span><span class="pln">
            </span><span class="typ">Button</span><span class="pln"> goBackButton </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Back to Main"</span><span class="pun">,</span><span class="pln">
                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">Center</span><span class="pun">,</span><span class="pln">
                </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">Center</span><span class="pln">
            </span><span class="pun">};</span><span class="pln">

            goBackButton</span><span class="pun">.</span><span class="typ">Clicked</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> async </span><span class="pun">(</span><span class="pln">sender</span><span class="pun">,</span><span class="pln"> args</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
            </span><span class="pun">{</span><span class="pln">
                await </span><span class="typ">Navigation</span><span class="pun">.</span><span class="typ">PopAsync</span><span class="pun">();</span><span class="pln">
            </span><span class="pun">};</span><span class="pln">

            </span><span class="typ">Content</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> goBackButton</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	محتويات كلّ من الصفحتين السابقتين متطابقة. فكل منهما يحتوي على زر اسمه goBackButton هدفه العودة إلى الصفحة السابقة (التي سببت ظهور الصفحة الحالية). هناك فرق بسيط وحيد بين معالجي حدثي النقر للزرين في الصفحتين السابقتين. بالنسبة للصفحة من النمط الجامد modal تم استخدام الاستدعاء غير المتزامن Navigation.PopModalAsync للعودة إلى الصفحة السابقة. أمّا في حالة الصفحة ذات النمط غير الجامد modeless فقد تمّ استخدام الاستدعاء غير المتزامن Navigation.PopAsync للعودة إلى الصفحة السابقة. ثمة فرق آخر عند تنفيذ البرنامج، وهو أنّه في حالة الانتقال من الصفحة الرئيسية إلى الصفحة ModelessPage (الصفحة غير الجامدة) سيظهر عنوان الصفحة في الأعلى مع سهم صغير يسمح لنا بالعودة إلى الصفحة السابقة. أمّا عند الانتقال من الصفحة الرئيسية إلى الصفحة ModePage (الصفحة الجامدة) فلن يظهر عنوان الصفحة أبدًا (رغم تعيين الخاصيّة Title لها)، والوسيلة الوحيدة للرجوع إلى الصفحة السابقة هي بنقر زر الرجوع الموجود ضمن الصفحة أو بنقر زر العودة إلى الوراء الذي يزوّدنا به نظام التشغيل. أجرِ بعض التجارب على التطبيق ولاحظ الفرق بين الصفحتين.
</p>

<blockquote>
	<blockquote class="ipsQuote" data-ipsquote="">
		<div class="ipsQuote_citation">
			Quote
		</div>

		<div class="ipsQuote_contents ipsClearfix">
			<p>
				تُستَخدم الصفحات الجامدة عادةً عندما نريد من المستخدم أن يزوّد التطبيق بمعلومات أساسيّة قبل أن ينتقل إلى صفحة أخرى. في الحقيقة تستخدم أغلب تطبيقات أندرويد النمط غير الجامد modeless في عملها.
			</p>
		</div>
	</blockquote>

	<p>
		 
	</p>
</blockquote>

<h3>
	الخلاصة
</h3>

<p>
	تناولنا في هذا الدرس آلية التنقّل بين الصفحات في تطبيقات أندرويد، وهو موضوع مهمّ بالطبع. حيث تعرّفنا إلى الفرق بين الصفحات من النمط modal والنمط modeless. كما تعلّمنا كيفية إنشاء الصفحة الرئيسيّة التي تُعتبر حجر البناء الأساسي في عمليّة الانتقال بين الصفحات، وذلك من خلال إنشاء الصفحة الرئيسيّة لتكون من النوع NavigationPage.
</p>
]]></description><guid isPermaLink="false">450</guid><pubDate>Tue, 11 Apr 2017 07:57:15 +0000</pubDate></item><item><title>&#x645;&#x642;&#x62F;&#x651;&#x645;&#x629; &#x625;&#x644;&#x649; &#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x629; &#x63A;&#x64A;&#x631; &#x627;&#x644;&#x645;&#x62A;&#x632;&#x627;&#x645;&#x646;&#x629; &#x641;&#x64A; Xamarin</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D9%85%D9%82%D8%AF%D9%91%D9%85%D8%A9-%D8%A5%D9%84%D9%89-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D8%A9-%D8%BA%D9%8A%D8%B1-%D8%A7%D9%84%D9%85%D8%AA%D8%B2%D8%A7%D9%85%D9%86%D8%A9-%D9%81%D9%8A-xamarin-r448/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.9880ca757fb68dd3d1b7c09d20e8273b.png" /></p>

<p>
	سنتعرّف في هذا الدرس من ضمن سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms على تقنيّة متقدّمة بعض الشيء، وهي البرمجة غير المتزامنة Asynchronous Programming. وهي تقنيّة مهمّة تسمح للمبرمجين ببناء تطبيقات مرنة وذات استجابة عالية عند الاستخدام. سيتناول هذا الدرس الحاجة إلى البرمجة غير المتزامنة، ويقدّم تطبيق عملي بسيط يعمل على توضيح فكرة البرمجة غير المتزامنة من خلال تطبيق بسيط للغاية.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22417" data-unique="smihsbse5" src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.2ab7c91da48fab8ec77455706c115954.png"></p>

<h3>
	الحاجة إلى البرمجة غير المتزامنة
</h3>

<p>
	تسلك التطبيقات نفس السلوك في معالجة مُدخلات المستخدم التي قد تكون عبارة عن نقرة فأرة أو لمسة على الشاشة أو ضغط على مفتاح من لوحة المفاتيح. إذ يجب أن تُعالج هذه المدخلات بشكل متسلسل حسب ترتيب وقوعها. ولا يتم الانتقال من مُدخل إلى مُدخل آخر إلّا بعد الانتهاء من معالجة التعليمات البرمجيّة التي سبّبها المُدخل الحالي. فإذا فرضنا مثلًا وجود زرّين على الشاشة، فإذا نقرت (لمست) الزرّين بشكل متتال وبسرعة، فإنّ التعليمات الموجودة في معالج حدث النقر للزر الذي لُمسَ أولًا سيتم تنفيذها بالكامل، وبعد ذلك ينتقل البرنامج لتنفيذ مجموعة التعليمات البرمجيّة الموجودة في معالج حدث النقر للزر الثاني. بمعنى آخر، لن يتم تنفيذ التعليمات البرمجيّة للزرّين معًا، حتى وإن بدا للمستخدم أنّه قد نقرهما (لمسهما) معًا. وهذا أمر طبيعي تمامًا ويجري في جميع التطبيقات التي تعمل على أنظمة التشغيل المختلفة.
</p>

<p>
	السبب في هذا الأمر، هو أنّه وبشكل افتراضي يعمل التطبيق ضمن ما يُسمّى بمسار تنفيذ Thread رئيسي. يضمن مسار التنفيذ هذا أن يتم التنفيذ بالصورة التي أوضحناها قبل قليل. وفي الحقيقة يُسمّى مسار التنفيذ الرئيسي أحيانًا بمسار التنفيذ الخاص بواجهة المستخدم UI Thread وذلك لأنّ جميع العناصر المرئيّة يتم التعامل معها حصرًا من خلاله.
</p>

<p>
	تكمن المشكلة في أنّ بعض التطبيقات قد تحتاج إلى زمن طويل نسبيًا في تنفيذ التعليمات البرمجيّة الموجودة -ولنقل- في أحد معالجات الأحداث. فقد ينقر (يلمس) المستخدم زرًا يؤدّي مثلًا إلى جلب بعض البيانات من الإنترنت، وهي عمليّة قد تتطلّب في بعض الأحيان زمنًا طويلًا نسبيًّا وذلك لأسباب متنوّعة لسنا بمعرض الحديث عنها حاليًّا. سيعني هذا بكلّ تأكيد أنّ واجهة التطبيق ستبقى جامدة ولا تستجيب حتى تنجح عملية جلب البيانات أو تفشل لسبب ما. السيناريو السابق غير مرغوب بكل تأكيد، فلا بدّ من وجود طريقة ما تسمح بجلب البيانات دون التأثير على واجهة التطبيق الأساسيّة، أو بمعنى أدق، دون التأثير على مسار التنفيذ الرئيسي UI Thread.
</p>

<p>
	تُوفّر العديد من لغات البرمجة تقنيّة مهمّة لحل هذه المشكلة تتمثّل في استخدام مسارات تنفيذ أخرى (نسميها مسارات التنفيذ العاملة Worker Threads) يتم من خلالها تنفيذ المهام المتنوّعة التي يتطلّبها التطبيق والتي قد تستغرق زمنًا طويلًا نسبيًّا وذلك دون التأثير على مسار التنفيذ الرئيسي UI Thread. تُسمّى هذه التقنيّة بالبرمجة ذات مسارات التنفيذ المتعدّدة Multi-Threading Programming وهي من التقنيّات البرمجيّة المتقدّمة، وليس من السهل العمل معها.
</p>

<p>
	توفّر معظم لغات البرمجة بما فيها سي شارب حلول مبسّطة تُعفي المستخدم من مغبّة التورّط -إن صحّ التعبير- في موضوع متقدّم كهذا. الحل الذي تقدّمه سي شارب هو في البرمجة غير المتزامنة Asynchronous Programming حيث تعمل هذه التقنيّة على تنفيذ المهام البرمجيّة التي تتطلّب وقتًا طويلًا نسبيًّا ضمن ما يشبه مسارات تنفيذ منفصلة عن مسار التنفيذ الرئيسي، بحيث يمكن القول أنّ التعليمات البرمجيّة الموجودة ضمن معالجات أحداث مختلفة يصبح من الممكن تنفيذها بشكل متوازٍ بدلًا من الشكل المتسلسل الذي تحدثنا عنه. انظر إلى الشكل التالي الذي يوضّح الفرق العام بين التطبيقات التي تستخدم مسار التنفيذ الرئيسي فقط، وبين التطبيقات التي تستخدم مسارات تنفيذ متعدّدة.
</p>

<p style="text-align: center;">
	<img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22415" data-unique="nf6exnld3" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.png.d3e464f5bdc3fe4e31351e5f944f2bc6.png"></p>

<blockquote class="ipsQuote" data-ipsquote="">
	<div class="ipsQuote_citation">
		Quote
	</div>

	<div class="ipsQuote_contents ipsClearfix">
		<p>
			في الحقيقة هناك فرق تقني بين برمجة مسارات التنفيذ المتعدّدة وبين البرمجة غير المتزامنة. إذ أنّ عمليّة إنشاء مسارات التنفيذ المنفصلة تتم بشكل مختلف بينهما.
		</p>
	</div>
</blockquote>

<h3>
	تطبيق العدّاد المحسّن مع استدعاء غير متزامن
</h3>

<p>
	تذكر معي تطبيق العدّاد المحسّن الذي تناولناه في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%AC%D8%A7%D8%A8%D8%A9-%D9%84%D8%A3%D8%AD%D8%AF%D8%A7%D8%AB-%D8%A7%D9%84%D9%86%D9%82%D8%B1-%D9%81%D9%8A-xamarin-r415/" rel="">هذا الدرس</a>. سنجري تعديلًا عليه بحيث سنعمل على إضافة زر جديد لإجراء استدعاء غير متزامن يعمل على محاكاة عمليّة برمجيّة تستغرق 5 ثانية، بالإضافة إلى لصيقة تقع أسفل الزر السابق لعرض رسالة بعد الانتهاء من عمليّة الاستدعاء غير المتزامن. أثناء تنفيذ هذه العمليّة البرمجيّة سنضغط على زرّي الزيادة والإنقاص، وسيتابع التطبيق العمل بشكل طبيعي دون حدوث أيّ جمود على واجهة المستخدم. بعد انقضاء العمليّة الناتجة عن الاستدعاء غير المتزامن بعد 5 ثانية، سيعرض التطبيق رسالة "Hello From Async." ضمن لصيقة تقع أسفل الزر للإشارة إلى انتهاء هذه العمليّة. انظر الشكل التالي لمعاينة الشكل الجديد لذلك التطبيق:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22416" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.png.f6815b82cc37cb10e38e4c139f15e155.png" rel=""><img alt="fig02.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22416" data-unique="w8xvu3d8b" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.thumb.png.0c34bef70b01e5dcc18b18a344befaf7.png"></a>
</p>

<p>
	أنشئ مشروعًا جديدًا من النوع Blank App (Xamarin.Forms Portable) وسمّه AsyncCounterApp، ثم أبق فقط على المشروعين AsyncCounterApp (Portable) و AsyncCounterApp.Droid كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-visual-studio-2015-community-%D9%88%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-xamarin-%D9%84%D9%84%D8%B9%D9%85%D9%84-r373/" rel="">هذا الدرس</a>. بعد ذلك أضف صفحة محتوى وسمّها AsyncEnhancedCounterPage. احرص على أن تكون محتويات هذه الصفحة على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1846_14">
<span class="lit">1</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">;</span><span class="pln">
</span><span class="lit">2</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Threading</span><span class="pun">.</span><span class="typ">Tasks</span><span class="pun">;</span><span class="pln">
</span><span class="lit">3</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">
</span><span class="lit">4</span><span class="pln">	
</span><span class="lit">5</span><span class="pln">	</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">AsyncCounterApp</span><span class="pln">
</span><span class="lit">6</span><span class="pln">	</span><span class="pun">{</span><span class="pln">
</span><span class="lit">7</span><span class="pln">	    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">AsyncEnhancedCounterPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
</span><span class="lit">8</span><span class="pln">	    </span><span class="pun">{</span><span class="pln">
</span><span class="lit">9</span><span class="pln">	        </span><span class="typ">Label</span><span class="pln"> lblDisplayAsync</span><span class="pun">;</span><span class="pln">
</span><span class="lit">10</span><span class="pln">	
</span><span class="lit">11</span><span class="pln">	        </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">AsyncEnhancedCounterPage</span><span class="pun">()</span><span class="pln">
</span><span class="lit">12</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">13</span><span class="pln">	            </span><span class="typ">int</span><span class="pln"> counter </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
</span><span class="lit">14</span><span class="pln">	
</span><span class="lit">15</span><span class="pln">	            </span><span class="typ">Label</span><span class="pln"> lblDisplay </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Label</span><span class="pln">
</span><span class="lit">16</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">17</span><span class="pln">	                </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"0"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">18</span><span class="pln">	                </span><span class="typ">TextColor</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Color</span><span class="pun">.</span><span class="typ">Accent</span><span class="pun">,</span><span class="pln">
</span><span class="lit">19</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">CenterAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">20</span><span class="pln">	                </span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Device</span><span class="pun">.</span><span class="typ">GetNamedSize</span><span class="pun">(</span><span class="typ">NamedSize</span><span class="pun">.</span><span class="typ">Large</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">typeof</span><span class="pun">(</span><span class="typ">Label</span><span class="pun">))</span><span class="pln">
</span><span class="lit">21</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">22</span><span class="pln">	
</span><span class="lit">23</span><span class="pln">	            </span><span class="typ">Button</span><span class="pln"> btnIncrement </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">
</span><span class="lit">24</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">25</span><span class="pln">	                </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"+"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">26</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">CenterAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">27</span><span class="pln">	                </span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Device</span><span class="pun">.</span><span class="typ">GetNamedSize</span><span class="pun">(</span><span class="typ">NamedSize</span><span class="pun">.</span><span class="typ">Large</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">typeof</span><span class="pun">(</span><span class="typ">Label</span><span class="pun">))</span><span class="pln">
</span><span class="lit">28</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">29</span><span class="pln">	            btnIncrement</span><span class="pun">.</span><span class="typ">Clicked</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">s</span><span class="pun">,</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
</span><span class="lit">30</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">31</span><span class="pln">	                counter</span><span class="pun">++;</span><span class="pln">
</span><span class="lit">32</span><span class="pln">	                lblDisplay</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> counter</span><span class="pun">.</span><span class="typ">ToString</span><span class="pun">();</span><span class="pln">
</span><span class="lit">33</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">34</span><span class="pln">	
</span><span class="lit">35</span><span class="pln">	            </span><span class="typ">Button</span><span class="pln"> btnDecrement </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">
</span><span class="lit">36</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">37</span><span class="pln">	                </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"-"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">38</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">CenterAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">39</span><span class="pln">	                </span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Device</span><span class="pun">.</span><span class="typ">GetNamedSize</span><span class="pun">(</span><span class="typ">NamedSize</span><span class="pun">.</span><span class="typ">Large</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">typeof</span><span class="pun">(</span><span class="typ">Label</span><span class="pun">))</span><span class="pln">
</span><span class="lit">40</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">41</span><span class="pln">	            btnDecrement</span><span class="pun">.</span><span class="typ">Clicked</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">s</span><span class="pun">,</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
</span><span class="lit">42</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">43</span><span class="pln">	                </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">counter </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln">
</span><span class="lit">44</span><span class="pln">	                </span><span class="pun">{</span><span class="pln">
</span><span class="lit">45</span><span class="pln">	                    </span><span class="typ">DisplayAlert</span><span class="pun">(</span><span class="str">"تحذير"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"لا يمكن لقيمة العدّاد أن تكون أصغر من الصفر"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"موافق"</span><span class="pun">);</span><span class="pln">
</span><span class="lit">46</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">47</span><span class="pln">	                </span><span class="kwd">else</span><span class="pln">
</span><span class="lit">48</span><span class="pln">	                </span><span class="pun">{</span><span class="pln">
</span><span class="lit">49</span><span class="pln">	                    counter</span><span class="pun">--;</span><span class="pln">
</span><span class="lit">50</span><span class="pln">	                    lblDisplay</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> counter</span><span class="pun">.</span><span class="typ">ToString</span><span class="pun">();</span><span class="pln">
</span><span class="lit">51</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">52</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">53</span><span class="pln">	
</span><span class="lit">54</span><span class="pln">	            </span><span class="typ">Button</span><span class="pln"> btnAsyncCall </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">
</span><span class="lit">55</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">56</span><span class="pln">	                </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Async Call"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">57</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">CenterAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">58</span><span class="pln">	                </span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Device</span><span class="pun">.</span><span class="typ">GetNamedSize</span><span class="pun">(</span><span class="typ">NamedSize</span><span class="pun">.</span><span class="typ">Large</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">typeof</span><span class="pun">(</span><span class="typ">Label</span><span class="pun">))</span><span class="pln">
</span><span class="lit">59</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">60</span><span class="pln">	            btnAsyncCall</span><span class="pun">.</span><span class="typ">Clicked</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> </span><span class="typ">BtnAsyncCall_Clicked</span><span class="pun">;</span><span class="pln"> </span><span class="pun">;</span><span class="pln">
</span><span class="lit">61</span><span class="pln">	
</span><span class="lit">62</span><span class="pln">	            lblDisplayAsync </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Label</span><span class="pln">
</span><span class="lit">63</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">64</span><span class="pln">	                </span><span class="typ">TextColor</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Color</span><span class="pun">.</span><span class="typ">Green</span><span class="pun">,</span><span class="pln">
</span><span class="lit">65</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">CenterAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">66</span><span class="pln">	                </span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Device</span><span class="pun">.</span><span class="typ">GetNamedSize</span><span class="pun">(</span><span class="typ">NamedSize</span><span class="pun">.</span><span class="typ">Large</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">typeof</span><span class="pun">(</span><span class="typ">Label</span><span class="pun">))</span><span class="pln">
</span><span class="lit">67</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">68</span><span class="pln">	
</span><span class="lit">69</span><span class="pln">	            </span><span class="typ">Content</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StackLayout</span><span class="pln">
</span><span class="lit">70</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">71</span><span class="pln">	                </span><span class="typ">Children</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="lit">72</span><span class="pln">	                    </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StackLayout</span><span class="pln">
</span><span class="lit">73</span><span class="pln">	                    </span><span class="pun">{</span><span class="pln">
</span><span class="lit">74</span><span class="pln">	                        </span><span class="typ">Orientation</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">StackOrientation</span><span class="pun">.</span><span class="typ">Horizontal</span><span class="pun">,</span><span class="pln">
</span><span class="lit">75</span><span class="pln">	                        </span><span class="typ">Padding</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Thickness</span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="lit">64</span><span class="pun">,</span><span class="lit">0</span><span class="pun">,</span><span class="lit">64</span><span class="pun">),</span><span class="pln">
</span><span class="lit">76</span><span class="pln">	                        </span><span class="typ">Children</span><span class="pln"> </span><span class="pun">=</span><span class="pln">
</span><span class="lit">77</span><span class="pln">	                        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">78</span><span class="pln">	                            btnIncrement</span><span class="pun">,</span><span class="pln">
</span><span class="lit">79</span><span class="pln">	                            btnDecrement
</span><span class="lit">80</span><span class="pln">	                        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">81</span><span class="pln">	                    </span><span class="pun">},</span><span class="pln">
</span><span class="lit">82</span><span class="pln">	                    lblDisplay</span><span class="pun">,</span><span class="pln">
</span><span class="lit">83</span><span class="pln">	                    btnAsyncCall</span><span class="pun">,</span><span class="pln">
</span><span class="lit">84</span><span class="pln">	                    lblDisplayAsync
</span><span class="lit">85</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">86</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">87</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">88</span><span class="pln">	
</span><span class="lit">89</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> async </span><span class="kwd">void</span><span class="pln"> </span><span class="typ">BtnAsyncCall_Clicked</span><span class="pun">(</span><span class="pln">object sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">EventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
</span><span class="lit">90</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">91</span><span class="pln">	            </span><span class="com">//simulate long process execution for 5 seconds</span><span class="pln">
</span><span class="lit">92</span><span class="pln">	            string msg </span><span class="pun">=</span><span class="pln"> await </span><span class="typ">Task</span><span class="str">&lt;string&gt;</span><span class="pun">.</span><span class="typ">Run</span><span class="pun">(()</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
</span><span class="lit">93</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">94</span><span class="pln">	                </span><span class="typ">DateTime</span><span class="pln"> d </span><span class="pun">=</span><span class="pln"> </span><span class="typ">DateTime</span><span class="pun">.</span><span class="typ">Now</span><span class="pun">;</span><span class="pln">
</span><span class="lit">95</span><span class="pln">	
</span><span class="lit">96</span><span class="pln">	                </span><span class="kwd">while</span><span class="pln"> </span><span class="pun">(</span><span class="typ">DateTime</span><span class="pun">.</span><span class="typ">Now</span><span class="pun">.</span><span class="typ">Second</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> d</span><span class="pun">.</span><span class="typ">Second</span><span class="pln"> </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">5</span><span class="pun">)</span><span class="pln"> </span><span class="pun">;</span><span class="pln">
</span><span class="lit">97</span><span class="pln">	
</span><span class="lit">98</span><span class="pln">	                </span><span class="kwd">return</span><span class="pln"> </span><span class="str">"Hello from Async."</span><span class="pun">;</span><span class="pln">
</span><span class="lit">99</span><span class="pln">	            </span><span class="pun">});</span><span class="pln">
</span><span class="lit">100</span><span class="pln">	
</span><span class="lit">101</span><span class="pln">	            lblDisplayAsync</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> msg</span><span class="pun">;</span><span class="pln">
</span><span class="lit">102</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">103</span><span class="pln">	    </span><span class="pun">}</span><span class="pln">
</span><span class="lit">104</span><span class="pln">	</span><span class="pun">}</span></pre>

<p>
	لقد تناولنا الشيفرة السابقة من قبل. لذلك سنتحدّث عن عمليّة الاستدعاء غير المتزامن فحسب. لقد أسندنا لحدث نقر الزر btnAsyncCall معالج حدث BtnAsyncCall_Clicked وهو موجود في الأسطر من 89 حتى 102. الجديد في معالج الحدث هذا هو وجود الكلمة المحجوزة async (السطر 89) قبل نوع القيمة المعادة مباشرةً. تُشير هذه الكلمة المحجوزة إلى أنّ عملية الاستدعاء غير المتزامن ستجري ضمن التابع  BtnAsyncCall_Clicked.
</p>

<p>
	انظر الآن إلى الأسطر من 92 إلى 99:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1846_8">
<span class="pln">string msg </span><span class="pun">=</span><span class="pln"> await </span><span class="typ">Task</span><span class="str">&lt;string&gt;</span><span class="pun">.</span><span class="typ">Run</span><span class="pun">(()</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">

</span><span class="pun">{</span><span class="pln">

    </span><span class="typ">DateTime</span><span class="pln"> d </span><span class="pun">=</span><span class="pln"> </span><span class="typ">DateTime</span><span class="pun">.</span><span class="typ">Now</span><span class="pun">;</span><span class="pln">



    </span><span class="kwd">while</span><span class="pln"> </span><span class="pun">(</span><span class="typ">DateTime</span><span class="pun">.</span><span class="typ">Now</span><span class="pun">.</span><span class="typ">Second</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> d</span><span class="pun">.</span><span class="typ">Second</span><span class="pln"> </span><span class="pun">&lt;</span><span class="pln"> </span><span class="lit">5</span><span class="pun">)</span><span class="pln"> </span><span class="pun">;</span><span class="pln">



    </span><span class="kwd">return</span><span class="pln"> </span><span class="str">"Hello from Async."</span><span class="pun">;</span><span class="pln">

</span><span class="pun">});</span></pre>

<p>
	لاحظ التابع الساكن Run من الصنف العمومي Task&lt;string&gt;. يعمل هذا التابع على استدعاء أيّ تابع مُمرّر إليه ضمن مسار تنفيذ منفصل عن مسار التنفيذ الأساسي، وبالتالي لا يُشغل مسار التنفيذ الأساسي المرتبط بواجهة المستخدم.
</p>

<p>
	يجب أن يُسبق الاستدعاء غير المتزامن بالكلمة المحجوزة await. لقد مرّرنا إلى التابع Run تعبير Lambda يحتوي التعليمات البرمجيّة التي نريد تنفيذها على مسار تنفيذ مستقل (للمزيد حول تعابير Lambda <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D8%AF%D8%AE%D9%84-%D8%A5%D9%84%D9%89-%D8%AA%D8%B9%D8%A7%D8%A8%D9%8A%D8%B1-lambda-%D9%88%D8%A7%D8%B3%D8%AA%D8%B9%D9%84%D8%A7%D9%85%D8%A7%D8%AA-linq-%D9%81%D9%8A-%D9%84%D8%BA%D8%A9-%D8%B3%D9%8A-%D8%B4%D8%A7%D8%B1%D8%A8-c-r381/" rel="">انظر هنا</a>). من الواضح أنّنا قد كتبنا شيفرة برمجيّة لا تقوم بعمل مفيد بكل تأكيد، إنما الغاية الوحيدة منها هي توضيح فكرة الاستدعاء غير المتزامن، حيث أجريت تأخيرًا زمنيًّا باستخدام حلقة while يستغرق 5 ثواني.
</p>

<p>
	سنكتفي بهذه المقدّمة حول البرمجة غير المتزامنة، مع التأكيد على أنّنا سنتوسّع في هذا الموضوع حينما نتناول تطبيقًا عمليًّا مفيدًا لاحقًا في هذه السلسلة.
</p>

<h3>
	الخلاصة
</h3>

<p>
	تحدثنا في هذا الدرس عن مفهوم البرمجة غير المتزامنة Asynchronous Programming والحاجة إليها في التطبيقات التي نصمّمها لضمان أنّ العمليات البرمجيّة التي قد تستغرق وقتًا طويلًا نسبيًّا لن تؤدّي إلى جمود في واجهة المستخدم. ثمّ أجرينا تعديلًا بسيطًا على تطبيق بنيناه في درس سابق بحيث نجري استدعاءً غير متزامنًا يستغرق وقتًا لا بأس به حتى ينتهي، ورغم ذلك استطاع المستخدم متابعة العمل على التطبيق دون أيّ تأثير على واجهة التطبيق. لن نكتفي بكلّ تأكيد بما وصلنا إليه هنا، سنتوسّع بالحديث عن هذا الموضوع المهم لاحقًا حينما نبدأ بتنفيذ تطبيقات عمليّة باستخدام Xamarin.
</p>
]]></description><guid isPermaLink="false">448</guid><pubDate>Mon, 03 Apr 2017 15:31:54 +0000</pubDate></item><item><title>&#x62A;&#x62D;&#x631;&#x64A;&#x643; &#x639;&#x646;&#x627;&#x635;&#x631; &#x627;&#x644;&#x648;&#x627;&#x62C;&#x647;&#x629; &#x627;&#x644;&#x628;&#x631;&#x645;&#x62C;&#x64A;&#x629; &#x648;&#x627;&#x644;&#x62A;&#x651;&#x62D;&#x643;&#x645; &#x641;&#x64A;&#x647;&#x627; &#x641;&#x64A; Xamarin</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%AA%D8%AD%D8%B1%D9%8A%D9%83-%D8%B9%D9%86%D8%A7%D8%B5%D8%B1-%D8%A7%D9%84%D9%88%D8%A7%D8%AC%D9%87%D8%A9-%D8%A7%D9%84%D8%A8%D8%B1%D9%85%D8%AC%D9%8A%D8%A9-%D9%88%D8%A7%D9%84%D8%AA%D9%91%D8%AD%D9%83%D9%85-%D9%81%D9%8A%D9%87%D8%A7-%D9%81%D9%8A-xamarin-r463/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.e98327dc29a2b67b29a047a60b8d5bf9.png" /></p>

<p>
	تحدثنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D9%85%D8%AE%D8%B7%D9%91%D8%B7-%D8%A7%D9%84%D9%85%D8%B7%D9%84%D9%82-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%B1%D9%85%D8%A7%D8%B2-xaml-%D9%81%D9%8A-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-r462/" rel="">الدرس السابق</a> عن المخطّط المطلق Absolute Layout وعن فائدته في التحكّم بمواضع وأحجام العناصر المرئيّة باستخدام الواحدات المستقلة عن الجهاز independent-device units. سنتابع عملنا في هذا الدرس ضمن <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/" rel="">سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms</a> ببناء تطبيق عمليّ جميل يُعتبر تحسينًا لتطبيق تحريك المربّعات الثلاثة المتداخلة الذي أوردناه في نهاية <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D9%85%D8%AE%D8%B7%D9%91%D8%B7-%D8%A7%D9%84%D9%85%D8%B7%D9%84%D9%82-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%B1%D9%85%D8%A7%D8%B2-xaml-%D9%81%D9%8A-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-r462/" rel="">الدرس السابق</a>. يوضّح لنا هذا التطبيق المُحسّن كيفيّة التحكّم بهذه المربّعات باستخدام أزرار تمثّل الاتجاهات الأربعة الأساسيّة (أعلى – أسفل - يمين – يسار).
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22581" data-unique="8qhka2zor" src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.7740230325ae454b7a5e52dc2c8ef914.png"></p>

<h3>
	وصف التطبيق
</h3>

<p>
	واجهة هذا التطبيق بسيطة. فبالإضافة إلى المربّعات الثلاثة. سنضع أربعة أزرار عاديّة تمثّل الاتجاهات الأربعة الأساسيّة. بحيث تتوضّع هذه المربّعات أسفل ووسط الشاشة. عند بدء تشغيل التطبيق سنحصل على شكل شبيه بما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22580" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.png.b343bf00c3a5ae3b27c76911c7be0326.png" rel=""><img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22580" data-unique="eaq17lhu9" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.thumb.png.d8b4067d38b29499a5c6c08e9c1bb49e.png"></a>
</p>

<p>
	لاحظ كيف تتوسّط الأزرار الأربعة الشاشة أفقيًّا، سنوضّح سبب ذلك بعد قليل. إذا حاول المستخدم في الوضع الحالي نقر أي زر من الأزرار الأربعة السابقة سيعرض له البرنامج رسالة يطلب منه فيها اختيار أحد المربّعات أولًا لتحريكه. عندما ينقر المستخدم على أحد المربّعات السابقة، ستتلوّن الأزرار الأربعة بنفس لون المربّع الذي نقره المستخدم. وعندها فقط يمكن استخدام الأزرار لتحريك المربّع المُختار في أيّ اتجاه يرغبه. في الشكل التالي قمت باختيار المربّع الأحمر، ومن ثمّ تحريكه إلى الأعلى ثم إلى اليمين:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22579" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.png.85f27bc664af25bdc8d5f4b21a38e074.png" rel=""><img alt="fig02.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22579" data-unique="i2w0qdsl6" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.thumb.png.5e5c2bd1355b4d0d9df68c801f3f14bf.png"></a>
</p>

<p>
	يمكنك تكرار نفس الخطوات السابقة لتحريك أيّ مربّع آخر. هذا هو مبدأ هذا البرنامج، وهو بسيط كما ترى، ولكن سنتعلّم من خلاله بعض التقنيّات المفيدة في ضبط التموضع ضمن المخطّط المطلق، بالإضافة إلى تعلّم كيفيّة إكساب عناصر BoxView قابلية الاستجابة إلى أحداث اللمس كما سنرى بعد قليل.
</p>

<h3>
	تطبيق تحريك المربّعات باستخدام الأزرار
</h3>

<p>
	أنشئ مشروعًا جديدًا من النوع Blank App (Xamarin.Forms Portable) وسمّه MoveSquaresByButtons، ثم أبق فقط على المشروعين MoveSquaresByButtons (Portable) و MoveSquaresByButtons.Droid كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-visual-studio-2015-community-%D9%88%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-xamarin-%D9%84%D9%84%D8%B9%D9%85%D9%84-r373/" rel="">هذا الدرس</a>. بعد ذلك سنضيف صفحة محتوى تعتمد على رُماز XAML كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xaml-r453/" rel="">هذا الدرس</a> سنسمّيها MoveSquaresByButtonsPage. احرص على أن تكون محتويات هذه الصفحة على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6699_7">
<span class="lit">1</span><span class="pln">	</span><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
</span><span class="lit">2</span><span class="pln">	</span><span class="pun">&lt;</span><span class="typ">ContentPage</span><span class="pln"> xmlns</span><span class="pun">=</span><span class="str">"http://xamarin.com/schemas/2014/forms"</span><span class="pln">
</span><span class="lit">3</span><span class="pln">	             xmlns</span><span class="pun">:</span><span class="pln">x</span><span class="pun">=</span><span class="str">"http://schemas.microsoft.com/winfx/2009/xaml"</span><span class="pln">
</span><span class="lit">4</span><span class="pln">	             x</span><span class="pun">:</span><span class="typ">Class</span><span class="pun">=</span><span class="str">"MoveSquaresByButtons.MoveSquaresByButtonsPage"</span><span class="pln">
</span><span class="lit">5</span><span class="pln">	             </span><span class="typ">SizeChanged</span><span class="pun">=</span><span class="str">"PageResize"</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">6</span><span class="pln">	
</span><span class="lit">7</span><span class="pln">	  </span><span class="pun">&lt;</span><span class="typ">AbsoluteLayout</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">8</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">BoxView</span><span class="pln">  x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"boxAccent"</span><span class="pln">
</span><span class="lit">9</span><span class="pln">	              </span><span class="typ">Color</span><span class="pun">=</span><span class="str">"Accent"</span><span class="pln">
</span><span class="lit">10</span><span class="pln">	              </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">LayoutBounds</span><span class="pun">=</span><span class="str">"25, 100, 100, 100"</span><span class="pln">
</span><span class="lit">11</span><span class="pln">	              </span><span class="typ">Opacity</span><span class="pun">=</span><span class="str">"0.5"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">12</span><span class="pln">	
</span><span class="lit">13</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">BoxView</span><span class="pln">  x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"boxRed"</span><span class="pln">
</span><span class="lit">14</span><span class="pln">	              </span><span class="typ">Color</span><span class="pun">=</span><span class="str">"Red"</span><span class="pln">
</span><span class="lit">15</span><span class="pln">	              </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">LayoutBounds</span><span class="pun">=</span><span class="str">"75, 150, 100, 100"</span><span class="pln">
</span><span class="lit">16</span><span class="pln">	              </span><span class="typ">Opacity</span><span class="pun">=</span><span class="str">"0.5"</span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">17</span><span class="pln">	
</span><span class="lit">18</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">BoxView</span><span class="pln">  x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"boxGreen"</span><span class="pln">
</span><span class="lit">19</span><span class="pln">	              </span><span class="typ">Color</span><span class="pun">=</span><span class="str">"Green"</span><span class="pln">
</span><span class="lit">20</span><span class="pln">	              </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">LayoutBounds</span><span class="pun">=</span><span class="str">"125, 200, 100, 100"</span><span class="pln">
</span><span class="lit">21</span><span class="pln">	              </span><span class="typ">Opacity</span><span class="pun">=</span><span class="str">"0.5"</span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">22</span><span class="pln">	
</span><span class="lit">23</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"btnMoveUp"</span><span class="pln">
</span><span class="lit">24</span><span class="pln">	           </span><span class="typ">StyleId</span><span class="pun">=</span><span class="str">"MoveBoxUp"</span><span class="pln">
</span><span class="lit">25</span><span class="pln">	           </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"MoveBox_Clicked"</span><span class="pln">
</span><span class="lit">26</span><span class="pln">	           </span><span class="typ">FontSize</span><span class="pun">=</span><span class="str">"Large"</span><span class="pln">
</span><span class="lit">27</span><span class="pln">	           </span><span class="typ">BorderWidth</span><span class="pun">=</span><span class="str">"0"</span><span class="pln">
</span><span class="lit">28</span><span class="pln">	           </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"↑"</span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">29</span><span class="pln">	
</span><span class="lit">30</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"btnMoveDown"</span><span class="pln">
</span><span class="lit">31</span><span class="pln">	            </span><span class="typ">StyleId</span><span class="pun">=</span><span class="str">"MoveBoxDown"</span><span class="pln">
</span><span class="lit">32</span><span class="pln">	            </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"MoveBox_Clicked"</span><span class="pln">
</span><span class="lit">33</span><span class="pln">	            </span><span class="typ">FontSize</span><span class="pun">=</span><span class="str">"Large"</span><span class="pln">
</span><span class="lit">34</span><span class="pln">	            </span><span class="typ">BorderWidth</span><span class="pun">=</span><span class="str">"0"</span><span class="pln">
</span><span class="lit">35</span><span class="pln">	            </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"↓"</span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">36</span><span class="pln">	
</span><span class="lit">37</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"btnMoveRight"</span><span class="pln">
</span><span class="lit">38</span><span class="pln">	            </span><span class="typ">StyleId</span><span class="pun">=</span><span class="str">"MoveBoxRight"</span><span class="pln">
</span><span class="lit">39</span><span class="pln">	            </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"MoveBox_Clicked"</span><span class="pln">
</span><span class="lit">40</span><span class="pln">	            </span><span class="typ">FontSize</span><span class="pun">=</span><span class="str">"Large"</span><span class="pln">
</span><span class="lit">41</span><span class="pln">	            </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"→"</span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">42</span><span class="pln">	
</span><span class="lit">43</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"btnMoveLeft"</span><span class="pln">
</span><span class="lit">44</span><span class="pln">	            </span><span class="typ">StyleId</span><span class="pun">=</span><span class="str">"MoveBoxLeft"</span><span class="pln">
</span><span class="lit">45</span><span class="pln">	            </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"MoveBox_Clicked"</span><span class="pln">
</span><span class="lit">46</span><span class="pln">	            </span><span class="typ">FontSize</span><span class="pun">=</span><span class="str">"Large"</span><span class="pln">
</span><span class="lit">47</span><span class="pln">	            </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"←"</span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">48</span><span class="pln">	  </span><span class="pun">&lt;/</span><span class="typ">AbsoluteLayout</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">49</span><span class="pln">	  
</span><span class="lit">50</span><span class="pln">	</span><span class="pun">&lt;/</span><span class="typ">ContentPage</span><span class="pun">&gt;</span></pre>

<p>
	لاحظ معي أنّ عناصر BoxView الموجودة في الأسطر من 8 حتى 21 هي نفسها الموجودة في تطبيق المربّعات المتداخلة من الدرس السابق. الجديد هنا هو تعيين معالج للحدث SizeChanged للصفحة (السطر 5) الذي يُستدعى كلّما اقتضت الحاجة إلى تغيير حجم الصفحة، وهو يحدث عادةً عند البدء بتشغيل التطبيق، وأيضًا عندما يُغيّر المستخدم اتجاه الجهاز من عمودي إلى أفقي أو بالعكس. الجديد هنا أيضًا هو الأزرار الأربعة الموجودة في الأسطر من 23 حتى 47. من الواضح أنّ جميع العناصر المرئيّة السابقة موجودة ضمن مخطّط مطلق AbsoluteLayout يضمن لنا التحكّم بمواقعها وبأحجامها كما أشرنا.
</p>

<p>
	تأمّل معي هذا الرماز الذي يمثّل زر الحركة نحو الأعلى:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6699_11">
<span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"btnMoveUp"</span><span class="pln">
        </span><span class="typ">StyleId</span><span class="pun">=</span><span class="str">"MoveBoxUp"</span><span class="pln">
        </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"MoveBox_Clicked"</span><span class="pln">
        </span><span class="typ">FontSize</span><span class="pun">=</span><span class="str">"Large"</span><span class="pln">
        </span><span class="typ">BorderWidth</span><span class="pun">=</span><span class="str">"0"</span><span class="pln">
        </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"&amp;#8593;"</span><span class="pun">/&gt;</span></pre>

<p>
	لقد وضعت القيمة "MoveBoxUp" للخاصيّة StyleId حيث سنستفيد منها ضمن معالج الحدث MoveBox_Clicked الذي أسندته للحدث Clicked كما هو واضح. سنرى بعد قليل الشيفرة البرمجيّة الخاصّة بهذا المعالج. الأمر الملفت هنا هو القيمة "&amp;H8593;" التي ضبطُّها لخاصيّة النص. سيؤدي ذلك إلى وضع رمز السهم المتجه إلى أعلى ليظهر على هذا الزر. بنفس هذا الأسلوب تمّ تجهيز الأزرار الثلاثة الباقية التي سأسند إلى كلّ منها قيمة مختلفة للخاصيّة StyleId لتعبّر عن وظيفتها، ولكن مع إسناد نفس معالج الحدث MoveBox_Clicked لجميعها. لننتقل الآن إلى ملف الشيفرة البرمجية الموافق لصفحة المحتوى السابقة. احرص على أن تكون محتوياته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6699_13">
<span class="lit">1</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">;</span><span class="pln">
</span><span class="lit">2</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">
</span><span class="lit">3</span><span class="pln">	
</span><span class="lit">4</span><span class="pln">	</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">MoveSquaresByButtons</span><span class="pln">
</span><span class="lit">5</span><span class="pln">	</span><span class="pun">{</span><span class="pln">
</span><span class="lit">6</span><span class="pln">	    </span><span class="kwd">public</span><span class="pln"> partial </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">MoveSquaresByButtonsPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
</span><span class="lit">7</span><span class="pln">	    </span><span class="pun">{</span><span class="pln">
</span><span class="lit">8</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> </span><span class="typ">BoxView</span><span class="pln"> selectedBoxView</span><span class="pun">;</span><span class="pln">
</span><span class="lit">9</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">double</span><span class="pln"> BUTTON_MARGIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">5</span><span class="pun">;</span><span class="pln">
</span><span class="lit">10</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">double</span><span class="pln"> PAGE_BUTTOM_MARGIN </span><span class="pun">=</span><span class="pln"> </span><span class="lit">10</span><span class="pun">;</span><span class="pln">
</span><span class="lit">11</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">const</span><span class="pln"> </span><span class="kwd">double</span><span class="pln"> MOVE_AMOUNT </span><span class="pun">=</span><span class="pln"> </span><span class="lit">15</span><span class="pun">;</span><span class="pln">
</span><span class="lit">12</span><span class="pln">	
</span><span class="lit">13</span><span class="pln">	        </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">MoveSquaresByButtonsPage</span><span class="pun">()</span><span class="pln">
</span><span class="lit">14</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">15</span><span class="pln">	            </span><span class="typ">InitializeComponent</span><span class="pun">();</span><span class="pln">
</span><span class="lit">16</span><span class="pln">	
</span><span class="lit">17</span><span class="pln">	            </span><span class="typ">TapGestureRecognizer</span><span class="pln"> tapGesture </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">TapGestureRecognizer</span><span class="pun">();</span><span class="pln">
</span><span class="lit">18</span><span class="pln">	
</span><span class="lit">19</span><span class="pln">	            tapGesture</span><span class="pun">.</span><span class="typ">Tapped</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> </span><span class="typ">TapGesture_Tapped</span><span class="pun">;</span><span class="pln">
</span><span class="lit">20</span><span class="pln">	
</span><span class="lit">21</span><span class="pln">	            boxAccent</span><span class="pun">.</span><span class="typ">GestureRecognizers</span><span class="pun">.</span><span class="typ">Add</span><span class="pun">(</span><span class="pln">tapGesture</span><span class="pun">);</span><span class="pln">
</span><span class="lit">22</span><span class="pln">	            boxRed</span><span class="pun">.</span><span class="typ">GestureRecognizers</span><span class="pun">.</span><span class="typ">Add</span><span class="pun">(</span><span class="pln">tapGesture</span><span class="pun">);</span><span class="pln">
</span><span class="lit">23</span><span class="pln">	            boxGreen</span><span class="pun">.</span><span class="typ">GestureRecognizers</span><span class="pun">.</span><span class="typ">Add</span><span class="pun">(</span><span class="pln">tapGesture</span><span class="pun">);</span><span class="pln">
</span><span class="lit">24</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">25</span><span class="pln">	
</span><span class="lit">26</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> </span><span class="typ">TapGesture_Tapped</span><span class="pun">(</span><span class="pln">object sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">EventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
</span><span class="lit">27</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">28</span><span class="pln">	            selectedBoxView </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">BoxView</span><span class="pun">)</span><span class="pln">sender</span><span class="pun">;</span><span class="pln">
</span><span class="lit">29</span><span class="pln">	
</span><span class="lit">30</span><span class="pln">	            btnMoveUp</span><span class="pun">.</span><span class="typ">BackgroundColor</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> selectedBoxView</span><span class="pun">.</span><span class="typ">Color</span><span class="pun">;</span><span class="pln">
</span><span class="lit">31</span><span class="pln">	            btnMoveDown</span><span class="pun">.</span><span class="typ">BackgroundColor</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> selectedBoxView</span><span class="pun">.</span><span class="typ">Color</span><span class="pun">;</span><span class="pln">
</span><span class="lit">32</span><span class="pln">	            btnMoveLeft</span><span class="pun">.</span><span class="typ">BackgroundColor</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> selectedBoxView</span><span class="pun">.</span><span class="typ">Color</span><span class="pun">;</span><span class="pln">
</span><span class="lit">33</span><span class="pln">	            btnMoveRight</span><span class="pun">.</span><span class="typ">BackgroundColor</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> selectedBoxView</span><span class="pun">.</span><span class="typ">Color</span><span class="pun">;</span><span class="pln">
</span><span class="lit">34</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">35</span><span class="pln">	
</span><span class="lit">36</span><span class="pln">	
</span><span class="lit">37</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> </span><span class="typ">MoveBox_Clicked</span><span class="pun">(</span><span class="pln">object sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">EventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
</span><span class="lit">38</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">39</span><span class="pln">	            </span><span class="typ">Button</span><span class="pln"> moveButton </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">Button</span><span class="pun">)</span><span class="pln">sender</span><span class="pun">;</span><span class="pln">
</span><span class="lit">40</span><span class="pln">	            </span><span class="typ">Rectangle</span><span class="pln"> rect</span><span class="pun">;</span><span class="pln">
</span><span class="lit">41</span><span class="pln">	
</span><span class="lit">42</span><span class="pln">	            </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">selectedBoxView </span><span class="pun">==</span><span class="pln"> null</span><span class="pun">)</span><span class="pln">
</span><span class="lit">43</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">44</span><span class="pln">	                </span><span class="typ">DisplayAlert</span><span class="pun">(</span><span class="str">"اختيار مربع"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"اختر مربّعًا من فضلك"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"موافق"</span><span class="pun">);</span><span class="pln">
</span><span class="lit">45</span><span class="pln">	                </span><span class="kwd">return</span><span class="pun">;</span><span class="pln">
</span><span class="lit">46</span><span class="pln">	            </span><span class="pun">}</span><span class="pln">
</span><span class="lit">47</span><span class="pln">	
</span><span class="lit">48</span><span class="pln">	            rect </span><span class="pun">=</span><span class="pln"> </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">GetLayoutBounds</span><span class="pun">(</span><span class="pln">selectedBoxView</span><span class="pun">);</span><span class="pln">
</span><span class="lit">49</span><span class="pln">	
</span><span class="lit">50</span><span class="pln">	            </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">moveButton</span><span class="pun">.</span><span class="typ">StyleId</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="str">"MoveBoxUp"</span><span class="pun">)</span><span class="pln">
</span><span class="lit">51</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">52</span><span class="pln">	                rect </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Rectangle</span><span class="pun">(</span><span class="pln">rect</span><span class="pun">.</span><span class="pln">X</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="pln">Y </span><span class="pun">-</span><span class="pln"> MOVE_AMOUNT</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="typ">Width</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="typ">Height</span><span class="pun">);</span><span class="pln">
</span><span class="lit">53</span><span class="pln">	            </span><span class="pun">}</span><span class="pln">
</span><span class="lit">54</span><span class="pln">	            </span><span class="kwd">else</span><span class="pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">moveButton</span><span class="pun">.</span><span class="typ">StyleId</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="str">"MoveBoxDown"</span><span class="pun">)</span><span class="pln">
</span><span class="lit">55</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">56</span><span class="pln">	                rect </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Rectangle</span><span class="pun">(</span><span class="pln">rect</span><span class="pun">.</span><span class="pln">X</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="pln">Y </span><span class="pun">+</span><span class="pln"> MOVE_AMOUNT</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="typ">Width</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="typ">Height</span><span class="pun">);</span><span class="pln">
</span><span class="lit">57</span><span class="pln">	            </span><span class="pun">}</span><span class="pln">
</span><span class="lit">58</span><span class="pln">	            </span><span class="kwd">else</span><span class="pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">moveButton</span><span class="pun">.</span><span class="typ">StyleId</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="str">"MoveBoxRight"</span><span class="pun">)</span><span class="pln">
</span><span class="lit">59</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">60</span><span class="pln">	                rect </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Rectangle</span><span class="pun">(</span><span class="pln">rect</span><span class="pun">.</span><span class="pln">X </span><span class="pun">+</span><span class="pln"> MOVE_AMOUNT</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="pln">Y</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="typ">Width</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="typ">Height</span><span class="pun">);</span><span class="pln">
</span><span class="lit">61</span><span class="pln">	            </span><span class="pun">}</span><span class="pln">
</span><span class="lit">62</span><span class="pln">	            </span><span class="kwd">else</span><span class="pln"> </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">moveButton</span><span class="pun">.</span><span class="typ">StyleId</span><span class="pln"> </span><span class="pun">==</span><span class="pln"> </span><span class="str">"MoveBoxLeft"</span><span class="pun">)</span><span class="pln">
</span><span class="lit">63</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">64</span><span class="pln">	                rect </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Rectangle</span><span class="pun">(</span><span class="pln">rect</span><span class="pun">.</span><span class="pln">X </span><span class="pun">-</span><span class="pln"> MOVE_AMOUNT</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="pln">Y</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="typ">Width</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="typ">Height</span><span class="pun">);</span><span class="pln">
</span><span class="lit">65</span><span class="pln">	            </span><span class="pun">}</span><span class="pln">
</span><span class="lit">66</span><span class="pln">	
</span><span class="lit">67</span><span class="pln">	            </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">SetLayoutBounds</span><span class="pun">(</span><span class="pln">selectedBoxView</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">);</span><span class="pln">
</span><span class="lit">68</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">69</span><span class="pln">	
</span><span class="lit">70</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> </span><span class="typ">PageResize</span><span class="pun">(</span><span class="pln">object sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">EventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
</span><span class="lit">71</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">72</span><span class="pln">	            </span><span class="typ">ContentPage</span><span class="pln"> page </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">ContentPage</span><span class="pun">)</span><span class="pln">sender</span><span class="pun">;</span><span class="pln">
</span><span class="lit">73</span><span class="pln">	
</span><span class="lit">74</span><span class="pln">	            </span><span class="kwd">double</span><span class="pln"> buttonWidth </span><span class="pun">=</span><span class="pln"> btnMoveUp</span><span class="pun">.</span><span class="typ">Width</span><span class="pun">;</span><span class="pln">
</span><span class="lit">75</span><span class="pln">	            </span><span class="kwd">double</span><span class="pln"> buttonHeight </span><span class="pun">=</span><span class="pln"> btnMoveUp</span><span class="pun">.</span><span class="typ">Height</span><span class="pun">;</span><span class="pln">
</span><span class="lit">76</span><span class="pln">	            </span><span class="kwd">double</span><span class="pln"> buttonsAreaWidth </span><span class="pun">=</span><span class="pln"> buttonWidth </span><span class="pun">*</span><span class="pln"> </span><span class="lit">3</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> BUTTON_MARGIN </span><span class="pun">*</span><span class="pln"> </span><span class="lit">2</span><span class="pun">;</span><span class="pln">
</span><span class="lit">77</span><span class="pln">	            </span><span class="kwd">double</span><span class="pln"> buttonsAreaLeftDisplacement </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">page</span><span class="pun">.</span><span class="typ">Width</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> buttonsAreaWidth</span><span class="pun">)</span><span class="pln"> </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">;</span><span class="pln">
</span><span class="lit">78</span><span class="pln">	
</span><span class="lit">79</span><span class="pln">	            </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">SetLayoutBounds</span><span class="pun">(</span><span class="pln">btnMoveDown</span><span class="pun">,</span><span class="pln">
</span><span class="lit">80</span><span class="pln">	               </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Rectangle</span><span class="pun">(</span><span class="pln">buttonsAreaLeftDisplacement </span><span class="pun">+</span><span class="pln"> buttonWidth </span><span class="pun">+</span><span class="pln"> BUTTON_MARGIN</span><span class="pun">,</span><span class="pln">
</span><span class="lit">81</span><span class="pln">	                   page</span><span class="pun">.</span><span class="typ">Height</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> buttonHeight </span><span class="pun">-</span><span class="pln"> PAGE_BUTTOM_MARGIN</span><span class="pun">,</span><span class="pln">
</span><span class="lit">82</span><span class="pln">	                   buttonWidth</span><span class="pun">,</span><span class="pln">
</span><span class="lit">83</span><span class="pln">	                   buttonHeight</span><span class="pun">));</span><span class="pln">
</span><span class="lit">84</span><span class="pln">	
</span><span class="lit">85</span><span class="pln">	            </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">SetLayoutBounds</span><span class="pun">(</span><span class="pln">btnMoveUp</span><span class="pun">,</span><span class="pln">
</span><span class="lit">86</span><span class="pln">	                </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Rectangle</span><span class="pun">(</span><span class="pln">buttonsAreaLeftDisplacement </span><span class="pun">+</span><span class="pln"> buttonWidth </span><span class="pun">+</span><span class="pln"> BUTTON_MARGIN</span><span class="pun">,</span><span class="pln">
</span><span class="lit">87</span><span class="pln">	                    page</span><span class="pun">.</span><span class="typ">Height</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> buttonHeight </span><span class="pun">*</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> BUTTON_MARGIN </span><span class="pun">-</span><span class="pln"> PAGE_BUTTOM_MARGIN</span><span class="pun">,</span><span class="pln">
</span><span class="lit">88</span><span class="pln">	                    buttonWidth</span><span class="pun">,</span><span class="pln">
</span><span class="lit">89</span><span class="pln">	                    buttonHeight</span><span class="pun">));</span><span class="pln">
</span><span class="lit">90</span><span class="pln">	
</span><span class="lit">91</span><span class="pln">	
</span><span class="lit">92</span><span class="pln">	            </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">SetLayoutBounds</span><span class="pun">(</span><span class="pln">btnMoveLeft</span><span class="pun">,</span><span class="pln">
</span><span class="lit">93</span><span class="pln">	                </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Rectangle</span><span class="pun">(</span><span class="pln">buttonsAreaLeftDisplacement</span><span class="pun">,</span><span class="pln">
</span><span class="lit">94</span><span class="pln">	                    page</span><span class="pun">.</span><span class="typ">Height</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="lit">3</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> buttonHeight </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> PAGE_BUTTOM_MARGIN</span><span class="pun">,</span><span class="pln">
</span><span class="lit">95</span><span class="pln">	                    buttonWidth</span><span class="pun">,</span><span class="pln">
</span><span class="lit">96</span><span class="pln">	                    buttonHeight</span><span class="pun">));</span><span class="pln">
</span><span class="lit">97</span><span class="pln">	
</span><span class="lit">98</span><span class="pln">	            </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">SetLayoutBounds</span><span class="pun">(</span><span class="pln">btnMoveRight</span><span class="pun">,</span><span class="pln">
</span><span class="lit">99</span><span class="pln">	                </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Rectangle</span><span class="pun">(</span><span class="pln">buttonsAreaLeftDisplacement </span><span class="pun">+</span><span class="pln"> buttonWidth </span><span class="pun">*</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> BUTTON_MARGIN </span><span class="pun">*</span><span class="pln"> </span><span class="lit">2</span><span class="pun">,</span><span class="pln">
</span><span class="lit">100</span><span class="pln">	                    page</span><span class="pun">.</span><span class="typ">Height</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="lit">3</span><span class="pln"> </span><span class="pun">*</span><span class="pln"> buttonHeight </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> PAGE_BUTTOM_MARGIN</span><span class="pun">,</span><span class="pln">
</span><span class="lit">101</span><span class="pln">	                    buttonWidth</span><span class="pun">,</span><span class="pln">
</span><span class="lit">102</span><span class="pln">	                    buttonHeight</span><span class="pun">));</span><span class="pln">
</span><span class="lit">103</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">104</span><span class="pln">	    </span><span class="pun">}</span><span class="pln">
</span><span class="lit">105</span><span class="pln">	</span><span class="pun">}</span></pre>

<p>
	يحتوي الصنف MoveSquaresByButtonsPage بشكل أساسيّ على بانية وعدّة توابع هي في الواقع معالجات للأحداث التي يحتاج إليها التطبيق. سنتحدّث عنها بشيء من التفصيل.
</p>

<h3>
	البانية
</h3>

<p>
	إذا نظرت إلى البانية (الأسطر من 13 حتى 24) فستجد أنّنا نعرّف ضمنها كائنًا من النوع TapGestureRecognizer (السطر 17) سنُسند هذا الكائن إلى المتغيّر tapGesture كما هو واضح. يفيد هذا الكائن في إكساب عنصر BoxView قابلية النقر لأنّه –وبشكل مغاير لعنصر الزر Button- لا يمتلكها أصلًا. نعمل في السطر 19 على تعيين معالج لحدث النقر (اللمس) Tapped للكائن السابق واسمه TapGesture_Tapped (سنتحدّث عنه بعد لحظة). العملية الأخيرة التي نجريها في البانية هي إضافة الكائن tapGesture إلى كل من المربّعات الثلاثة عن طريق التابع Add للمجموعة GestureRecognizers لكل مربع من هذه المربعات (الأسطر من 21 حتى 23).
</p>

<h3>
	معالج حدث النقر على المربّعات TapGesture_Tapped
</h3>

<p>
	يمكنك رؤية هذا المعالج في الأسطر من 26 حتى 34. الذي يحدث ضمن هذا المعالج هو أنّنا نحصل على مرجع المربّع الذي نقره المستخدم (السطر 28) ونُسنده إلى الحقل selectedBoxView وهو حقل خاص من النوع BoxView مصرّح عنه في السطر 8، ثم نلوّن أزرار التحريك الأربعة بنفس لون المربّع الذي نقره (لمسه) المستخدم.
</p>

<h3>
	معالج حدث النقر على الأزرار MoveBox_Clicked
</h3>

<p>
	بالنسبة لمعالج الحدث MoveBox_Clicked وهو موجود في الأسطر من 37 حتى 68 فهو يُستدعى عندما ينقر المستخدم أيًا من أزرار التحريك الأربعة. ووظيفته هو تحريك المربّع الذي اختاره المستخدم مسبقًا في الاتجاه المطلوب. نحصل في السطر 39 على مرجع الزر الذي تمّ نقره، ثمّ نختبر فيما إذا كان المستخدم قد قام فعلًا باختيار مربّع من قبل (الأسطر من 42 حتى 46) حيث يُعطي التطبيق تنبيهًا للمستخدم في حال لم يكن قد اختار مربّعًا من قبل. انظر الآن إلى السطر 48:
</p>

<pre>
<code>
</code></pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6699_15">
<span class="pln">rect </span><span class="pun">=</span><span class="pln"> </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">GetLayoutBounds</span><span class="pun">(</span><span class="pln">selectedBoxView</span><span class="pun">);</span></pre>

<p>
	يُرجع التابع GetLayoutBounds من الصنف AbsoluteLayout بنية من النوع Rectangle لأيّ عنصر مرئي نمرّره له موجود ضمن المخطّط المطلق. نحتاج هنا إلى معرفة المستطيل المُحدّد للمربّع الذي اختاره المستخدم من قبل. يُعطينا المستطيل المحدّد معلومات حول إحداثيّي الزاوية اليسرى العليا للمربّع (الإحداثي X والإحداثي Y) بالإضافة إلى عرض Width وارتفاع Height المربّع.
</p>

<p>
	تقارن بعد ذلك عبارات if الموجودة في الأسطر من 50 حتى 65 الخاصيّة StyleId للزر الذي نقره المستخدم مع عدّة نصوص معدّة سلفًا، لمعرفة الاتجاه المطلوب التحريك وفقه. لكي يتمكّن البرنامج من تعديل الإحداثي المطلوب على المستطيل المحدّد للمربّع وذلك بالانتقال المسافة المعيّنة بالثابت MOVE_AMOUNT الذي عرّفناه في السطر 11. بعد ذلك يتم تعيين المستطيل المحدّد الجديد (بعد التعديل) إلى المربّع نفسه (السطر 67) مما يؤدي إلى إعطاء انطباع بالحركة.
</p>

<h3>
	معالج حدث تغيير حجم الصفحة PageResize
</h3>

<p>
	بالنسبة للمعالج PageResize (الأسطر من 70 حتى 103) فهو يُستدعى عندما يطرأ تعديل على حجم الصفحة. وتنحصر وظيفة هذا المعالج في الحقيقة بوضع أزرار الحركة الأربعة بالشكل الذي أوضحناه أوّل الدرس. حيث يعتمد على ثابتين:
</p>

<ul>
<li>
		الثابت BUTTON_MARGIN (مصرّح عنه في السطر 9) ويمثّل التباعد بين أيّ زرّين.
	</li>
	<li>
		الثابت PAGE_BUTTOM_MARGIN (مصرّح عنه في السطر 10) ويمثّل الهامش السفلي لزر الحركة نحو الأسفل وذلك عن أسفل الشاشة.
	</li>
</ul>
<p>
	الأمر الملفت ضمن هذا المعالج هو كيفية حساب مسافة الإزاحة الأفقيّة لتوسيط مجموعة الأزرار أفقيًّا، حيث يتم ذلك بأسلوب حسابي بسيط. إذ أنّ الشيفرة تحسب العرض الإجمالي لثلاثة أزرار مضافًا إليها قيمتي هامشين (بين كل زرين هامش) وتضعه ضمن المتغيّر buttonsAreaWidth:
</p>

<pre>
<code>
</code></pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6699_17">
<span class="kwd">double</span><span class="pln"> buttonsAreaWidth </span><span class="pun">=</span><span class="pln"> buttonWidth </span><span class="pun">*</span><span class="pln"> </span><span class="lit">3</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> BUTTON_MARGIN </span><span class="pun">*</span><span class="pln"> </span><span class="lit">2</span><span class="pun">;</span></pre>

<p>
	ثمّ تقوم بطرح القيمة السابقة من عرض الصفحة page.Width وتقسّمه على 2. فنحصل على مقدار الإزاحة الأفقيّة الواجب تطبيقها من الجهة اليسرى وتضعها ضمن المتغيّر buttonsAreaLeftDisplacement:
</p>

<pre>
<code>
</code></pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6699_19">
<span class="kwd">double</span><span class="pln"> buttonsAreaLeftDisplacement </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">page</span><span class="pun">.</span><span class="typ">Width</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> buttonsAreaWidth</span><span class="pun">)</span><span class="pln"> </span><span class="pun">/</span><span class="pln"> </span><span class="lit">2</span><span class="pun">;</span></pre>

<p>
	ما تبقى من عبارات برمجيّة هي بسيطة في الواقع ولا تعدو عن كونها عبارات تنظيميّة تهدف إلى وضع الأزرار على نحو متناسق.
</p>

<p>
	انتقل أخيرًا إلى الملف App.cs واحرص على أن تكون بانيته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6699_21">
<span class="kwd">public</span><span class="pln"> </span><span class="typ">App</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="com">// The root page of your application</span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">MoveSquaresByButtonsPage</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	أصبح التطبيق جاهزًا للتنفيذ. يمكنك تنفيذه بضغط المفتاح F5 كما تعلّمنا.
</p>

<h3>
	الخلاصة
</h3>

<p>
	تحدثنا في هذا الدرس عن تطبيق عمليّ يعتمد على المخطّط المطلق Absolute Layout. حيث تعلّمنا كيفيّة التحكم الدقيق بمواضع العناصر لإكساب واجهة المستخدم شكلًا دقيقًا مُعد مسبقًا. كما تعلّمنا كيفيّة إكساب أيّ عنصر من النوع BoxView إمكانية الاستجابة لحدث النقر عن طريق كائن من الصنف TapGestureRecognizer. وتعلّمنا أيضًا تقنيّات بسيطة لتحريك العناصر المرئية على الشاشة. سننهي بهذا المقال حديثنا عن المخطّطات التي تدعمها Xamarin. في الحقيقة يُعتبر الفهم الجيّد للمخطّطات مفتاحًا أساسيًّا لبناء واجهة المستخدم.
</p>
]]></description><guid isPermaLink="false">463</guid><pubDate>Sat, 28 Jan 2017 21:00:00 +0000</pubDate></item><item><title>&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x627;&#x644;&#x645;&#x62E;&#x637;&#x651;&#x637; &#x627;&#x644;&#x645;&#x637;&#x644;&#x642; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x631;&#x645;&#x627;&#x632; XAML &#x641;&#x64A; &#x62A;&#x637;&#x628;&#x64A;&#x642;&#x627;&#x62A; Xamarin</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%A7%D9%84%D9%85%D8%AE%D8%B7%D9%91%D8%B7-%D8%A7%D9%84%D9%85%D8%B7%D9%84%D9%82-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D8%B1%D9%85%D8%A7%D8%B2-xaml-%D9%81%D9%8A-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-r462/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.bcc56806e493d6db3c25cc1fc488a111.png" /></p>

<p>
	المخطّط المطلق Absolute Layout هو من المخطّطات المعتمدة في Xamarin، وتقوم فكرته على السماح للعناصر المرئيّة الموجودة ضمنه بأن يكون تموضعها بشكل مطلق، أي من الممكن ضبط مكان التموضع بالإضافة إلى عرض وارتفاع كل عنصر مرئي بشكل دقيق باستخدام الواحدات المستقلة عن الجهاز independent-device units. ولعلّ هذا المفهوم ليس جديدًا، بل هو من المفاهيم القديمة في عالم البرمجة، فقد كان المبرمجون قديمًا (وما زالوا في بعض الأحيان حتى اليوم) يعتمدون على بناء واجهات التطبيقات بتعريف موضع وأبعاد (العرض والارتفاع) كل عنصر بشكل دقيق ضمن الواجهة. سنطّلع في هذا الدرس ضمن <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/" rel="">سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms</a> على كيفيّة التعامل مع هذا المخطّط باستخدام رماز XAML من خلال تطبيقين بسيطين.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22576" data-unique="5u69jr1lo" src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.2b12ba9012ee453642fd397888614d2a.png"></p>

<h3>
	تطبيق المربّعات المتداخلة
</h3>

<p>
	تعتمد فكرة هذا التطبيق على وجود 3 مربّعات متداخلة فيما بينها بحيث يمتلك كلّ منها شفافيّة بمقدار 50%. ستكون هذه المربّعات ضمن مخطّط مطلق Absolute Layout، وكلّ منها عبارة عن كائن ViewBox. سنعيّن مواقع وأبعاد هذه المربّعات باستخدام الواحدات المستقلة عن الجهاز independent-device units. أنشئ مشروعًا جديدًا من النوع Blank App (Xamarin.Forms Portable) وسمّه SimpleAbsoluteLayout، ثم أبق فقط على المشروعين SimpleAbsoluteLayout (Portable) و SimpleAbsoluteLayout.Droid كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-visual-studio-2015-community-%D9%88%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-xamarin-%D9%84%D9%84%D8%B9%D9%85%D9%84-r373/" rel="">هذا الدرس</a>. بعد ذلك سنضيف صفحة محتوى تعتمد على رماز XAML كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xaml-r453/" rel="">هذا الدرس</a> سنسمّيها SimpleAbsoluteLayoutPage. احرص على أن تكون محتويات هذه الصفحة على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5054_7">
<span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
</span><span class="pun">&lt;</span><span class="typ">ContentPage</span><span class="pln"> xmlns</span><span class="pun">=</span><span class="str">"http://xamarin.com/schemas/2014/forms"</span><span class="pln">
             xmlns</span><span class="pun">:</span><span class="pln">x</span><span class="pun">=</span><span class="str">"http://schemas.microsoft.com/winfx/2009/xaml"</span><span class="pln">
             x</span><span class="pun">:</span><span class="typ">Class</span><span class="pun">=</span><span class="str">"SimpleAbsoluteLayout.SimpleAbsoluteLayoutPage"</span><span class="pun">&gt;</span><span class="pln">
  
  </span><span class="pun">&lt;</span><span class="typ">AbsoluteLayout</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"absLayout"</span><span class="pun">&gt;</span><span class="pln">
      </span><span class="pun">&lt;</span><span class="typ">BoxView</span><span class="pln">  x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"boxAccent"</span><span class="pln">
                </span><span class="typ">Color</span><span class="pun">=</span><span class="str">"Accent"</span><span class="pln">
                </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">LayoutBounds</span><span class="pun">=</span><span class="str">"25, 100, 110, 110"</span><span class="pln">
                </span><span class="typ">Opacity</span><span class="pun">=</span><span class="str">"0.5"</span><span class="pun">/&gt;</span><span class="pln">

      </span><span class="pun">&lt;</span><span class="typ">BoxView</span><span class="pln">  x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"boxRed"</span><span class="pln">
                </span><span class="typ">Color</span><span class="pun">=</span><span class="str">"Red"</span><span class="pln">
                </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">LayoutBounds</span><span class="pun">=</span><span class="str">"50, 125, 110, 110"</span><span class="pln">
                </span><span class="typ">Opacity</span><span class="pun">=</span><span class="str">"0.5"</span><span class="pun">/&gt;</span><span class="pln">

      </span><span class="pun">&lt;</span><span class="typ">BoxView</span><span class="pln">  x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"boxGreen"</span><span class="pln">
                </span><span class="typ">Color</span><span class="pun">=</span><span class="str">"Green"</span><span class="pln">
                </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">LayoutBounds</span><span class="pun">=</span><span class="str">"75, 150, 110, 110"</span><span class="pln">
                </span><span class="typ">Opacity</span><span class="pun">=</span><span class="str">"0.5"</span><span class="pun">/&gt;</span><span class="pln">
  </span><span class="pun">&lt;/</span><span class="typ">AbsoluteLayout</span><span class="pun">&gt;</span><span class="pln">
</span><span class="pun">&lt;/</span><span class="typ">ContentPage</span><span class="pun">&gt;</span></pre>

<p>
	محتويات هذه الصفحة بسيطة وواضحة. حيث نعمل على إنشاء مخطّط مطلق باستخدام الوسم <absolutelayout>. لاحظ كيف وضعنا ضمن هذا العنصر ثلاثة عناصر من النوع BoxView. وقد عيّنّا لكل عنصر منها اسمًا لأنّنا سنحتاجه في القسم الثاني من هذا الدرس. الملفت للنظر أنّ هذه العناصر قد تمّ وضعها مباشرةً ضمن العنصر AbsoluteLayout دون الحاجة إلى وجود الوسم <children> وهذا جائز تمامًا. لاحظ بالنسبة إلى عنصر BoxView الأوّل:</children></absolutelayout></p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5054_9">
<span class="pun">&lt;</span><span class="typ">BoxView</span><span class="pln">  x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"boxAccent"</span><span class="pln">
          </span><span class="typ">Color</span><span class="pun">=</span><span class="str">"Accent"</span><span class="pln">
          </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">LayoutBounds</span><span class="pun">=</span><span class="str">"25, 100, 110, 110"</span><span class="pln">
          </span><span class="typ">Opacity</span><span class="pun">=</span><span class="str">"0.5"</span><span class="pun">/&gt;</span></pre>

<p>
	الخاصيّة التي تتحكّم بموضعه هي AbsoluteLayout.LayoutBounds حيث أسندنا إليها النص:
</p>

<pre>
<code>
</code></pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5054_11">
<span class="pln"> </span><span class="str">"25, 100, 110, 110"</span><span class="pln"> </span></pre>

<p>
	الذي يحتوي على أربعة أرقام تفصل بينها فواصل، وهي من اليسار إلى اليمين:
</p>

<ul>
<li>
		بعد الزاوية اليسرى العليا من العنصر عن الحافة اليسرى للمخطّط المطلق ورمزه X (القيمة 25).
	</li>
	<li>
		بعد الزاوية اليسرى العليا من العنصر عن الحافة العليا للمخطّط المطلق ورمزه Y (القيمة 100).
	</li>
	<li>
		عرض العنصر ورمزه Width (القيمة 110).
	</li>
	<li>
		ارتفاع العنصر ورمزه Height (القيمة 110).
	</li>
</ul>
<p>
	انظر الشكل التخطيطي التالي لمزيد من التوضيح:
</p>

<p style="text-align: center;">
	<img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22577" data-unique="9y31qngqx" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.png.c4ae13d614ee6f6d69321fe2f3de892d.png"></p>

<p>
	في الحقيقة يمكنك اعتبار الشكل السابق كجملة إحداثية ديكارتيّة، ولكنّ محور التراتيب y-axis موجّه نحو الأسفل كما هو واضح بدلًا من الاتجاه المألوف نحو الأعلى. ينطبق نفس الأمر تمامًا على عنصريّ BoxView الباقيين:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5054_13">
<span class="pun">&lt;</span><span class="typ">BoxView</span><span class="pln">  x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"boxRed"</span><span class="pln">
          </span><span class="typ">Color</span><span class="pun">=</span><span class="str">"Red"</span><span class="pln">
          </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">LayoutBounds</span><span class="pun">=</span><span class="str">"50, 125, 110, 110"</span><span class="pln">
          </span><span class="typ">Opacity</span><span class="pun">=</span><span class="str">"0.5"</span><span class="pun">/&gt;</span><span class="pln">

</span><span class="pun">&lt;</span><span class="typ">BoxView</span><span class="pln">  x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"boxGreen"</span><span class="pln">
          </span><span class="typ">Color</span><span class="pun">=</span><span class="str">"Green"</span><span class="pln">
          </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">LayoutBounds</span><span class="pun">=</span><span class="str">"75, 150, 110, 110"</span><span class="pln">
          </span><span class="typ">Opacity</span><span class="pun">=</span><span class="str">"0.5"</span><span class="pun">/&gt;</span></pre>

<p>
	وبما أنّ لكل من هذه العناصر الثلاثة نفس القيمة للعرض وللارتفاع، إذًا فهي عبارة عن مربّعات، وهي طبوقة فيما بينها. إذا نظرت إلى الأرقام الخاصّة بالموضع وبالحجم التي اخترتها "للمربّعات" الثلاث، فستلاحظ أنّني اخترتها بعناية كي تكون متداخلة فيما بينها. وقد جعلت الشفافيّة (الخاصية Opacity) لكلّ منها 50% (القيمة 0.5) لكي تعطي ذلك التأثير اللوني الجميل عندما تتداخل مع بعضها. انتقل الآن إلى الملف App.cs واحرص على ان تكون بانية الصنف App على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5054_15">
<span class="kwd">public</span><span class="pln"> </span><span class="typ">App</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="com">// The root page of your application</span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">SimpleAbsoluteLayoutPage</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	نفّذ التطبيق باستخدام F5، لتحصل على شكل شبيه بما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22578" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.png.83c7b68fc4b2d47074680d27b6ad16d7.png" rel=""><img alt="fig02.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22578" data-unique="adlrslc1i" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.thumb.png.01483333fa9f8eb3545c12173792e389.png"></a>
</p>

<h3>
	لنحرّك المربّعات!
</h3>

<p>
	لنعمل على إضفاء القليل من الإثارة على التطبيق السابق. سنعمل على تحريك المربّعات السابقة بحركة رأسيّة تلقائيّة. أي أنّ المربّعات السابقة ستتحرّك نحو الأعلى حتى تصل إلى الحافة العليا للشاشة، ثم تعكس اتجاه الحركة نحو الأسفل حتى تصل إلى الحافة السفلى من الشاشة. ثم تعود من جديد لتعكس جهة الحركة لتصبح نحو الأعلى، وهكذا دواليك. في الحقيقة لن يطرأ أيّ تغيير على رماز XAML، فكل ما سنفعله هو إضافة الشيفرة البرمجيّة المناسبة لملف الشيفرة البرمجيّة الموافق لملف الرماز السابق. انتقل الآن إلى الملف SimpleAbsoluteLayoutPage.xaml.cs واحرص على أن تكون محتوياته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_5054_17">
<span class="lit">1</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">;</span><span class="pln">
</span><span class="lit">2</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">
</span><span class="lit">3</span><span class="pln">	
</span><span class="lit">4</span><span class="pln">	</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">SimpleAbsoluteLayout</span><span class="pln">
</span><span class="lit">5</span><span class="pln">	</span><span class="pun">{</span><span class="pln">
</span><span class="lit">6</span><span class="pln">	    </span><span class="kwd">public</span><span class="pln"> partial </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">SimpleAbsoluteLayoutPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
</span><span class="lit">7</span><span class="pln">	    </span><span class="pun">{</span><span class="pln">
</span><span class="lit">8</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">bool</span><span class="pln"> isUpDirection</span><span class="pun">;</span><span class="pln">
</span><span class="lit">9</span><span class="pln">	        </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">SimpleAbsoluteLayoutPage</span><span class="pun">()</span><span class="pln">
</span><span class="lit">10</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">11</span><span class="pln">	            </span><span class="typ">InitializeComponent</span><span class="pun">();</span><span class="pln">
</span><span class="lit">12</span><span class="pln">	
</span><span class="lit">13</span><span class="pln">	            isUpDirection </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln">
</span><span class="lit">14</span><span class="pln">	
</span><span class="lit">15</span><span class="pln">	            </span><span class="typ">Device</span><span class="pun">.</span><span class="typ">StartTimer</span><span class="pun">(</span><span class="typ">TimeSpan</span><span class="pun">.</span><span class="typ">FromMilliseconds</span><span class="pun">(</span><span class="lit">50</span><span class="pun">),</span><span class="pln"> </span><span class="typ">UpdatePositions</span><span class="pun">);</span><span class="pln">
</span><span class="lit">16</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">17</span><span class="pln">	
</span><span class="lit">18</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">bool</span><span class="pln"> </span><span class="typ">UpdatePositions</span><span class="pun">()</span><span class="pln">
</span><span class="lit">19</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">20</span><span class="pln">	            </span><span class="typ">Rectangle</span><span class="pln"> rect</span><span class="pun">;</span><span class="pln">
</span><span class="lit">21</span><span class="pln">	
</span><span class="lit">22</span><span class="pln">	            rect </span><span class="pun">=</span><span class="pln"> </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">GetLayoutBounds</span><span class="pun">(</span><span class="pln">boxAccent</span><span class="pun">);</span><span class="pln">
</span><span class="lit">23</span><span class="pln">	            </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">rect</span><span class="pun">.</span><span class="pln">Y </span><span class="pun">-</span><span class="pln"> </span><span class="lit">10</span><span class="pln"> </span><span class="pun">&lt;=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln">
</span><span class="lit">24</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">25</span><span class="pln">	                isUpDirection </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">false</span><span class="pun">;</span><span class="pln">
</span><span class="lit">26</span><span class="pln">	            </span><span class="pun">}</span><span class="pln">
</span><span class="lit">27</span><span class="pln">	
</span><span class="lit">28</span><span class="pln">	            rect </span><span class="pun">=</span><span class="pln"> </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">GetLayoutBounds</span><span class="pun">(</span><span class="pln">boxGreen</span><span class="pun">);</span><span class="pln">
</span><span class="lit">29</span><span class="pln">	            </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">rect</span><span class="pun">.</span><span class="pln">Y </span><span class="pun">+</span><span class="pln"> rect</span><span class="pun">.</span><span class="typ">Height</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> </span><span class="lit">10</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="typ">Height</span><span class="pun">)</span><span class="pln">
</span><span class="lit">30</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">31</span><span class="pln">	                isUpDirection </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln">                
</span><span class="lit">32</span><span class="pln">	            </span><span class="pun">}</span><span class="pln">
</span><span class="lit">33</span><span class="pln">	
</span><span class="lit">34</span><span class="pln">	            </span><span class="typ">BoxView</span><span class="pun">[]</span><span class="pln"> boxViews </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="pln"> boxAccent</span><span class="pun">,</span><span class="pln"> boxRed</span><span class="pun">,</span><span class="pln"> boxGreen </span><span class="pun">};</span><span class="pln">
</span><span class="lit">35</span><span class="pln">	
</span><span class="lit">36</span><span class="pln">	            </span><span class="kwd">for</span><span class="pln"> </span><span class="pun">(</span><span class="typ">int</span><span class="pln"> i </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln"> i </span><span class="pun">&lt;</span><span class="pln"> boxViews</span><span class="pun">.</span><span class="typ">Length</span><span class="pun">;</span><span class="pln"> i</span><span class="pun">++)</span><span class="pln">
</span><span class="lit">37</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">38</span><span class="pln">	                rect </span><span class="pun">=</span><span class="pln"> </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">GetLayoutBounds</span><span class="pun">(</span><span class="pln">boxViews</span><span class="pun">[</span><span class="pln">i</span><span class="pun">]);</span><span class="pln">
</span><span class="lit">39</span><span class="pln">	
</span><span class="lit">40</span><span class="pln">	                </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">isUpDirection</span><span class="pun">)</span><span class="pln">
</span><span class="lit">41</span><span class="pln">	                </span><span class="pun">{</span><span class="pln">
</span><span class="lit">42</span><span class="pln">	                    rect </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Rectangle</span><span class="pun">(</span><span class="pln">rect</span><span class="pun">.</span><span class="pln">X</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="pln">Y </span><span class="pun">-</span><span class="pln"> </span><span class="lit">10</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="typ">Width</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="typ">Height</span><span class="pun">);</span><span class="pln">
</span><span class="lit">43</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">44</span><span class="pln">	                </span><span class="kwd">else</span><span class="pln">
</span><span class="lit">45</span><span class="pln">	                </span><span class="pun">{</span><span class="pln">
</span><span class="lit">46</span><span class="pln">	                    rect </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Rectangle</span><span class="pun">(</span><span class="pln">rect</span><span class="pun">.</span><span class="pln">X</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="pln">Y </span><span class="pun">+</span><span class="pln"> </span><span class="lit">10</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="typ">Width</span><span class="pun">,</span><span class="pln"> rect</span><span class="pun">.</span><span class="typ">Height</span><span class="pun">);</span><span class="pln">
</span><span class="lit">47</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">48</span><span class="pln">	
</span><span class="lit">49</span><span class="pln">	                </span><span class="typ">AbsoluteLayout</span><span class="pun">.</span><span class="typ">SetLayoutBounds</span><span class="pun">(</span><span class="pln">boxViews</span><span class="pun">[</span><span class="pln">i</span><span class="pun">],</span><span class="pln"> rect</span><span class="pun">);</span><span class="pln">
</span><span class="lit">50</span><span class="pln">	            </span><span class="pun">}</span><span class="pln">
</span><span class="lit">51</span><span class="pln">	
</span><span class="lit">52</span><span class="pln">	            </span><span class="kwd">return</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln">
</span><span class="lit">53</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">54</span><span class="pln">	    </span><span class="pun">}</span><span class="pln">
</span><span class="lit">55</span><span class="pln">	</span><span class="pun">}</span></pre>

<p>
	بالإضافة إلى بانية الصنف SimpleAbsoluteLayoutPage أنشأت تابعًا جديدًا أسميته UpdatePositions يمكنك أن تجده في الأسطر من 18 حتى 53. يُعتبر هذا التابع مسؤولًا عن تحريك المربّعات الثلاثة بالحركة الرأسيّة التي تحدثنا عنها قبل قليل. يتمّ استدعاء هذا التابع بشكل تلقائيّ كل 50 ميللي ثانيّة. التقنيّة التي استخدمناها في هذا الاستدعاء هي نفسها الموجودة في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-%D8%B9%D9%85%D9%84%D9%8A%D9%91%D8%A9-%D8%AD%D9%88%D9%84-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D9%82%D9%8A%D8%A7%D8%B3%D8%A7%D8%AA-%D9%81%D9%8A-xamarin-r414/" rel="">هذا الدرس</a>. حيث استخدمنا التابع StartTimer من الصنف Device لهذا الغرض (انظر السطر 15).
</p>

<p>
	لاحظ الحقل isUpDirection من النوع bool المصرّح عنه في السطر 8. يُفيد هذا الحقل في الاحتفاظ بالاتجاه الحالي للمربّعات أثناء الحركة (أي هل الحركة نحو الأعلى أم نحو الأسفل). يبدأ التابع UpdatePositions بالتصريح عن المتغيّر rect من النوع Rectangle (السطر 20). و Rectangle هو عبارة عن بنية struct أي هو من نوع قيمة value type. يُفيد هذا النوع في وصف الأشكال المستطيلة عمومًا. فهو يمتلك أربع خصائص تصف حجم وموضع أيّ مستطيل على الشاشة. هذه الخصائص هي: X و Y و Width و Height وهي تصف على الترتيب: مقدار الإزاحة الأفقيّة عن الحد الأيسر، مقدار الإزاحة الرأسيّة عن الحد الأعلى، وعرض المستطيل، وارتفاع المستطيل. وذلك بمنطق مشابه لما ورد ذكره في الشكل الأوّل الذي تعرضنا له في هذا الدرس.
</p>

<p>
	نقوم في السطر 22 بالحصول على المستطيل (المربّع في واقع الأمر) الحاضن للعنصر boxAccent وهو المربّع الأوّل. ثمّ نختبر كون الإحداثي Y له قد أوشك أن يصبح سالبًا وذلك في السطر 23. فإن أوشك على ذلك فهذا يعني أنّ المربّع boxAccent قد ارتطم بالحد الأعلى للشاشة ويجب تغيير اتجاه الحركة ليصبح نحو الأسفل بدلًا من الأعلى، وهذا ما نفعله في السطر 25.
</p>

<p>
	نفس المنطق السابق نطبّقه على العنصر boxGreen وهو المربّع الثالث، وذلك في السطر 28. حيث نحصل على المستطيل الحاضن للعنصر boxGreen. ثمّ نختبر كون الحافة السفلى له (تأمل التعبير rect.Y + rect.Height + 10) قد أوشكت أن تتجاوز قيمتها ارتفاع الصفحة (وهو يماثل في مثالنا الارتفاع الكامل للمخطّط المطلق) وذلك في السطر 29. فإن أوشكت على ذلك فهذا يعني أنّ المربّع boxGreen سيتجاوز الحد السفلي للشاشة ويجب تغيير اتجاه الحركة ليصبح نحو الأعلى بدلًا من الأسفل، وهذا ما نفعله في السطر 31. بعد ذلك ننشئ المصفوفة boxViews بحيث تحتوي على عناصر المربّعات الثلاثة boxAccent و boxRed و boxGreen وذلك في السطر 34.
</p>

<p>
	ثمّ يدخل البرنامج حلقة for (الأسطر من 36 حتى 50) التي تنحصر وظيفتها في تحديث إحداثيات المربّعات الثلاثة بحيث تحرّكها نحو الأعلى أو نحو الأسفل بحسب قيمة الحقل isUpDirection. سيكون مقدار الانتقال الرأسي 10 وحدات في كل مرّة كما هو واضح في السطرين 42 و 46. ويتم إسناد الإحداثيّات الجديدة للمربّعات الثلاثة عن طريق استدعاء التابع الساكن AbsoluteLayout.SetLayoutBounds في السطر 49. حيث يتطلّب هذا التابع وسيطين. الأوّل هو المربّع المراد تطبيق الإحداثيات الجديدة عليه وهو موجود ضمن المصفوفة boxView، والثاني هو قيمة من النوع Rectange تحوي المستطيل (المربّع في مثالنا هذا) الحاضن الجديد.
</p>

<blockquote>
	<blockquote class="ipsQuote" data-ipsquote="">
		<div class="ipsQuote_citation">
			Quote
		</div>

		<div class="ipsQuote_contents ipsClearfix">
			<p>
				لاحظ بأنّ استخدامنا للمصفوفة boxViews يوفّر علينا الكثير من العبارات البرمجيّة التي ستتكرّر. فمن خلال حلقة for نستطيع المرور على جميع عناصر المصفوفة والتي هي عبارة عن المربّعات التي نريد تحريكها.
			</p>
		</div>
	</blockquote>

	<p>
		 
	</p>
</blockquote>

<h3>
	الخلاصة
</h3>

<p>
	تحدثنا في هذا الدرس عن المخطّط المطلق Absolute Layout وكيفيّة استخدامه من خلال رماز XAML. يفيد هذا المخطّط كما أشرنا في التحكّم بحجم وتموضع أي عنصر مرئي على الشاشة على نحو دقيق. تناولنا تطبيقين بسيطين يوضّحان كيفيّة التحكّم بحجم وموضع كل عنصر من عناصر BoxView، كما استخدمنا التابع StartTimer من الصنف Device لتوليد استدعاءات تلقائيّة ذات أزمنة منتظمة إلى تابع مخصّص كي يتحكّم بمواضع هذه العناصر. سنتناول في الدرس القادم تطبيقًا عمليًّا هو في واقع الأمر تحديث للتطبيق الثاني في هذا الدرس لكي نتحكّم في مواضع العناصر بشكل مخصّص أكثر.
</p>
]]></description><guid isPermaLink="false">462</guid><pubDate>Tue, 10 Jan 2017 21:00:00 +0000</pubDate></item><item><title>&#x62A;&#x637;&#x628;&#x64A;&#x642; &#x62D;&#x633;&#x627;&#x628; &#x62A;&#x643;&#x631;&#x627;&#x631; &#x627;&#x644;&#x645;&#x62D;&#x627;&#x631;&#x641; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x645;&#x62E;&#x637;&#x651;&#x637; &#x627;&#x644;&#x634;&#x628;&#x643;&#x629;</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D8%AD%D8%B3%D8%A7%D8%A8-%D8%AA%D9%83%D8%B1%D8%A7%D8%B1-%D8%A7%D9%84%D9%85%D8%AD%D8%A7%D8%B1%D9%81-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%85%D8%AE%D8%B7%D9%91%D8%B7-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A9-r461/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.8c177c49613c9af19cd36dbdd9fbd4e3.png" /></p>

<p>
	سنتناول في هذا الدرس من <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/" rel="">سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms</a> تطبيقًا عمليًّا مفيدًا آخرًا، نتعلّم من خلاله المزيد عن مزايا مخطّط الشبكة Grid Layout واستخداماته العمليّة في التطبيقات التي نطوّرها. سيستخدم هذا التطبيق مخطّطًا تكراريًّا Histogram سيكون مصمّمًا باستخدام مخطّط الشبكة. إذا أردت معرفة المزيد عن مخطّط الشبكة فيمكنك مراجعة هذا الدرس. وإلّا، فيمكنك البدء مباشرةً في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%85%D8%AE%D8%B7%D9%91%D8%B7-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A9-grid-%D9%84%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D9%85%D8%AA%D9%82%D8%AF%D9%91%D9%85%D8%A9-r459/" rel="">هذا الدرس</a>.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22575" data-unique="5y9i1o267" src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.c095406553f4f14e833b895ffde5bed0.png"></p>

<h3>
	فكرة التطبيق
</h3>

<p>
	تتلخّص فكرة هذا التطبيق في أنّ المستخدم سيُدخل نصًّا بأيّ لغة يرغبها. ثم ينقر على زر "احسب" ليعمل التطبيق بعد ذلك على حساب تكرار كلّ محرف من محارف النص المُدخل. بعد الانتهاء من ذلك، سيعمل التطبيق على إظهار مخطّط تكراري Histogram على شكل مخطّط أعمدة bars chart يمكن من خلاله ملاحظة الأحرف الأكثر تكرارًا والأقل تكرارًا من نظرة واحدة.
</p>

<p>
	سيعتمد التطبيق على عنصر رسومي من النوع Editor لاستقبال الدخل النصيّ من المستخدم. وكذلك على عنصر الزر Button للبدء بإيجاد القيم التكراريّة، وأيضًا سيستخدم مخطط شبكة لعرض النتائج التكراريّة. من أجل كل حرف موجود في النص، سيضيف التطبيق عمود bar سيكون عبارة عن عنصر BoxView يكون ارتفاعه متناسبًا مع تكرار الحرف ضمن النص المُدخَل. بعد إظهار مخطّط الأعمدة سيكون من الممكن النقر على أي عمود (عنصر BoxView) ليعرض التطبيق رسالة للمستخدم تحوي الحرف الذي يمثّله هذا العمود مع عدد مرًّات تكراره ضمن النص المُدخَل. أي بشكل مشابه لما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22574" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.png.42b8af002fbf233a3b959f7d946238f3.png" rel=""><img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22574" data-unique="jn15545zz" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.thumb.png.110aff2d077582de9dc09bb5e9b9f5b8.png"></a>
</p>

<p>
	سنتناول في الفقرة التالية كامل الشيفرة البرمجيّة لهذا التطبيق.
</p>

<h3>
	الشيفرة البرمجيّة للتطبيق
</h3>

<p>
	ابدأ بإنشاء مشروع جديد من النوع Blank App (Xamarin.Forms Portable) وسمّه GridBarChart، ثم أبق فقط على المشروعين GridBarChart (Portable) و GridBarChart.Droid كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-visual-studio-2015-community-%D9%88%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-xamarin-%D9%84%D9%84%D8%B9%D9%85%D9%84-r373/" rel="">هذا الدرس</a>. بعد ذلك سنضيف صفحة محتوى تعتمد على رماز XAML كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xaml-r453/" rel="">هذا الدرس</a> سنسمّها GridBarChartPage. احرص على أن تكون محتويات هذه الصفحة على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_7335_7">
<span class="lit">1</span><span class="pln">	</span><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
</span><span class="lit">2</span><span class="pln">	</span><span class="pun">&lt;</span><span class="typ">ContentPage</span><span class="pln"> xmlns</span><span class="pun">=</span><span class="str">"http://xamarin.com/schemas/2014/forms"</span><span class="pln">
</span><span class="lit">3</span><span class="pln">	             xmlns</span><span class="pun">:</span><span class="pln">x</span><span class="pun">=</span><span class="str">"http://schemas.microsoft.com/winfx/2009/xaml"</span><span class="pln">
</span><span class="lit">4</span><span class="pln">	             x</span><span class="pun">:</span><span class="typ">Class</span><span class="pun">=</span><span class="str">"GridBarChart.GridBarChartPage"</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">5</span><span class="pln">	  </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">6</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pln"> </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"Start"</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">7</span><span class="pln">	      </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"تطبيق حساب تكرار المحارف"</span><span class="pln"> 
</span><span class="lit">8</span><span class="pln">	             </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"CenterAndExpand"</span><span class="pln">  
</span><span class="lit">9</span><span class="pln">	             </span><span class="typ">HorizontalTextAlignment</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln">
</span><span class="lit">10</span><span class="pln">	             </span><span class="typ">FontSize</span><span class="pun">=</span><span class="str">"Large"</span><span class="pln"> 
</span><span class="lit">11</span><span class="pln">	             </span><span class="typ">TextColor</span><span class="pun">=</span><span class="str">"Green"</span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">12</span><span class="pln">	      </span><span class="pun">&lt;</span><span class="typ">Editor</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"txtInput"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">13</span><span class="pln">	      </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"btnCalculate"</span><span class="pln"> 
</span><span class="lit">14</span><span class="pln">	              </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"احسب"</span><span class="pln"> 
</span><span class="lit">15</span><span class="pln">	              </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"FillAndExpand"</span><span class="pln">
</span><span class="lit">16</span><span class="pln">	              </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"btnCalculate_Clicked"</span><span class="pln">  </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">17</span><span class="pln">	    </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">18</span><span class="pln">	    
</span><span class="lit">19</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">Grid</span><span class="pln">  x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"grdLettersHistogram"</span><span class="pln">
</span><span class="lit">20</span><span class="pln">	           </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"FillAndExpand"</span><span class="pln">
</span><span class="lit">21</span><span class="pln">	           </span><span class="typ">BackgroundColor</span><span class="pun">=</span><span class="str">"#EBF2F5"</span><span class="pln">
</span><span class="lit">22</span><span class="pln">	           </span><span class="typ">Padding</span><span class="pun">=</span><span class="str">"5,5,5,0"</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">23</span><span class="pln">	    </span><span class="pun">&lt;/</span><span class="typ">Grid</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">24</span><span class="pln">	  </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">25</span><span class="pln">	</span><span class="pun">&lt;/</span><span class="typ">ContentPage</span><span class="pun">&gt;</span></pre>

<p>
	من الملاحظ أنّ رماز XAML لهذا التطبيق صغير نسبيًّا. يبدأ الرماز بتعريف مخطّط مكدّس StackLayout سيعمل على احتواء كامل واجهة التطبيق. سيحتوي مخطّط المكدّس هذا على عنصرين آخرين:
</p>

<ul>
<li>
		العنصر الأوّل عبارة عن مخطّط مكدّس آخر (الأسطر من 6 حتى 17) يحتوي على لصيقة تعريفيّة بالتطبيق، وعلى عنصر الإدخال النصيّ Editor الذي أسميته txtInput وهو يسمح بكتابة أكثر من سطر نصيّ واحد ضمنه، بالإضافة إلى زر البدء بالحساب الذي أسميته btnCalculate والذي سيؤدّي نقره إلى الانتقال إلى معالج حدث النقر btnCalculate_Clicked. المعالج السابق سيكون بالتأكيد ضمن ملف الشيفرة البرمجيّة الذي سنطّلع عليه بعد قليل.
	</li>
	<li>
		العنصر الثاني هو مخطّط الشبكة (الأسطر من 19 حتى 23) والذي أسميته grdLettersHistogram. لاحظ أنّ هذا المخطّط لا يحوي حاليًّا أيّة عناصر. سنضيف لاحقًا إلى هذا المخطّط عناصر BoxView يمثّل كل منها محرفًا موجودًا ضمن النص المُدخَل، وذلك عن طريق الشيفرة البرمجيّة كما سنرى بعد قليل. انتقل الآن إلى الملف GridBarChartPage.xaml.cs وهو ملف الشيفرة البرمجيّة التابع لملف رماز XAML السابق. احرص على أن تكون محتوياته على الشكل التالي:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_7335_9">
<span class="lit">1</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">;</span><span class="pln">
</span><span class="lit">2</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Collections</span><span class="pun">.</span><span class="typ">Generic</span><span class="pun">;</span><span class="pln">
</span><span class="lit">3</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">
</span><span class="lit">4</span><span class="pln">	
</span><span class="lit">5</span><span class="pln">	</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">GridBarChart</span><span class="pln">
</span><span class="lit">6</span><span class="pln">	</span><span class="pun">{</span><span class="pln">
</span><span class="lit">7</span><span class="pln">	    </span><span class="kwd">public</span><span class="pln"> partial </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">GridBarChartPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
</span><span class="lit">8</span><span class="pln">	    </span><span class="pun">{</span><span class="pln">
</span><span class="lit">9</span><span class="pln">	        </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">GridBarChartPage</span><span class="pun">()</span><span class="pln">
</span><span class="lit">10</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">11</span><span class="pln">	            </span><span class="typ">InitializeComponent</span><span class="pun">();</span><span class="pln">
</span><span class="lit">12</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">13</span><span class="pln">	
</span><span class="lit">14</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> btnCalculate_Clicked</span><span class="pun">(</span><span class="pln">object sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">EventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
</span><span class="lit">15</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">16</span><span class="pln">	            </span><span class="typ">Dictionary</span><span class="pun">&lt;</span><span class="kwd">char</span><span class="pun">,</span><span class="pln"> </span><span class="typ">int</span><span class="pun">&gt;</span><span class="pln"> freq </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Dictionary</span><span class="pun">&lt;</span><span class="kwd">char</span><span class="pun">,</span><span class="pln"> </span><span class="typ">int</span><span class="pun">&gt;();</span><span class="pln">
</span><span class="lit">17</span><span class="pln">	            </span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">View</span><span class="pun">&gt;</span><span class="pln"> bars </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">List</span><span class="pun">&lt;</span><span class="typ">View</span><span class="pun">&gt;();</span><span class="pln">
</span><span class="lit">18</span><span class="pln">	            </span><span class="typ">TapGestureRecognizer</span><span class="pln"> tapGesture </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">TapGestureRecognizer</span><span class="pun">();</span><span class="pln">
</span><span class="lit">19</span><span class="pln">	            </span><span class="typ">int</span><span class="pln"> maxFreq </span><span class="pun">=</span><span class="pln"> </span><span class="pun">-</span><span class="lit">1</span><span class="pun">;</span><span class="pln">
</span><span class="lit">20</span><span class="pln">	
</span><span class="lit">21</span><span class="pln">	            tapGesture</span><span class="pun">.</span><span class="typ">Tapped</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> </span><span class="typ">TapGesture_Tapped</span><span class="pun">;</span><span class="pln">
</span><span class="lit">22</span><span class="pln">	
</span><span class="lit">23</span><span class="pln">	            string s </span><span class="pun">=</span><span class="pln"> txtInput</span><span class="pun">.</span><span class="typ">Text</span><span class="pun">;</span><span class="pln">
</span><span class="lit">24</span><span class="pln">	
</span><span class="lit">25</span><span class="pln">	            foreach </span><span class="pun">(</span><span class="kwd">char</span><span class="pln"> t in s</span><span class="pun">)</span><span class="pln">
</span><span class="lit">26</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">27</span><span class="pln">	                </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="kwd">char</span><span class="pun">.</span><span class="typ">IsLetterOrDigit</span><span class="pun">(</span><span class="pln">t</span><span class="pun">))</span><span class="pln">
</span><span class="lit">28</span><span class="pln">	                </span><span class="pun">{</span><span class="pln">
</span><span class="lit">29</span><span class="pln">	                    </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(!</span><span class="pln">freq</span><span class="pun">.</span><span class="typ">ContainsKey</span><span class="pun">(</span><span class="pln">t</span><span class="pun">))</span><span class="pln">
</span><span class="lit">30</span><span class="pln">	                    </span><span class="pun">{</span><span class="pln">
</span><span class="lit">31</span><span class="pln">	                        freq</span><span class="pun">.</span><span class="typ">Add</span><span class="pun">(</span><span class="pln">t</span><span class="pun">,</span><span class="pln"> </span><span class="lit">1</span><span class="pun">);</span><span class="pln">
</span><span class="lit">32</span><span class="pln">	                    </span><span class="pun">}</span><span class="pln">
</span><span class="lit">33</span><span class="pln">	                    </span><span class="kwd">else</span><span class="pln">
</span><span class="lit">34</span><span class="pln">	                    </span><span class="pun">{</span><span class="pln">
</span><span class="lit">35</span><span class="pln">	                        freq</span><span class="pun">[</span><span class="pln">t</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">++</span><span class="pln">freq</span><span class="pun">[</span><span class="pln">t</span><span class="pun">];</span><span class="pln">
</span><span class="lit">36</span><span class="pln">	                    </span><span class="pun">}</span><span class="pln">
</span><span class="lit">37</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">38</span><span class="pln">	            </span><span class="pun">}</span><span class="pln">
</span><span class="lit">39</span><span class="pln">	
</span><span class="lit">40</span><span class="pln">	            grdLettersHistogram</span><span class="pun">.</span><span class="typ">Children</span><span class="pun">.</span><span class="typ">Clear</span><span class="pun">();</span><span class="pln">
</span><span class="lit">41</span><span class="pln">	
</span><span class="lit">42</span><span class="pln">	            </span><span class="com">//find the max letter frequency.</span><span class="pln">
</span><span class="lit">43</span><span class="pln">	            foreach</span><span class="pun">(</span><span class="pln">var v in freq</span><span class="pun">.</span><span class="typ">Values</span><span class="pun">)</span><span class="pln">
</span><span class="lit">44</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">45</span><span class="pln">	                </span><span class="kwd">if</span><span class="pun">(</span><span class="pln">maxFreq</span><span class="pun">&lt;</span><span class="pln"> v</span><span class="pun">)</span><span class="pln">
</span><span class="lit">46</span><span class="pln">	                </span><span class="pun">{</span><span class="pln">
</span><span class="lit">47</span><span class="pln">	                    maxFreq </span><span class="pun">=</span><span class="pln"> v</span><span class="pun">;</span><span class="pln">
</span><span class="lit">48</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">49</span><span class="pln">	            </span><span class="pun">}</span><span class="pln">
</span><span class="lit">50</span><span class="pln">	
</span><span class="lit">51</span><span class="pln">	            </span><span class="com">//calculate measurment unit will apply on bars.</span><span class="pln">
</span><span class="lit">52</span><span class="pln">	            </span><span class="kwd">double</span><span class="pln"> measureUnit </span><span class="pun">=</span><span class="pln"> grdLettersHistogram</span><span class="pun">.</span><span class="typ">Height</span><span class="pln"> </span><span class="pun">/</span><span class="pln"> maxFreq</span><span class="pun">;</span><span class="pln">
</span><span class="lit">53</span><span class="pln">	
</span><span class="lit">54</span><span class="pln">	            foreach </span><span class="pun">(</span><span class="pln">var c in freq</span><span class="pun">.</span><span class="typ">Keys</span><span class="pun">)</span><span class="pln">
</span><span class="lit">55</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">56</span><span class="pln">	                var boxView </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">BoxView</span><span class="pln">
</span><span class="lit">57</span><span class="pln">	                </span><span class="pun">{</span><span class="pln">
</span><span class="lit">58</span><span class="pln">	                    </span><span class="typ">HeightRequest</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> measureUnit </span><span class="pun">*</span><span class="pln"> freq</span><span class="pun">[</span><span class="pln">c</span><span class="pun">],</span><span class="pln">
</span><span class="lit">59</span><span class="pln">	                    </span><span class="typ">BackgroundColor</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Color</span><span class="pun">.</span><span class="typ">Accent</span><span class="pun">,</span><span class="pln">
</span><span class="lit">60</span><span class="pln">	                    </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">End</span><span class="pun">,</span><span class="pln">
</span><span class="lit">61</span><span class="pln">	                    </span><span class="typ">StyleId</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> string</span><span class="pun">.</span><span class="typ">Format</span><span class="pun">(</span><span class="str">"المحرف '{0}' له التكرار {1}"</span><span class="pun">,</span><span class="pln"> c</span><span class="pun">,</span><span class="pln"> freq</span><span class="pun">[</span><span class="pln">c</span><span class="pun">]),</span><span class="pln">
</span><span class="lit">62</span><span class="pln">	                </span><span class="pun">};</span><span class="pln">
</span><span class="lit">63</span><span class="pln">	
</span><span class="lit">64</span><span class="pln">	                boxView</span><span class="pun">.</span><span class="typ">GestureRecognizers</span><span class="pun">.</span><span class="typ">Add</span><span class="pun">(</span><span class="pln">tapGesture</span><span class="pun">);</span><span class="pln">
</span><span class="lit">65</span><span class="pln">	
</span><span class="lit">66</span><span class="pln">	                bars</span><span class="pun">.</span><span class="typ">Add</span><span class="pun">(</span><span class="pln">boxView</span><span class="pun">);</span><span class="pln">   
</span><span class="lit">67</span><span class="pln">	            </span><span class="pun">}</span><span class="pln">
</span><span class="lit">68</span><span class="pln">	
</span><span class="lit">69</span><span class="pln">	            grdLettersHistogram</span><span class="pun">.</span><span class="typ">Children</span><span class="pun">.</span><span class="typ">AddHorizontal</span><span class="pun">(</span><span class="pln">bars</span><span class="pun">);</span><span class="pln">
</span><span class="lit">70</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">71</span><span class="pln">	
</span><span class="lit">72</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> </span><span class="typ">TapGesture_Tapped</span><span class="pun">(</span><span class="pln">object sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">EventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
</span><span class="lit">73</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">74</span><span class="pln">	            </span><span class="typ">DisplayAlert</span><span class="pun">(</span><span class="str">"رسالة"</span><span class="pun">,</span><span class="pln"> </span><span class="pun">((</span><span class="typ">BoxView</span><span class="pun">)</span><span class="pln">sender</span><span class="pun">).</span><span class="typ">StyleId</span><span class="pun">,</span><span class="pln"> </span><span class="str">"اغلاق"</span><span class="pun">);</span><span class="pln">
</span><span class="lit">75</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">76</span><span class="pln">	    </span><span class="pun">}</span><span class="pln">
</span><span class="lit">77</span><span class="pln">	</span><span class="pun">}</span></pre>

<p>
	تكمن معظم الشيفرة البرمجيّة في هذا الملف ضمن معالج حدث نقر زر حساب التكرارات btnCalculate_Clicked الذي يمتد من السطر 14 حتى السطر 70. في البداية تمّ تعريف المتغيّر freq في السطر 16 ليكون من النوع العمومي Dictionary<char int="">، وهو عبارة عن بنية معطيات مشهورة تُعرف بالقاموس dictionary. سيحتوي هذا المتغيّر على جميع الأحرف المختلفة الموجودة ضمن النص المُدخَل بالإضافة إلى عدد مرّات التكرار لكلّ حرف. أمّا في السطر 17 فقد تمّ تعريف المتغيّر bars وهو من نوع القائمة List<view>. سيحتوي هذا المتغيّر على جميع عناصر BoxView التي سننشئها لاحقًا من الشيفرة البرمجيّة. بعد ذلك نعرّف المتغيّر tapGesture وهو من النوع TapGestureRecognizer. سنتمكّن من خلال هذا المتغيّر أن نُكسِب لأي عنصر BoxView إمكانيّة أن ينقر عليه المستخدم ليعرض عند ذلك الرسالة التي تحدثنا عنها مسبقًا. أمّا في السطر 19 فقد عرّفنا المتغيّر maxFreq الذي سيحوي التكرار الأكبر من بين الحروف المختلفة.</view></char>,&gt;
</p>

<blockquote>
	<blockquote class="ipsQuote" data-ipsquote="">
		<div class="ipsQuote_citation">
			Quote
		</div>

		<div class="ipsQuote_contents ipsClearfix">
			<p>
				بنية معطيات القاموس dictionary بسيطة من حيث المبدأ. حيث يتطلّب كل عنصر ضمن القاموس وجود مفتاح key وقيمة value لهذا المفتاح. جميع العناصر الموجودة ضمن القاموس الواحد يجب أن تكون مفاتيحها مختلفة عن بعضها. أمّا قيم تلك المفاتيح فلا مشكلة في أن تتماثل. بالنسبة لتطبيقنا هذا، اخترت النوع العمومي Dictionary<char int=""> وهذا يعني أنّ أيّ عنصر موجود في هذا القاموس سيكون مفتاحه من النوع char (المحرف الموجود في النص المُدخَل)، وقيمة هذا المفتاح ستكون من النوع int (قيمة تمثّل تكرار هذا المحرف ضمن النص).</char>,&gt;
			</p>
		</div>
	</blockquote>

	<p>
		<char int=""></char>,&gt;
	</p>
</blockquote>

<blockquote>
	<blockquote class="ipsQuote" data-ipsquote="">
		<div class="ipsQuote_citation">
			Quote
		</div>

		<div class="ipsQuote_contents ipsClearfix">
			<p>
				يمكن إكساب أيّ عنصر رسومي يرث من لصنف View إمكانيّة الاستجابة لحدث النقر عليه Tap من قِبَل المستخدم. يُعرّف الصنف View الخاصيّة GestureRecognizers وهي مجموعة عناصرها عبارة عن كائنات من الصنف GestureRecognizer. الآن ولكي يستطيع العنصر الرسومي الاستجابة لحدث النقر ينبغي إضافة كائن واحد على الأقل للخاصيّة GestureRecognizers والذي سيكون من الصنف TapGestureRecognizer وهو يرث بطبيعة الحال من الصنف GestureRecognizer. يمكن من خلال هذا الكائن ربط معالج حدث للنقر يتمّ استدعائه عندما ينقر المستخدم على ذلك العنصر الرسومي.
			</p>
		</div>
	</blockquote>

	<p>
		 
	</p>
</blockquote>

<p>
	نعمل في السطر 21 على إضافة معالج الحدث TapGesture_Tapped (مصرّح عنه في الأسطر من 72 حتى 75) لحدث النقر Tapped للكائن tapGesture. بعد أن نحصل على دخل المستخدم ونضعه ضمن المتغيّر s في السطر 23، سندخل حلقة foreach التكراريّة بحيث نقرأ محتويات النص s محرفًا تلو الآخر، ونختبر كون هذا المحرف هو حرف أو رقم في السطر 27 لأنّنا لا نريد قبول الفراغات على سبيل المثال. في السطر 29 سنختبر في حال كان هذا المحرف موجود فعلًا ضمن القاموس freq من قبل أم لا وذلك عن طريق التابع ContainsKey. فإن كان غير موجود من قبل، سنعمل على إضافته في السطر 31، أمّا إذا كان موجود من قبل فسنعمل على إضافة التكرار الخاص به بمقدار واحد وذلك في السطر 35:
</p>

<pre>
<code>
</code></pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_7335_11">
<span class="pln">freq</span><span class="pun">[</span><span class="pln">t</span><span class="pun">]</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">++</span><span class="pln">freq</span><span class="pun">[</span><span class="pln">t</span><span class="pun">];</span></pre>

<p>
	لاحظ أنّ التعبير freq[t] يسمح لنا بالوصول إلى قيمة المفتاح t الموجودة في القاموس freq. بعد ذلك سنمسح محتويات مخطّط الشبكة في السطر 40، ثم سننتقل إلى حلقة foreach أخرى (الأسطر من 43 حتى 49) تسمح لنا بحساب التكرار الأكبر من بين المحارف الموجودة ضمن القاموس freq. في السطر 52 سنقوم بإجراء عمليّة حسابيّة بسيطة، حيث سنعمل على حساب واحدة القياس الخاصّة بالأعمدة (عناصر BoxView)، وبشكل أدق، واحدة القياس الخاصّة بارتفاع كل عنصر BoxView. وذلك من خلال تقسيم ارتفاع مخطّط الشبكة grdLettersHistogram على التكرار الأكبر maxFreq الذي حسبناه قبل قليل. سنخزّن واحدة القياس هذه ضمن المتغيّر measureUnit كما هو واضح.
</p>

<p>
	سندخل أخيرًا ضمن حلقة foreach أخرى (الأسطر من 54 حتى 67) وظيفتها إنشاء عناصر BoxView كلّ منها يمثّل محرف مختلف موجود ضمن القاموس freq، وبارتفاع يتناسب مع تكرار هذا المحرف ضمن النص المُدخل. ستعمل هذه الحلقة على إضافة كل عنصر BoxView إلى القائمة bars (السطر 66). تجدر الملاحظة أنّنا في السطر 61 قد أسندنا نصًّا توضيحيًّا إلى الخاصيّة StyleId لعنصر BoxView. يحتوي هذا النص على الحرف وعلى تكراره ضمن النص المُدخَل. في الواقع يمكننا دومًا استخدام الخاصيّة StyleId مع أيّ عنصر يرث من الصنف View لمثل هذه الأغراض.
</p>

<p>
	في النهاية سنعمل على إضافة الأعمدة (عناصر BoxView) الموجودة ضمن القائمة bars دفعةً واحدةً إلى مخطّط الشبكة من خلال العبارة التالي الموجودة في السطر 69:
</p>

<pre>
<code>
</code></pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_7335_13">
<span class="pln">grdLettersHistogram</span><span class="pun">.</span><span class="typ">Children</span><span class="pun">.</span><span class="typ">AddHorizontal</span><span class="pun">(</span><span class="pln">bars</span><span class="pun">);</span></pre>

<p>
	يعمل التابع AddHorizontal من الخاصّية Children لمخطّط الشبكة على إضافة عنصر أو مجموعة من العناصر (كما في مثالنا) إلى مخطّط الشبكة على أن تكون على نفس السطر (أفقيًّا horizontal) وذلك دفعةً واحدةً. يوجد في الواقع تابع آخر مماثل لهذا التابع وهو التابع AddVertical، ولكنّه يضيف العناصر على نفس العمود. من الممكن تحديد السطر أو العمود المراد الإضافة إليه عن طريق توابع ساكنة static مثل Grid.SetRow و Grid.SetColumn ولكنّنا لن نحتاج إلى مثل هذه التوابع لأنّنا سنترك الإعدادات الافتراضيّة كما هي. بقي أن نتحدّث عن معالج حدث النقر TapGesture_Tapped. في الحقيقة الشيء الوحيد الذي يفعله هذا الحدث هو إظهار رسالة تنبيه للمستخدم (السطر 74) عند نقره لأحد الأعمدة ضمن المخطّط (عنصر BoxView) تحتوي هذه الرسالة على النص الذي مرّرناه مسبقًا لعنصر BoxView ضمن الخاصيّة StyleId له.<br>
	انتقل الآن إلى الملف App.cs واحرص على أن تكون بانية الصنف App على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_7335_15">
<span class="kwd">public</span><span class="pln"> </span><span class="typ">App</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="com">// The root page of your application</span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">GridBarChartPage</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	نفّذ البرنامج وأجر بعض الإدخالات النصيّة، وراقب النتائج. حاول نقر بعض الأعمدة لتظهر لك رسالة المعلومات حوله.
</p>

<h3>
	الخلاصة
</h3>

<p>
	تناولنا في هذا الدرس تطبيقًا عمليًّا مفيدًا في حساب التكرارات للأحرف ضمن نص ما، ومن ثمّ عرضها بشكل مخطّط تكراري histogram ضمن مخطّط الشبكة. يوضّح لنا هذا التطبيق مدى القوّة والمرونة التي من الممكن الحصول عليها من استخدام مخطّط الشبكة، هذا بالإضافة إلى إمكانيّة المزج بين استخدام مخطّط الشبكة ومخطّط المكدّس بكلّ سهولة ويسر. هناك الكثير من التطبيقات التي يمكن استخدام مخطّط الشبكة معها. وسنعمل في الدروس القادمة على استخدامه بشكل متكرّر في التطبيقات التي نطوّرها.
</p>
]]></description><guid isPermaLink="false">461</guid><pubDate>Sun, 08 Jan 2017 21:00:00 +0000</pubDate></item><item><title>&#x62A;&#x637;&#x628;&#x64A;&#x642; &#x644;&#x648;&#x62D;&#x629; &#x627;&#x644;&#x623;&#x631;&#x642;&#x627;&#x645; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x645;&#x62E;&#x637;&#x651;&#x637; &#x627;&#x644;&#x634;&#x628;&#x643;&#x629;</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D9%84%D9%88%D8%AD%D8%A9-%D8%A7%D9%84%D8%A3%D8%B1%D9%82%D8%A7%D9%85-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%85%D8%AE%D8%B7%D9%91%D8%B7-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A9-r460/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.aa8978cc64fa93b7cb9964f42ff3b3bf.png" /></p>

<p>
	سنتناول في هذا الدرس من <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/" rel="">سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms</a> تطبيقًا عمليًّا مفيدًا حول التعامل مع مخطّط الشبكة Grid Layout وهو عبارة عن تطبيق لوحة أرقام يمكن تطويرها لاحقًا لتصبح مثلًا تطبيق آلة حاسبة متعدّد الوظائف. اطلعنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%85%D8%AE%D8%B7%D9%91%D8%B7-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A9-grid-%D9%84%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D9%85%D8%AA%D9%82%D8%AF%D9%91%D9%85%D8%A9-r459/" rel="">الدرس السابق</a> على مخطّط الشبكة وتعلمنا بعض المبادئ الأساسيّة لاستخدامه. يمكنك مراجعة ذلك الدرس، أو من الممكن أن تبدأ مباشرةً في هذا الدرس.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22573" data-unique="mp5lmnqeb" src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.158bd57225e0656d2dd7e2e9a8eec7e5.png"></p>

<h3>
	فكرة التطبيق
</h3>

<p>
	سنعمل على كتابة تطبيق لوحة أرقام بسيط، حيث ستظهر أزرار تحمل الأرقام من 0 حتى 9 بالإضافة إلى زر الفاصلة العشرية، مع وجود زر لإلغاء آخر رقم تمّت كتابته. ستبدو واجهة التطبيق كما في الشكل التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22572" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.png.53822b46c2695846b4daf13426347af1.png" rel=""><img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22572" data-unique="mfmch47ls" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.thumb.png.ca89234d884e6ed63c864cff69104220.png"></a>
</p>

<p>
	عندما ينقر المستخدم على أزرار الأرقام ستظهر هذه الأرقام تباعًا بجوار بعضها بالترتيب. أمّا عندما ينقر زر الإلغاء فسيتم إلغاء آخر رقم تمّ نقره. لنستعرض الشيفرة البرمجيّة لهذا التطبيق في الفقرة التالية.
</p>

<h3>
	الشيفرة البرمجيّة للتطبيق
</h3>

<p>
	ابدأ بإنشاء مشروع جديد من النوع Blank App (Xamarin.Forms Portable) وسمّه KeypadGrid، ثم أبق فقط على المشروعين KeypadGrid (Portable) و KeypadGrid.Droid كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-visual-studio-2015-community-%D9%88%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-xamarin-%D9%84%D9%84%D8%B9%D9%85%D9%84-r373/" rel="">هذا الدرس</a>. بعد ذلك سنضيف صفحة محتوى تعتمد على رُماز XAML كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xaml-r453/" rel="">هذا الدرس</a> سنسمّها KeypadGridPage. احرص على أن تكون محتويات هذه الصفحة على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3009_7">
<span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
</span><span class="pun">&lt;</span><span class="typ">ContentPage</span><span class="pln"> xmlns</span><span class="pun">=</span><span class="str">"http://xamarin.com/schemas/2014/forms"</span><span class="pln">
             xmlns</span><span class="pun">:</span><span class="pln">x</span><span class="pun">=</span><span class="str">"http://schemas.microsoft.com/winfx/2009/xaml"</span><span class="pln">
             x</span><span class="pun">:</span><span class="typ">Class</span><span class="pun">=</span><span class="str">"KeypadGrid.KeypadGridPage"</span><span class="pun">&gt;</span><span class="pln">

  </span><span class="pun">&lt;</span><span class="typ">Grid</span><span class="pln"> </span><span class="typ">RowSpacing</span><span class="pun">=</span><span class="str">"2"</span><span class="pln">
        </span><span class="typ">ColumnSpacing</span><span class="pun">=</span><span class="str">"2"</span><span class="pln">
        </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln">
        </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln">
        </span><span class="typ">WidthRequest</span><span class="pun">=</span><span class="str">"180"</span><span class="pln">
        </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">HeightRequest</span><span class="pun">=</span><span class="str">"300"</span><span class="pun">&gt;</span><span class="pln">

    </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"displayLabel"</span><span class="pln">
           </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"0"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"0"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">ColumnSpan</span><span class="pun">=</span><span class="str">"2"</span><span class="pln">
           </span><span class="typ">FontSize</span><span class="pun">=</span><span class="str">"Large"</span><span class="pln">
           </span><span class="typ">LineBreakMode</span><span class="pun">=</span><span class="str">"HeadTruncation"</span><span class="pln">
           </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln">
           </span><span class="typ">HorizontalTextAlignment</span><span class="pun">=</span><span class="str">"End"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">

    </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"btnBackspace"</span><span class="pln">
            </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"⇦"</span><span class="pln">
            </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"0"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"2"</span><span class="pln">
            </span><span class="typ">IsEnabled</span><span class="pun">=</span><span class="str">"False"</span><span class="pln">
            </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"btnBackspace_Clicked"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">

    </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"7"</span><span class="pln"> </span><span class="typ">StyleId</span><span class="pun">=</span><span class="str">"7"</span><span class="pln">
            </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"1"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"0"</span><span class="pln">
            </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"OnDigitButtonClicked"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">

    </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"8"</span><span class="pln"> </span><span class="typ">StyleId</span><span class="pun">=</span><span class="str">"8"</span><span class="pln">
            </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"1"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"1"</span><span class="pln">
            </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"OnDigitButtonClicked"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">

    </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"9"</span><span class="pln"> </span><span class="typ">StyleId</span><span class="pun">=</span><span class="str">"9"</span><span class="pln">
            </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"1"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"2"</span><span class="pln">
            </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"OnDigitButtonClicked"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">

    </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"4"</span><span class="pln"> </span><span class="typ">StyleId</span><span class="pun">=</span><span class="str">"4"</span><span class="pln">
            </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"2"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"0"</span><span class="pln">
            </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"OnDigitButtonClicked"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">

    </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"5"</span><span class="pln"> </span><span class="typ">StyleId</span><span class="pun">=</span><span class="str">"5"</span><span class="pln">
            </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"2"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"1"</span><span class="pln">
            </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"OnDigitButtonClicked"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">

    </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"6"</span><span class="pln"> </span><span class="typ">StyleId</span><span class="pun">=</span><span class="str">"6"</span><span class="pln">
            </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"2"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"2"</span><span class="pln">
            </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"OnDigitButtonClicked"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">

    </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"1"</span><span class="pln"> </span><span class="typ">StyleId</span><span class="pun">=</span><span class="str">"1"</span><span class="pln">
            </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"3"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"0"</span><span class="pln">
            </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"OnDigitButtonClicked"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">

    </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"2"</span><span class="pln"> </span><span class="typ">StyleId</span><span class="pun">=</span><span class="str">"2"</span><span class="pln">
            </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"3"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"1"</span><span class="pln">
            </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"OnDigitButtonClicked"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">

    </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"3"</span><span class="pln"> </span><span class="typ">StyleId</span><span class="pun">=</span><span class="str">"3"</span><span class="pln">
            </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"3"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"2"</span><span class="pln">
            </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"OnDigitButtonClicked"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">

    </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"0"</span><span class="pln"> </span><span class="typ">StyleId</span><span class="pun">=</span><span class="str">"0"</span><span class="pln">
            </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"4"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"0"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">ColumnSpan</span><span class="pun">=</span><span class="str">"2"</span><span class="pln">
            </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"OnDigitButtonClicked"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">

    </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"."</span><span class="pln"> </span><span class="typ">StyleId</span><span class="pun">=</span><span class="str">"."</span><span class="pln">
            </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"4"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"2"</span><span class="pln">
            </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"OnDigitButtonClicked"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
  </span><span class="pun">&lt;/</span><span class="typ">Grid</span><span class="pun">&gt;</span><span class="pln">
</span><span class="pun">&lt;/</span><span class="typ">ContentPage</span><span class="pun">&gt;</span></pre>

<p>
	من السهل فهم الرُماز السابق مع بعض الملاحظات البسيطة:
</p>

<ol>
<li>
		في البداية لاحظ أنّنا قد أسندنا خصائص إضافيّة لمخطّط الشبكة مثل تباعد الأسطر RowSpacing وتباعد الأعمدة ColumnSpacing وذلك بهدف جعل الأزرار غير ملتصقة ببعضها البعض. كما أسندنا الخيارات الرأسية VerticalOptions والأفقية HorizontalOptions لكي تحمل كل منهما القيمة Center بهدف جعل الشبكة تظهر في مركز الشاشة.
	</li>
	<li>
		لم نستخدم في هذا التطبيق الخاصيّتين RowDefinitions و ColumnDefinitions اللّتان تحدثنا عنهما في<a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%85%D8%AE%D8%B7%D9%91%D8%B7-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A9-grid-%D9%84%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D9%85%D8%AA%D9%82%D8%AF%D9%91%D9%85%D8%A9-r459/" rel=""> الدرس السابق</a>. إذ أنّه من الممكن اعتماد الإعدادات الافتراضيّة الخاصّة بهما، والبدء مباشرة بإضافة العناصر المرئيّة، حيث يمكن من خلال هذه العناصر تحديد السطر والعمود للخليّة التي نودّ وضع العنصر ضمنها كما سنرى بعد قليل.
	</li>
	<li>
		اللصيقة الوحيدة الموجودة في هذا التطبيق تُستَخدم لعرض الرقم الذي أدخله المستخدم. لاحظ أنّنا نريد عرضها في الخلية المحدّدة بالسطر الأوّل والعمود الأوّل، بالإضافة إلى الانتشار لعمودين متتاليين بسبب وجود الخصائص التالية: Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2". كما توجد خاصية أخرى ملفتة للنظر لهذه اللصيقة، وهي الخاصيّة LineBreakMode والتي تحمل القيمة HeadTruncation. هذه القيمة مفيدة في مثل هذه التطبيقات حيث يؤدّي وجودها إلى اقتطاع النص الذي تمّ إدخاله أولًا في حال لم تتسع اللصيقة لعرض كامل النص (يمكنك تجريب ذلك بنفسك فيما بعد).
	</li>
	<li>
		الزر الأوّل الذي يأتي بعد تعريف اللصيقة هو زر إلغاء آخر رقم مُدخل، واسمه btnBackspace، وهو مرتبط مع معالج حدث النقر btnBackspace_Clicked الموجود ضمن ملف الشيفرة البرمجيّة كما سنرى بعد قليل.
	</li>
	<li>
		بالنسبة لبقيّة الأزرار فأمرها بسيط. فكلّ زر نُعيّن له الخاصيّة StyleId للاحتفاظ بالقيمة النصيّة الموافقة للرقم الذي يحمله، فمثًلا الزر الذي يُعبّر عن الرقم 9 ستكون قيمة StyleId له تساوي "9"، وهكذا. الجدير بالملاحظة هنا أننا قد ربطنا جميع هذه الأزرار بنفس معالج الحدث وهو OnDigitButtonClicked، وهو أمر جائز تمامًا، بل ومن المفضّل القيام به. سنطّلع على هذا المعالج بعد قليل.
	</li>
</ol>
<p>
	انتقل الآن إلى ملف الشيفرة البرمجيّة KeypadGridPage.xaml.cs الموافق لملف الرُماز السابق، واحرص على أن تكون محتوياته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3009_9">
<span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">KeypadGrid</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">public</span><span class="pln"> partial </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">KeypadGridPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">KeypadGridPage</span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">InitializeComponent</span><span class="pun">();</span><span class="pln">

            btnBackspace</span><span class="pun">.</span><span class="typ">IsEnabled</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> displayLabel</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">!=</span><span class="pln"> null </span><span class="pun">&amp;&amp;</span><span class="pln">
                                        displayLabel</span><span class="pun">.</span><span class="typ">Text</span><span class="pun">.</span><span class="typ">Length</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="kwd">void</span><span class="pln"> </span><span class="typ">OnDigitButtonClicked</span><span class="pun">(</span><span class="pln">object sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">EventArgs</span><span class="pln"> args</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">Button</span><span class="pln"> button </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">Button</span><span class="pun">)</span><span class="pln">sender</span><span class="pun">;</span><span class="pln">
            displayLabel</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">string</span><span class="pun">)</span><span class="pln">button</span><span class="pun">.</span><span class="typ">StyleId</span><span class="pun">;</span><span class="pln">
            btnBackspace</span><span class="pun">.</span><span class="typ">IsEnabled</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">true</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="kwd">void</span><span class="pln"> btnBackspace_Clicked</span><span class="pun">(</span><span class="pln">object sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">EventArgs</span><span class="pln"> args</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            string text </span><span class="pun">=</span><span class="pln"> displayLabel</span><span class="pun">.</span><span class="typ">Text</span><span class="pun">;</span><span class="pln">
            displayLabel</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> text</span><span class="pun">.</span><span class="typ">Substring</span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> text</span><span class="pun">.</span><span class="typ">Length</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="lit">1</span><span class="pun">);</span><span class="pln">
            btnBackspace</span><span class="pun">.</span><span class="typ">IsEnabled</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> displayLabel</span><span class="pun">.</span><span class="typ">Text</span><span class="pun">.</span><span class="typ">Length</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	الشيفرة السابقة بسيطة للغاية، فالصنف KeypadGridPage يحتوي بشكل أساسي على معالجيّ لحدث النقر:
</p>

<ul>
<li>
		المعالج الأوّل هو OnDigitButtonClicked وهو يُستدعى عندما ينقر المستخدم على أحد أزرار الأرقام بالإضافة إلى زر الفاصلة العشرية. وفي هذا المعالج يتم إضافة الرقم الذي نقره المستخدم توًّا إلى محتويات اللصيقة التي تعرض كامل الرقم المُدخَل. نبدأ أولًا بعمليّة تحويل cast للحصول على الزر الذي سبّب استدعاء هذا المعالج:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3009_11">
<span class="typ">Button</span><span class="pln"> button </span><span class="pun">=</span><span class="pln"> </span><span class="pun">(</span><span class="typ">Button</span><span class="pun">)</span><span class="pln">sender</span><span class="pun">;</span></pre>

<p>
	ثمّ استخلاص قيمة الخاصيّة StyleId له وضمّها إلى اللصيقة displayLabel:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3009_13">
<span class="pln">displayLabel</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">string</span><span class="pun">)</span><span class="pln">button</span><span class="pun">.</span><span class="typ">StyleId</span><span class="pun">;</span></pre>

<p>
	ومن ثمّ تفعيل زر إلغاء آخر رقم بسبب أنّه قد أصبح هناك رقم واحد على الأقل بشكل مؤكّد ضمن اللصيقة.
</p>

<ul>
<li>
		أمّا المعالج الثاني فهو btnBackspace_Clicked وهو يُستَدعى عندما يتم النقر على زر إلغاء آخر رقم مُدخَل. الشيفرة البرمجيّة ضمن هذا المعالج بسيطة، فهي تعمل أولًا على الحصول على النص الموجود أصلًا ضمن اللصيقة displayLabel وتضعه ضمن المتغيّر النصي text:
	</li>
</ul>
<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3009_15">
<span class="pln">string text </span><span class="pun">=</span><span class="pln"> displayLabel</span><span class="pun">.</span><span class="typ">Text</span><span class="pun">;</span></pre>

<p>
	ومن ثمّ تقوم بحذف آخر رقم عن طريق التابع Substring من المتغيّر text ومن ثمّ إعادة إسناد النص الناتج إلى الخاصيّة Text للصيقة displayLabel.
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3009_17">
<span class="pln">displayLabel</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> text</span><span class="pun">.</span><span class="typ">Substring</span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="pln"> text</span><span class="pun">.</span><span class="typ">Length</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> </span><span class="lit">1</span><span class="pun">);</span></pre>

<p>
	نقوم في نهاية المطاف بتفعيل زر إلغاء آخر رقم مُدخل أو تعمل على إلغاء تفعيله باستخدام طريقة جميلة تعتمد على تقييم التعبير المنطقي الموجود على يمين عامل الإسناد (=):
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_3009_19">
<span class="pln">btnBackspace</span><span class="pun">.</span><span class="typ">IsEnabled</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> displayLabel</span><span class="pun">.</span><span class="typ">Text</span><span class="pun">.</span><span class="typ">Length</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span></pre>

<p>
	فإذا كانت اللصيقة تحتوي على رقم واحد على الأقل سيكون التعبير displayLabel.Text.Length &gt; 0 مساويًا للقيمة true وبالتالي يتم تفعيل الزر. وإلّا سيعطي هذا التعبير القيمة false ويتم إلغاء تفعيله. حاول إجراء بعض التجارب على هذا التطبيق، ثمّ فكّر كيف يمكن تعديله لإنشاء تطبيق آلة حاسبة فعليّ، يمكنه دعم العمليّات الحسابيّة الأساسيّة الأربع على سبيل المثال.
</p>

<h3>
	الخلاصة
</h3>

<p>
	استفدنا من التطبيق الذي تناولناه في هذا الدرس، في كيفيّة استخدام مخطّط الشبكة بشكل عمليّ بغية الاستفادة من مزايا التموضع الدقيقة نسبيًّا التي يوفّرها للعناصر المرئيّة التي تُوضَع ضمنه. سنتابع العمل في الدرس التالي لنبني تطبيقًا عمليًّا مفيدًا أخرًا يستفيد أيضًا من المزايا الرائعة لمخطّط الشبكة في إنشاء مخطّط تكراري إحصائي يشبه مخطّطات الأعمدة التي من الممكن الحصول عليها من تطبيقات مكتبيّة مثل Microsoft Excel مثلًا.
</p>
]]></description><guid isPermaLink="false">460</guid><pubDate>Sat, 31 Dec 2016 21:00:00 +0000</pubDate></item><item><title>&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; &#x645;&#x62E;&#x637;&#x651;&#x637; &#x627;&#x644;&#x634;&#x628;&#x643;&#x629; Grid &#x644;&#x628;&#x646;&#x627;&#x621; &#x648;&#x627;&#x62C;&#x647;&#x627;&#x62A; &#x645;&#x62A;&#x642;&#x62F;&#x651;&#x645;&#x629;</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-%D9%85%D8%AE%D8%B7%D9%91%D8%B7-%D8%A7%D9%84%D8%B4%D8%A8%D9%83%D8%A9-grid-%D9%84%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D9%85%D8%AA%D9%82%D8%AF%D9%91%D9%85%D8%A9-r459/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.1634dfd317f0949ee4516e0acfd7310c.png" /></p>

<p>
	يُعتبر مخطّط الشبكة Grid Layout من المخطّطات الهامّة والضروريّة في تصميم واجهات المستخدم بالنسبة لتطبيقات الأجهزة المحمولة. فيمكن من خلال هذا المخطّط التحكّم على نحو دقيق نسبيًّا بمواقع جميع العناصر المرئيّة الموجودة في الواجهة، وذلك بخلاف مخطّط المكدّس Stack Layout الذي تناولناه منذ بداية <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/" rel="">هذه السلسلة</a> حتى الآن. حيث كان من الصعوبة التحكّم بمواقع العناصر المرئيّة بشكل دقيق، وخاصةً فيما يتعلّق بالمحاذاة. في الحقيقة يمكن استخدام كل من هذين المخطّطين معًا في الواجهة الواحدة.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22571" data-unique="jzj7bvtf8" src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.715efc4cffd893a0697a46670512f030.png"></p>

<p>
	سنبدأ في هذا الدرس بالتعرّف على مفهوم هذا المخطّط وطريقة استخدامه. ثمّ نُتْبع هذا الدرس بدرسين آخرين يتناولان تطبيقين عمليين لاكتساب الخبرة اللازمة للعمل مع مخطّط الشبكة بسهولة ويسر أكبر.
</p>

<h3>
	ما هو مخطّط الشبكة؟
</h3>

<p>
	مخطّط الشبكة هو عبارة عن بنية تشبه الجدول من الناحية الشكلية ولكنّها تختلف عنه من الناحية العمليّة. فمخطّط الشبكة قد صُمّم بالأساس ليكون وسيلة لتنظيم العناصر المرئيّة ضمن واجهة المستخدم. أمّا الجدول فهو بنية وظيفتها احتواء بيانات يمكن عرضها للمستخدم.
</p>

<p>
	سيكون أغلب تعاملنا مع مخطّط الشبكة من خلال رُماز XAML. إذ أنّه من الممكن أيضًا استخدام الأسلوب البرمجيّ في التعامل معه. ولكن التعامل معه من خلال الرُماز أفضل من ناحية الاستخدام والتنظيم. يمكن تعريف مخطّط الشبكة من خلال الوسم <grid>. حيث من الممكن تعيين الأسطر rows والأعمدة columns التي يتألّف منها هذا المخطّط من خلال الخاصيّتين RowDefinitions التي تحتوي على تعاريف الأسطر وColumnDefinitions التي تحتوي على تعاريف الأعمدة. يُدعى مكان تقاطع السطر والعمود بالخليّة Cell. الخاصيّة RowDefinitions هي عبارة عن مجموعة collection من العناصر التي يكون كلّ منها من النوع RowDefinition وتعني تعريف سطر. يمكن من خلال هذا النوع ضبط العديد من خصائص هذا السطر. سنهتم حاليًّا بالخاصيّة Height التي تُعبّر عن ارتفاع السطر. من الممكن تعيين قيمة هذا الارتفاع بثلاثة أنواع من المقاييس:</grid></p>

<ul>
<li>
		النوع الأوّل هو القيمة العدديّة المباشرة وهي قيمة لا تتعلّق لا تتعلّق بالشاشة device-independent units (<a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D9%82%D9%8A%D8%A7%D8%B3%D8%A7%D8%AA-%D8%B9%D9%84%D9%89-%D8%A7%D9%84%D8%B4%D8%A7%D8%B4%D8%A9-%D9%81%D9%8A-xamarin-r413/" rel="">انظر هذا الدرس</a>).
	</li>
	<li>
		النوع الثاني هو الكلمة Auto، والتي تعني أنّه ينبغي أن يكون ارتفاع السطر مساويًا لأعلى ارتفاع عنصر مرئي موجود ضمنه.
	</li>
	<li>
		النوع الثالث هو النوع النسبيّ، ويُعبّر عنه رمز النجمة (*)، حيث يكون ارتفاع السطر في هذه الحالة بحيث يشغل باقي الارتفاع المتاح لمخطّط الشبكة ككل. ومن الممكن أن يتعلّق أيضًا بسطر آخر له نفس هذا النوع من القياس، وسنوضّح ذلك في مثال تطبيقي بعد قليل.
	</li>
</ul>
<p>
	أمّا بالنسبة للخاصيّة ColumnDefinitions هي عبارة عن مجموعة collection من العناصر التي يكون كلّ منها من النوع ColumnDefinition وتعني تعريف عمود. يمكن من خلال هذا النوع ضبط العديد من خصائص هذا العمود. سنهتم بالخاصيّة Width منه التي تُعبّر عن عرض العمود. من الممكن تعيين قيمة هذا العرض كما هو الحال مع تعريف السطر أيضًا بثلاثة أنواع من المقاييس، تماثل من حيث المبدأ الأنواع الثلاثة السابقة من القياس للسطر:
</p>

<ul>
<li>
		النوع الأوّل هنا هو نفسه النوع الأوّل بالنسبة للسطر، وهو قيمة العدديّة المباشرة التي لا تتعلّق لا تتعلّق بالشاشة device-independent units.
	</li>
	<li>
		النوع الثاني هو الكلمة Auto، والتي تعني أنّه ينبغي أن يكون عرض العمود مساويًا لأعرض عنصر مرئي موجود ضمنه.
	</li>
	<li>
		النوع الثالث هو النوع النسبيّ، ويُعبّر عنه رمز النجمة (*) أيضًا، حيث يكون عرض العمود في هذه الحالة بحيث يشغل باقي العرض المتاح لمخطّط الشبكة ككل. ومن الممكن أن يتعلّق أيضًا بعمود آخر له نفس هذا النوع من القياس.
	</li>
</ul>
<p>
	وسنوضّح ذلك أيضًا في المثال التطبيقي الذي سنكتبه بعد قليل. من الجدير ذكره أنّه في حالة القياس النسبيّ في كلّ من حالة السطر والعمود، من الممكن وجود رقم بجوار رمز النجمة يدل على الحصّة التناسبيّة للسطر أو للعمود كما سنرى ذلك بعد قليل.
</p>

<h3>
	تطبيق عملي بسيط باستخدام مخطّط الشبكة
</h3>

<p>
	ابدأ بإنشاء مشروع جديد من النوع Blank App (Xamarin.Forms Portable) وسمّه SimpleGridApp، ثم أبق فقط على المشروعين SimpleGridApp (Portable) و SimpleGridApp.Droid كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-visual-studio-2015-community-%D9%88%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-xamarin-%D9%84%D9%84%D8%B9%D9%85%D9%84-r373/" rel="">هذا الدرس</a>. بعد ذلك سنضيف صفحة محتوى تعتمد على رُماز XAML كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xaml-r453/" rel="">هذا الدرس</a> سنسمّها SimpleGridPage. احرص على أن تكون محتويات هذه الصفحة على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_2181_7">
<span class="lit">1</span><span class="pln">	</span><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
</span><span class="lit">2</span><span class="pln">	</span><span class="pun">&lt;</span><span class="typ">ContentPage</span><span class="pln">  xmlns</span><span class="pun">=</span><span class="str">"http://xamarin.com/schemas/2014/forms"</span><span class="pln">
</span><span class="lit">3</span><span class="pln">	              xmlns</span><span class="pun">:</span><span class="pln">x</span><span class="pun">=</span><span class="str">"http://schemas.microsoft.com/winfx/2009/xaml"</span><span class="pln">
</span><span class="lit">4</span><span class="pln">	              x</span><span class="pun">:</span><span class="typ">Class</span><span class="pun">=</span><span class="str">"SimpleGridApp.SimpleGridPage"</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">5</span><span class="pln">	  </span><span class="pun">&lt;</span><span class="typ">Grid</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">6</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">RowDefinitions</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">7</span><span class="pln">	      </span><span class="pun">&lt;</span><span class="typ">RowDefinition</span><span class="pln"> </span><span class="typ">Height</span><span class="pun">=</span><span class="str">"Auto"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">8</span><span class="pln">	      </span><span class="pun">&lt;</span><span class="typ">RowDefinition</span><span class="pln"> </span><span class="typ">Height</span><span class="pun">=</span><span class="str">"100"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">9</span><span class="pln">	      </span><span class="pun">&lt;</span><span class="typ">RowDefinition</span><span class="pln"> </span><span class="typ">Height</span><span class="pun">=</span><span class="str">"2*"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">10</span><span class="pln">	      </span><span class="pun">&lt;</span><span class="typ">RowDefinition</span><span class="pln"> </span><span class="typ">Height</span><span class="pun">=</span><span class="str">"1*"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">11</span><span class="pln">	    </span><span class="pun">&lt;/</span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">RowDefinitions</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">12</span><span class="pln">	    
</span><span class="lit">13</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">ColumnDefinitions</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">14</span><span class="pln">	      </span><span class="pun">&lt;</span><span class="typ">ColumnDefinition</span><span class="pln"> </span><span class="typ">Width</span><span class="pun">=</span><span class="str">"*"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">15</span><span class="pln">	      </span><span class="pun">&lt;</span><span class="typ">ColumnDefinition</span><span class="pln"> </span><span class="typ">Width</span><span class="pun">=</span><span class="str">"*"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">16</span><span class="pln">	    </span><span class="pun">&lt;/</span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">ColumnDefinitions</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">17</span><span class="pln">	    
</span><span class="lit">18</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"مخطط الشبكة"</span><span class="pln">
</span><span class="lit">19</span><span class="pln">	      </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"0"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"0"</span><span class="pln">
</span><span class="lit">20</span><span class="pln">	      </span><span class="typ">FontSize</span><span class="pun">=</span><span class="str">"Large"</span><span class="pln">
</span><span class="lit">21</span><span class="pln">	      </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"End"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">22</span><span class="pln">	    
</span><span class="lit">23</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"تجربة مخطط الشبكة"</span><span class="pln">
</span><span class="lit">24</span><span class="pln">	      </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"0"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"1"</span><span class="pln">
</span><span class="lit">25</span><span class="pln">	      </span><span class="typ">FontSize</span><span class="pun">=</span><span class="str">"Small"</span><span class="pln">
</span><span class="lit">26</span><span class="pln">	      </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"End"</span><span class="pln">
</span><span class="lit">27</span><span class="pln">	      </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"End"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">28</span><span class="pln">	    
</span><span class="lit">29</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">Image</span><span class="pln"> </span><span class="typ">BackgroundColor</span><span class="pun">=</span><span class="str">"Gray"</span><span class="pln">
</span><span class="lit">30</span><span class="pln">	      </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"1"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"0"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">ColumnSpan</span><span class="pun">=</span><span class="str">"2"</span><span class="pln"> </span><span class="typ">Source</span><span class="pun">=</span><span class="str">"icon.png"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">31</span><span class="pln">	      
</span><span class="lit">32</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">BoxView</span><span class="pln"> </span><span class="typ">Color</span><span class="pun">=</span><span class="str">"Green"</span><span class="pln">
</span><span class="lit">33</span><span class="pln">	      </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"2"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"0"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">34</span><span class="pln">	    
</span><span class="lit">35</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">BoxView</span><span class="pln"> </span><span class="typ">Color</span><span class="pun">=</span><span class="str">"Red"</span><span class="pln">
</span><span class="lit">36</span><span class="pln">	      </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"2"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"1"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">RowSpan</span><span class="pun">=</span><span class="str">"2"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">37</span><span class="pln">	    
</span><span class="lit">38</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">BoxView</span><span class="pln"> </span><span class="typ">Color</span><span class="pun">=</span><span class="str">"Blue"</span><span class="pln">
</span><span class="lit">39</span><span class="pln">	      </span><span class="typ">Opacity</span><span class="pun">=</span><span class="str">"0.5"</span><span class="pln">
</span><span class="lit">40</span><span class="pln">	      </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Row</span><span class="pun">=</span><span class="str">"3"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">Column</span><span class="pun">=</span><span class="str">"0"</span><span class="pln"> </span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">ColumnSpan</span><span class="pun">=</span><span class="str">"2"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">41</span><span class="pln">	  </span><span class="pun">&lt;/</span><span class="typ">Grid</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">42</span><span class="pln">	</span><span class="pun">&lt;/</span><span class="typ">ContentPage</span><span class="pun">&gt;</span></pre>

<p>
	انتقل الآن إلى الملف App.cs واحرص على أن تكون بانية الصنف App على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_2181_9">
<span class="kwd">public</span><span class="pln"> </span><span class="typ">App</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="com">// The root page of your application</span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">SimpleGridPage</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	نفّذ البرنامج لتحصل على شكل شبيه بما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22570" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.png.5b49098f5cdd111830a29e3843d6a964.png" rel=""><img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22570" data-unique="qveus46lp" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.thumb.png.78bd95621676e97e3661d8b59ab31c20.png"></a>
</p>

<p>
	لنحلّل الآن هذا التطبيق البسيط. في البداية أنشأنا مخطّط شبكة عن طريق كتابة الوسم <grid> اعتبارًا من السطر 5. بعد ذلك وضعنا تعاريف أسطر الشبكة من السطر 6 حتى السطر 10 على الشكل التالي:</grid></p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_2181_11">
<span class="pun">&lt;</span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">RowDefinitions</span><span class="pun">&gt;</span><span class="pln">
  </span><span class="pun">&lt;</span><span class="typ">RowDefinition</span><span class="pln"> </span><span class="typ">Height</span><span class="pun">=</span><span class="str">"Auto"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
  </span><span class="pun">&lt;</span><span class="typ">RowDefinition</span><span class="pln"> </span><span class="typ">Height</span><span class="pun">=</span><span class="str">"100"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
  </span><span class="pun">&lt;</span><span class="typ">RowDefinition</span><span class="pln"> </span><span class="typ">Height</span><span class="pun">=</span><span class="str">"2*"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
  </span><span class="pun">&lt;</span><span class="typ">RowDefinition</span><span class="pln"> </span><span class="typ">Height</span><span class="pun">=</span><span class="str">"1*"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="pun">&lt;/</span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">RowDefinitions</span><span class="pun">&gt;</span></pre>

<p>
	ويعني ذلك أنّ هذه الشبكة سيكون لها أربعة أسطر (لوجود أربعة وسوم RowDefinition). سيكون ارتفاع السطر الأوّل Auto، ويعني ذلك أنّ هذا السطر سيكون ارتفاعه مساويًا لارتفاع أعلى عنصر موجود ضمنه. أمّا السطر الثاني فارتفاعه 100 وحدة مستقلة عن الجهاز. بالنسبة للسطرين الثالث والرابع فسيكون ارتفاعهما نسبيًّا لوجود رمز النجمة *. لاحظ وجود الرقم 2 بجوار رمز النجمة بالنسبة للسطر الثالث، ووجود الرقم 1 بجوار رمز النجمة بالنسبة للسطر الرابع. الذي سيحدث هنا أنّه وبعد أن يتم تعيين ارتفاعيّ السطرين الأوّل والثاني سيتم اقتسام الارتفاع المتبقي للشبكة بين السطرين الثالث والرابع بحيث تكون حصّة السطر الثالث ضعف (الرقم 2) حصّة السطر الرابع (الرقم 1). بعبارة أخرى ارتفاع السطر الثالث سيكون 2 إلى 1 من ارتفاع السطر الرابع.
</p>

<p>
	وضعنا بعد ذلك تعاريف أعمدة الشبكة من السطر 13 حتى السطر 16 على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_2181_13">
<span class="pun">&lt;</span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">ColumnDefinitions</span><span class="pun">&gt;</span><span class="pln">
  </span><span class="pun">&lt;</span><span class="typ">ColumnDefinition</span><span class="pln"> </span><span class="typ">Width</span><span class="pun">=</span><span class="str">"*"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
  </span><span class="pun">&lt;</span><span class="typ">ColumnDefinition</span><span class="pln"> </span><span class="typ">Width</span><span class="pun">=</span><span class="str">"*"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="pun">&lt;/</span><span class="typ">Grid</span><span class="pun">.</span><span class="typ">ColumnDefinitions</span><span class="pun">&gt;</span></pre>

<p>
	من الواضح أنّه سيكون لهذه الشبكة عمودان فقط. كل من هذين العمودين سيكون عرضه نسبيّ (الرمز <code>*</code>). ولكن بسبب عدم وجود أيّ رقم بجوار رمز النجمة في كلّ منهما، سيتمّ اعتبار وجود الرقم 1 بشكل افتراضيّ بجوار كل رمز نجمة (مثل<code>1*</code>). أي بالمحصلة سيكون لكل منهما نفس الرقم، وبالتالي نفس الحصّة النسبيّة لذلك سيكون لهما نفس العرض تمامًا.
</p>

<p>
	تأتي بعد ذلك العناصر المرئيّة التي سنضعها ضمن هذه الشبكة. يبدأ ترقيم كل من الأسطر والأعمدة بالرقم صفر. فالسطر رقم صفر هو السطر الأوّل، وكذلك الأمر بالنسبة للأعمدة. إذا نظرت إلى الأسطر من 18 حتى 21 فستجد أنّنا نضيف لصيقة إلى الخليّة المحدّدة بالسطر الأوّل والعمود الأوّل. ويكمن سبب ذلك في السطر 19 حيث نجد الخاصيّتين Grid.Row="0" للسطر رقم 0، وGrid.Column="0" للعمود رقم 0 أيضًا. أي السطر الأوّل والعمود الأوّل. بنفس الأسلوب تمامًا نضيف لصيقة أخرى إلى الخليّة المحدّدة بالسطر الأوّل والعمود الثاني (الأسطر من 23 حتى 27)، وأيضًا عنصر صورة ضمن الخليّة المحدّدة بالسطر الثاني والعمود الأوّل (السطران 29 و30). نلاحظ أيضًا أنّ عنصر الصورة هذا سيشغل بالإضافة إلى العمود الأوّل العمود الثاني أيضًا، وذلك بسبب وجود الخاصيّة Grid.ColumnSpan="2" والتي تشير إلى أنّ الخليّة التي ستحتوي عنصر الصورة يجب أن تمتد على عمودين متتاليين باتجاه اليمين، وهذا ما يُفسّر سبب ظهورها ممتدّة على كامل عرض الشبكة كما هو واضح في الشكل السابق. بعد إضافة عنصر الصورة السابق، سنضيف ثلاثة عناصر BoxView لأغراض العرض فقط (الأسطر من 32 حتى 40). حيث ستشغل هذه العناصر الثلاثة على الترتيب الخلايا المحدّدة بالسطر الثالث والعمود الأوّل، ثم السطر الثالث والعمود الثاني، ثم السطر الرابع والعمود الأوّل. مع ملاحظة أنّ عنصر BoxView الأوسط يحوي الخاصيّة Grid.RowSpan="2" التي تسمح للخلية التي تحتويه بالامتداد إلى سطرين متتاليين. أمّا عنصر BoxView الأخير فيحوي على الخاصية Grid.ColumnSpan="2" لتسمح له بالامتداد على عمودين متتاليين. أي أنّ عنصريّ BoxView الثالث والرابع سيتداخلان في الخليّة المحدّدة بالسطر الرابع والعمود الثاني كما هو واضح من الشكل السابق.
</p>

<h3>
	الخلاصة
</h3>

<p>
	تعلّمنا في هذا الدرس كيفيّة التعامل الأساسي مع مخطّط الشبكة Grid Layout. ولعلّ الفهم الأفضل لمثل هذه الأمور تنبع من الممارسّة العمليّة ببناء تطبيقات عمليّة صغيرة ولكنّها مفيدة. سنعمل في الدرسين القادمين على بناء تطبيقين بسيطين يحتويان على العديد من التقنيّات البرمجيّة المفيدة والتي من الممكن استخدامها في التطبيقات الواقعيّة.
</p>
]]></description><guid isPermaLink="false">459</guid><pubDate>Mon, 26 Dec 2016 21:00:00 +0000</pubDate></item><item><title>&#x631;&#x628;&#x637; &#x627;&#x644;&#x628;&#x64A;&#x627;&#x646;&#x627;&#x62A; &#x641;&#x64A; Xamarin</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%B1%D8%A8%D8%B7-%D8%A7%D9%84%D8%A8%D9%8A%D8%A7%D9%86%D8%A7%D8%AA-%D9%81%D9%8A-xamarin-r458/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.f7c0bcd42a3ba29c7f08a36c63109700.png" /></p>

<p>
	كنّا قد رأينا في دروس سابقة كيفيّة الاستفادة من الخصائص الموجودة في عناصر مرئية في التحكّم في خصائص عناصر مرئيّة أخرى كما فعلنا مسبقًا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A7%D9%84%D8%B9%D9%86%D8%A7%D8%B5%D8%B1-%D8%A7%D9%84%D9%85%D8%B1%D8%A6%D9%8A%D9%91%D8%A9-%D8%A7%D9%84%D8%B4%D8%A7%D8%A6%D8%B9%D8%A9-%D9%81%D9%8A-xamarin-%E2%80%93-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%A3%D9%88%D9%91%D9%84-r455/" rel="">هذا الدرس</a> حينما استطعنا التحكّم بحجم الخط المستخدم ضمن لصيقة باستخدام خاصيّة القيمة Value لعنصر Slider. حيث استخدمنا لهذا الغرض معالجات أحداث تحوي شيفرة برمجيّة.
</p>

<p>
	سنتعلّم في هذا الدرس من <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/" rel="">سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms</a>. كيفيّة الاستغناء عن استخدام الشيفرة البرمجيّة في مثل هذه المهام. وذلك من خلال استخدام تقنيّة ربط البيانات data bindings التي تقدّمها لنا Xamarin. تفيد هذه التقنيّة في التقليل من كتابة الشيفرة البرمجيّة إلى حدٍّ كبير. حيث يمكننا ربط العناصر المرئيّة مع بعضها مباشرةً دون الحاجة لكتابة أي سطر من الشيفرة.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22566" data-unique="yjzsz784j" src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.48902def524b9d7bb81806cb5a67d416.png"></p>

<p>
	سنتناول في هذا الدرس مثالين بسيطين لتوضيح هذه الفكرة. سنعمل في المثال الأوّل على التحكّم في حجم لصيقة باستخدام عنصر Slider. أمّا في المثال الثاني فسنجري تحسينًا بسيطًا على المثال الأوّل، حيث سنضيف لصيقة أخرى ونربطها مع نفس عنصر المنزلق Slider، بحيث ستعرض هذه اللصيقة الجديدة القيمة الحاليّة للخاصيّة Value للعنصر Slider.
</p>

<h3>
	تطبيق التحكّم بحجم اللصيقة
</h3>

<p>
	ابدأ بإنشاء مشروع جديد من النوع Blank App (Xamarin.Forms Portable) وسمّه SimpleDataBindingApp، ثم أبق فقط على المشروعين SimpleDataBindingApp (Portable) و SimpleDataBindingApp.Droid كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-visual-studio-2015-community-%D9%88%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-xamarin-%D9%84%D9%84%D8%B9%D9%85%D9%84-r373/" rel="">هذا الدرس</a>. بعد ذلك سنضيف صفحة محتوى تعتمد على رُماز XAML كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xaml-r453/" rel="">هذا الدرس</a> سنسمّها SimpleDataBindingPage. احرص على أن تكون محتويات هذه الصفحة على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6058_7">
<span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
</span><span class="pun">&lt;</span><span class="typ">ContentPage</span><span class="pln"> xmlns</span><span class="pun">=</span><span class="str">"http://xamarin.com/schemas/2014/forms"</span><span class="pln">
             xmlns</span><span class="pun">:</span><span class="pln">x</span><span class="pun">=</span><span class="str">"http://schemas.microsoft.com/winfx/2009/xaml"</span><span class="pln">
             x</span><span class="pun">:</span><span class="typ">Class</span><span class="pun">=</span><span class="str">"SimpleDataBindingApp.SimpleDataBindingPage"</span><span class="pun">&gt;</span><span class="pln">

  </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln">
    </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pun">.</span><span class="typ">Children</span><span class="pun">&gt;</span><span class="pln">
      </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"lblText"</span><span class="pln">
             </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"CenterAndExpand"</span><span class="pln"> 
             </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"النص"</span><span class="pln"> 
             </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln">
             </span><span class="typ">BindingContext</span><span class="pun">=</span><span class="str">"{x:Reference Name=slider}"</span><span class="pln">
             </span><span class="typ">Scale</span><span class="pun">=</span><span class="str">"{Binding Path=Value}"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
      
      </span><span class="pun">&lt;</span><span class="typ">Slider</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"slider"</span><span class="pln">
              </span><span class="typ">Maximum</span><span class="pun">=</span><span class="str">"10"</span><span class="pln">
              </span><span class="typ">Minimum</span><span class="pun">=</span><span class="str">"1"</span><span class="pln">
              </span><span class="typ">Value</span><span class="pun">=</span><span class="str">"4"</span><span class="pln">
              </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"CenterAndExpand"</span><span class="pun">/&gt;</span><span class="pln">
      
    </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">.</span><span class="typ">Children</span><span class="pun">&gt;</span><span class="pln">
  </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">
</span><span class="pun">&lt;/</span><span class="typ">ContentPage</span><span class="pun">&gt;</span></pre>

<p>
	انتقل إلى الملف App.cs واحرص على أن تكون بانية الصنف App على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6058_9">
<span class="kwd">public</span><span class="pln"> </span><span class="typ">App</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="com">// The root page of your application</span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">SimpleDataBindingPage</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	نفّذ البرنامج باستخدام F5 لتحصل على شكل شبيه بما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22567" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.png.7dc48d8f2001ec93234175d168e46845.png" rel=""><img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22567" data-unique="3ogxwi7dy" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.thumb.png.0d0efcf1797762451a1a1d5f8da23f41.png"></a>
</p>

<p>
	يمكنك تمرير عنصر المنزلق Slider لترى كيف يتغيّر حجم اللصيقة تلقائيًّا. هناك عدّة نقاط سنتحدّث عنها حول هذا التطبيق البسيط: 1- لم نستخدم الشيفرة البرمجيّة أبدًا. لقد ربطنا الخاصيّة Value لعنصر Slider مع خاصيّة مقياس العنصر Scale للصيقة من خلال رُماز XAML فحسب. 2- في أيّة عمليّة ربط هناك الكائن المصدر source (في مثالنا السابق كان عنصر Slider)، والكائن الهدف target (في مثالنا السابق كان عنصر اللصيقة Label). 3- في مثالنا السابق، ضبطنا الخاصيّة BindingContext للّصيقة (الهدف) لكي تشير إلى عنصر Slider (المصدر)، لاحظ كيف عيّنّا اسم عنصر المنزلق slider وذلك من خلال النص التالي:
</p>

<pre>
<code>
</code></pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6058_11">
<span class="typ">BindingContext</span><span class="pun">=</span><span class="str">"{x:Reference Name=slider}"</span></pre>

<p>
	ثم أخبرنا Xamarin أنّنا نريد ربط خاصيّة مقياس العنصر Scale للّصيقة مع الخاصيّة Value لعنصر المنزلق Slider عن طريق ضبط النص التالي إلى الخاصيّة Scale للصيقة:
</p>

<pre>
<code>
</code></pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6058_13">
<span class="typ">Scale</span><span class="pun">=</span><span class="str">"{Binding Path=Value}"</span><span class="pln"> </span></pre>

<p>
	تتحكّم الخاصيّة Scale بمقياس العنصر. سنتحدّث عن ذلك في دروس لاحقة ضمن هذه السلسلة.
</p>

<h3>
	التطبيق المحسّن للتحكّم بحجم اللصيقة
</h3>

<p>
	أضف إلى التطبيق السابق صفحة محتوى تعتمد على رُماز XAML كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xaml-r453/" rel="">هذا الدرس</a> سنسمّها EnhancedDataBindingPage. احرص على أن تكون محتويات هذه الصفحة على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6058_15">
<span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
</span><span class="pun">&lt;</span><span class="typ">ContentPage</span><span class="pln"> xmlns</span><span class="pun">=</span><span class="str">"http://xamarin.com/schemas/2014/forms"</span><span class="pln">
             xmlns</span><span class="pun">:</span><span class="pln">x</span><span class="pun">=</span><span class="str">"http://schemas.microsoft.com/winfx/2009/xaml"</span><span class="pln">
             x</span><span class="pun">:</span><span class="typ">Class</span><span class="pun">=</span><span class="str">"SimpleDataBindingApp.EnhancedDataBindingPage"</span><span class="pun">&gt;</span><span class="pln">
  </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pln"> </span><span class="pun">&gt;</span><span class="pln">
    </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pun">.</span><span class="typ">Children</span><span class="pun">&gt;</span><span class="pln">
      </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"lblText"</span><span class="pln">
             </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"CenterAndExpand"</span><span class="pln">
             </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"النص"</span><span class="pln">
             </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln">
             </span><span class="typ">BindingContext</span><span class="pun">=</span><span class="str">"{x:Reference Name=slider}"</span><span class="pln">
             </span><span class="typ">Scale</span><span class="pun">=</span><span class="str">"{Binding Path=Value}"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">

      </span><span class="pun">&lt;</span><span class="typ">Slider</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"slider"</span><span class="pln">
              </span><span class="typ">Maximum</span><span class="pun">=</span><span class="str">"10"</span><span class="pln">
              </span><span class="typ">Minimum</span><span class="pun">=</span><span class="str">"1"</span><span class="pln">
              </span><span class="typ">Value</span><span class="pun">=</span><span class="str">"4"</span><span class="pln">
              </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"CenterAndExpand"</span><span class="pun">/&gt;</span><span class="pln">

      </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"lblScale"</span><span class="pln">
             </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"CenterAndExpand"</span><span class="pln">
             </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"{Binding Path=Value, StringFormat = 'Scale = {0:F1}'}"</span><span class="pln">
             </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln">
             </span><span class="typ">BindingContext</span><span class="pun">=</span><span class="str">"{x:Reference Name=slider}"</span><span class="pun">/&gt;</span><span class="pln">

    </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">.</span><span class="typ">Children</span><span class="pun">&gt;</span><span class="pln">
  </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">
</span><span class="pun">&lt;/</span><span class="typ">ContentPage</span><span class="pun">&gt;</span></pre>

<p>
	من الواضح أنّ التعديل الوحيد الملاحظ هنا هو في وجود عنصر اللصيقة الجديد lblScale والذي تنحصر وظيفته كما أوضحنا سابقًا على عرض القيمة الحالية لعنصر المنزلق Slider. إليك تعريف عنصر اللصيقة lblScale:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6058_17">
<span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"lblScale"</span><span class="pln">
        </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"CenterAndExpand"</span><span class="pln">
        </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"{Binding Path=Value, StringFormat = 'Scale = {0:F1}'}"</span><span class="pln">
        </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln">
        </span><span class="typ">BindingContext</span><span class="pun">=</span><span class="str">"{x:Reference Name=slider}"</span><span class="pun">/&gt;</span></pre>

<p>
	كما وسبق أن فعلنا مع لصيقة النص lblText، قمنا بتعيين الخاصيّة BindingContext لتشير إلى عنصر المنزلق الذي يحمل الاسم "slider":
</p>

<pre>
<code>
</code></pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6058_19">
<span class="typ">BindingContext</span><span class="pun">=</span><span class="str">"{x:Reference Name=slider}"</span><span class="pun">/&gt;</span></pre>

<p>
	ثمّ سنربط هذه المرّة الخاصيّة Text لهذه اللصيقة بالخاصيّة Value لعنصر المنزلق على الشكل التالي:
</p>

<pre>
<code>
</code></pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6058_21">
<span class="typ">Text</span><span class="pun">=</span><span class="str">"{Binding Path=Value, StringFormat = 'Scale = {0:F1}'}"</span></pre>

<p>
	لاحظ كيف أنّ الربط Binding قد جرى بين الخاصيّة Value لعنصر المنزلق، والخاصيّة Text لعنصر اللصيقة الجديد lblScale. لاحظ أيضًا الكلمة الجديدة StringFormat. ستُفسَّر هذه الكلمة في الواقع لتصبح استدعاء إلى التابع String.Format الذي يعمل على تنسيق النص Scale = {0:F1} بحيث يظهر ضمن اللصيقة عدد ذو فاصلة عشرية ثابتة تمتلك رقم واحد فقط على يمين الفاصلة العشريّة. يمكنك تغيير هذا السلوك، بحيث تلغي عمليّة التنسيق هذه لترى الفرق وذلك على الشكل التالي:
</p>

<pre>
<code>
</code></pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6058_23">
<span class="typ">Text</span><span class="pun">=</span><span class="str">"{Binding Path=Value'}"</span></pre>

<p>
	انتقل الآن إلى الملف App.cs واحرص على أن تكون بانية الصنف App على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6058_25">
<span class="kwd">public</span><span class="pln"> </span><span class="typ">App</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="com">// The root page of your application</span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">EnhancedDataBindingPage</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	عند تنفيذ البرنامج ستحصل على شكل شبيه بما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22568" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.png.a5e3fd656b3b3d1310ac0fbf8d59d932.png" rel=""><img alt="fig02.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22568" data-unique="3tz0q6ier" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.thumb.png.eebf796dc560f335393890bdc32dce80.png"></a>
</p>

<p>
	يمكنك تحريك المنزلق لترى كيف يعمل الربط بين الخاصيّة Value وكل من الخاصيّتين Scale وText للصيقتين الموجودتين في البرنامج.
</p>

<h3>
	الخلاصة
</h3>

<p>
	يُعتبر هذا الدرس مثيرًا للانتباه. حيث لم نكتب أي شيفرة برمجيّة في أيّ من التطبيقين اللذين بنيناهما في هذا الدرس. إنّ عمليّة ربط البيانات data bindings بمعزل عن كونها توفّر الوقت والجهد في إنجاز مهام روتينيّة (وهو أمر مهم بالطبع)، تُعتبر حيويةً في أسلوب تصميم التطبيقات MVVM (اختصارًا للكلمات Model View ViewModel) الشائع جدًّا في تصميم تطبيقات الأجهزة المحمولة. سنتناول في الدرس القادم موضوعًا مهمًّا نتعلّم من خلاله كيفيّة تصميم واجهات مستخدم دقيقة من خلال مخطّط الشبكة Grid Layout. وهو أحد أنواع المخطّطات المستخدمة في Xamarin والتي من المؤكّد أنّها ستثير إعجابك.
</p>
]]></description><guid isPermaLink="false">458</guid><pubDate>Sun, 18 Dec 2016 21:00:00 +0000</pubDate></item><item><title>&#x628;&#x646;&#x627;&#x621; &#x62A;&#x637;&#x628;&#x64A;&#x642; &#x639;&#x645;&#x644;&#x64A;&#x651; &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; XAML</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82-%D8%B9%D9%85%D9%84%D9%8A%D9%91-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xaml-r457/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.81ccb58956ff198fddc321e835852e5a.png" /></p>

<p>
	نتابع عملنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/" rel="">سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms</a>. سنتعلّم في هذا الدرس تقنيّات جديدة لبناء واجهات متقدّمة أكثر باستخدام رماز XAML. كما سنتعلّم كيفيّة عرض رسائل تنبيه للمستخدم. يُعتبر هذا الدرس مساعدًا<a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xaml-r453/" rel=""> للدرس السابق</a> في فهم كيفية التعامل مع رماز XAML. سنتناول في هذا الدرس تطبيقًا عمليًا مفيدًا، الهدف منه هو حل معادلة من الدرجة الثانيّة Quadratic Equation في مجموعة الأعداد الحقيقية R.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22565" data-unique="8eow4sne9" src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.34976aa7b71b0f5d93987475a012afa8.png"></p>

<h3>
	كيفيّة حل معادلة من الدرجة الثانية
</h3>

<p>
	للمعادلة من الدرجة الثانية الشكل العام التالي:
</p>

<p style="text-align: center;">
	<img alt="sde-general-form.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22563" data-pin-nopin="true" data-unique="3lqd75k7w" src="https://academy.hsoub.com/uploads/monthly_2017_04/sde-general-form.png.7c2b811696466259132cafbac0ce3d60.png"></p>

<p>
	لكي نحل هذه المعادلة في المجموعة R نحتاج إلى معرفة قيم المعاملات a وb وc وهي عبارة عن ثوابت حقيقيّة سنطلب من المستخدم أي يزوّد البرنامج بها. بعد ذلك سنطبّق القانون التالي لحساب مميّز هذه المعادلة:
</p>

<p style="text-align: center;">
	<img alt="determinant.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22560" data-pin-nopin="true" data-unique="ytn49fxra" src="https://academy.hsoub.com/uploads/monthly_2017_04/determinant.png.8cdf9e95b39f9bcc9c98156ac5af1e6f.png"></p>

<p>
	من خلال قيمة هذا المميّز نكون أمام ثلاث حالات:
</p>

<ul>
<li>
		الحالة الأولى عندما يكون <img alt="delta-greater-then-zero.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22558" data-pin-nopin="true" data-unique="cr4lpo933" src="https://academy.hsoub.com/uploads/monthly_2017_04/delta-greater-then-zero.png.5b38b7c596e83d3876c729409a9c51ff.png"> فيوجد عندئذ حلّين مختلفين للمعادلة المفروضة يمكن الحصول عليهما من العلاقتين التاليتين: <img alt="two-solutions.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22564" data-pin-nopin="true" data-unique="v01xipbv2" src="https://academy.hsoub.com/uploads/monthly_2017_04/two-solutions.png.0d41c6c72a0ad9d7a26a946e1bd4bce1.png">
</li>
	<li>
		الحالة الثانية عندما <img alt="delta-equals-zero.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22557" data-pin-nopin="true" data-unique="folspk70y" src="https://academy.hsoub.com/uploads/monthly_2017_04/delta-equals-zero.png.183fed39c6d42f5b29a95f96c8d1f7d9.png"> فيوجد عندئذ حل مضاعف يُعطى بالعلاقة التالية:<img alt="one-solution.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22562" data-pin-nopin="true" data-unique="ievysozg1" src="https://academy.hsoub.com/uploads/monthly_2017_04/one-solution.png.d9b5baabe71ab1ea973759c07f3987d3.png">
</li>
	<li>
		الحالة الثالثة عندما <img alt="delta-smaller-then-zero.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22559" data-pin-nopin="true" data-unique="tkhygjppj" src="https://academy.hsoub.com/uploads/monthly_2017_04/delta-smaller-then-zero.png.22354b00cc9b6136161e63d6edd8347c.png">فلا يكون للمعادلة عندها أي حل في المجموعة R.
	</li>
</ul>
<h3>
	بناء تطبيق حل المعادلات من الدرجة الثانية
</h3>

<p>
	ابدأ بإنشاء مشروع جديد من النوع Blank App (Xamarin.Forms Portable) وسمّه SDESolverApp، ثم أبق فقط على المشروعين SDESolverApp (Portable) و SDESolverApp.Droid كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-visual-studio-2015-community-%D9%88%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-xamarin-%D9%84%D9%84%D8%B9%D9%85%D9%84-r373/" rel="">هذا الدرس</a>. بعد ذلك سنضيف صفحة محتوى تعتمد على رماز XAML كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xaml-r453/" rel="">الدرس السابق</a> سنسمّها SDESolverPage. سنقسّم الواجهة إلى ثلاثة أقسام. القسم الأوّل العلوي سيحتوي على رسالة ترحيبيّة، أمّا القسم الأوسط فسيضم المنطقة الخاصّة بإدخال قيم المعاملات a وb وc الذين تحدثنا عنهم قبل قليل مع لصيقة توضيحيّة. أمّا القسم الأخير السفلي فسيحوي زرًا عند نقره سيتم حل المعادلة. انظر الشكل التالي لمعرفة الشكل العام لهذا التطبيق:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22561" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.png.7e15db5c73e758ba62695f29d98b02e7.png" rel=""><img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22561" data-unique="2vb10w2zz" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.thumb.png.cddc8c8f84cbc66636c05e159e2d8e88.png"></a>
</p>

<p>
	في البداية أقترح وضع الواجهة السابقة ضمن مخطّط مكدّس يحيط بها بشكل كامل وذلك على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6992_7">
<span class="pln"> </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">
    </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pun">.</span><span class="typ">Children</span><span class="pun">&gt;</span><span class="pln">
	</span><span class="pun">…</span><span class="pln">
    </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">.</span><span class="typ">Children</span><span class="pun">&gt;</span><span class="pln">
  </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">&gt;</span></pre>

<p>
	تمثّل النقاط الثلاث التي تظهر في الرماز السابق، المكان المفترض لرماز الواجهة الذي سنتحدّث عنه بعد قليل، حيث ستقع أي عناصر مرئيّة أخرى ضمن العنصر StackLayout.Children كما هو معلوم.<br>
	لنجهّز الرسالة الترحيبيّة التي ستظهر في الأعلى. في الحقيقة تتألّف هذه الرسالة من عنصر إطار Frame يحوي لصيقة تعرض النص الترحيبي. يمكن استخدام الرماز التالي لتحقيق هذا الشكل:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6992_7">
<code>
&lt;Frame Padding="5"
        OutlineColor="Accent"
        BackgroundColor="#300000FF"
        VerticalOptions="StartAndExpand"&gt;
  &lt;Frame.Content&gt;
    &lt;Label Text="تطبيق حل المعادلات من الدرجة الثانية"
            FontSize="Large"
            TextColor="Accent"
            HorizontalOptions="FillAndExpand"
            HorizontalTextAlignment="Center" /&gt;
  &lt;/Frame.Content&gt;
&lt;/Frame&gt;
</code></pre>

<p>
	بالنسبة لعنصر الإطار Frame فقد ضبطنا الخاصيّة Padding له لإضافة حشوة صغيرة تحيط بمحتوياته. كما ضبطنا خصائص لون الحد الخارجي OutlineColor لتحمل اللون Accent وخاصيّة لون الخلفية BackgroundColor لتكون "#300000FF". القيمة السابقة هي قيمة ستة عشرية تتكوّن من أربعة مكوّنات. كل مكّون يحجز محرفين. هذه المكوّنات من اليسار إلى اليمين: قيمة الشفافيّة alpha وتتراوح بين 00 و FF (استخدمنا في هذا المثال القيمة 30)، ثم يأتي اللون الأحمر فالأخضر فالأزرق. فمن خلال القيمة "#300000FF" سيظهر معنا لون أزرق لكنّه شفّاف بعض الشيء. ضبطنا أيضًا خاصيّة التموضع الرأسي VerticalOptions لتكون StartAndExpand ليظهر الإطار في البداية (في الأعلى في هذا التطبيق). بعد ذلك تأتي الخاصيّة Frame.Content والتي يمكن إسناد عنصر مرئي واحد إليها. أسندنا لصيقة كما هو واضح في الرماز السابق، وضبطنا خصائصها ليكون حجم الخط كبيرًا ولونه Accent، كما جعلنا محاذاة النص ضمن اللصيقة في الوسط. تنحصر مهمّة عنصر الإطار في إكساب ناحية جمالية للصيقة التي يحتويها.
</p>

<p>
	لننتقل الآن إلى القسم الثاني الأوسط من واجهة التطبيق والذي يحتوي كما أشرنا على منطقة مدخلات المستخدم. سنضع هذا القسم بكامله ضمن مخطّط مكدّس. سيحتوي هذا المخطّط على ما يلي:
</p>

<p>
	<strong>1-</strong> لصيقة ضمن إطار كما فعلنا تمامًا مع الرسالة الترحيبيّة السابقة في القسم العلوي. تحوي هذه اللصيقة نصًّا توضيحيًّا. لننظر إلى الرماز المسؤول عن إظهار اللصيقة التي تحتوي على النص التوضيحي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6992_7">
<code>
&lt;StackLayout VerticalOptions="CenterAndExpand"&gt;
  &lt;StackLayout.Children&gt;
      &lt;Frame Padding="5"
              OutlineColor="Green"
              BackgroundColor="#3000FF00"&gt;
        &lt;Frame.Content&gt;
          &lt;Label Text="أدخل المعاملات التالية لإيجاد حل المعادلة "
                  FontSize="Medium"
                  TextColor="Lime"
                  HorizontalOptions="FillAndExpand"
                  HorizontalTextAlignment="End" /&gt;
        &lt;/Frame.Content&gt;
      &lt;/Frame&gt;

      ...

  &lt;/StackLayout.Children&gt;
&lt;/StackLayout&gt;
</code></pre>

<p>
	النقاط الثلاث الموجودة ضمن الرماز السابق هي مكان الرماز الذي سيُظهِر مربّعات النص المسؤولة عن استقبال الدخل من المستخدم، حيث تجنبّت وضعه صراحةً لكي نركّز الآن على الرماز الحالي. لاحظ عنصر الإطار Frame كيف يحتوي ضمن الخاصيّة Content له على اللصيقة التي تعرض العبارة "أدخل المعاملات التالية لإيجاد حل المعادلة". لقد ضبطت الخاصيّة HorizontalTextAlignment لها لتكون End أي ليظهر النص كما لو أنّه محاذًا نحو اليمين.
</p>

<p>
	<strong>2- </strong>مخطّط مكدّس آخر لعرض مربّعات الإدخال Entry لاستقبال الدخل من المستخدم، وهو يقع أسفل الإطار الذي يحوي اللصيقة التي تعرض العبارة التوضيحيّة (انظر رقم 1):
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6992_7">
<code>
&lt;StackLayout VerticalOptions="CenterAndExpand"&gt;
  &lt;StackLayout.Children&gt;
      ...

      &lt;StackLayout Orientation="Horizontal"&gt;
        &lt;StackLayout.Children&gt;
          &lt;Entry x:Name="txtA"
                  HorizontalOptions="StartAndExpand"
                  Placeholder="المعامل a"
                  FontSize="Medium"
                  Keyboard="Telephone" /&gt;

          &lt;Entry x:Name="txtB"
                  HorizontalOptions="CenterAndExpand"
                  Placeholder="المعامل b"
                  FontSize="Medium"
                  Keyboard="Telephone" /&gt;

          &lt;Entry x:Name="txtC"
                  HorizontalOptions="EndAndExpand"
                  Placeholder="المعامل c"
                  FontSize="Medium"
                  Keyboard="Telephone" /&gt;
        &lt;/StackLayout.Children&gt; 
      &lt;/StackLayout&gt;
  &lt;/StackLayout.Children&gt;
&lt;/StackLayout&gt;
</code></pre>

<p>
	الأمر الواضح هنا أنّني قد وضعت مربّعات النص Entry لاستقبال الدخل من المستخدم ضمن مخطّط مكدّس آخر، وهذا أمر طبيعي تمامًا في تصميم الواجهات. لقد جعلت خاصيّة الاتجاه Orientation لهذا المكدّس تحمل القيمة Horizontal أي أفقي. كما وضعت ضمن العنصر StackLayout.Children ثلاثة عناصر Entry لاستقبال المعاملات a وb وc على الترتيب. من الملاحظ أنّني استخدمت الخاصيّة x:Name لكلّ من هذه العناصر لكي نستطيع الوصول إلى محتوياتها ضمن ملف الشيفرة البرمجيّة المرافق لملف الرماز كما سنرى بعد قليل. كما استخدمت الخاصيّة Placeholder لكلّ منها لعرض نص توضيحي ضمن عنصر Entry يوضّح وظيفته. الأمر الأخير الملاحظ هنا هو استخدامي للخاصيّة Keyboard للعنصر Entry التي تسمح بتحديد لوحة المفاتيح التي ستظهر للمستخدم عندما يحاول الكتابة ضمن هذا العنصر. توجد عدّة لوحات مفاتيح تدعمها Xamarin.Froms. لقد استخدمت من أجل هذا المثال لوحة المفاتيح Telephone وهي لوحة مفاتيح مخصّصة لإدخال البيانات المتعلّقة بأرقام الهواتف. في الحقيقة توجد لوحة مفاتيح مخصّصة للأرقام اسمها Numeric ولكنّني آثرت لوحة مفاتيح Telephone عليها لأنّها تدعم إدخال إشارة السالب (-) وهذا ما لا توفّره لوحة المفاتيح الرقميّة القياسيّة Numeric.
</p>

<p>
	ننتقل الآن إلى القسم الأخير السفلي من الواجهة، وهو يحتوي على زر بسيط عندما ينقره المستخدم سيعمل البرنامج على حل المعادلة ويعرض النتيجة. انظر إلى الرماز الخاص به:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6992_7">
<code>
&lt;Button Text="حل المعادلة"`
        VerticalOptions="EndAndExpand"
        HorizontalOptions="FillAndExpand"
        HeightRequest="64"
        Clicked="btnSolve_Clicked"/&gt;
</code></pre>

<p>
	استخدمت هذه المرّة الخاصيّة HeightRequest التي يمكن من خلالها ضبط ارتفاع العنصر بشكل تقريبي. لقد جعلت ارتفاعه مساويًا لـ 1 سم تقريبًا. توجد خاصيّة أخرى مشابهة لها لضبط عرض أي عنصر بشكل تقريبي وهي WidthRequest. ضبطّت أيضًا معالج الحدث Clicked الذي سيتم تنفيذه عندما ينقر المستخدم على هذا الزر. اسم هذا المعالج btnSolve_Clicked وسيكون في الطبع ضمن ملف الشيفرة البرمجيّة. إليك الآن الرماز الكامل لهذا لواجهة هذا التطبيق مجمّعًا على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6992_7">
<code>
&lt;?xml version="1.0" encoding="utf-8" ?&gt;
&lt;ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="SDESolverApp.SDESolverPage"
             Padding="5"&gt;
  
  &lt;StackLayout&gt;
    &lt;StackLayout.Children&gt;
      &lt;Frame Padding="5"
             OutlineColor="Accent"
             BackgroundColor="#300000FF"
             VerticalOptions="StartAndExpand"&gt;
        &lt;Frame.Content&gt;
          &lt;Label Text="تطبيق حل المعادلات من الدرجة الثانية"
                 FontSize="Large"
                 TextColor="Accent"
                 HorizontalOptions="FillAndExpand"
                 HorizontalTextAlignment="Center" /&gt;
        &lt;/Frame.Content&gt;
      &lt;/Frame&gt;

      &lt;StackLayout VerticalOptions="CenterAndExpand"&gt;
        &lt;StackLayout.Children&gt;
            &lt;Frame Padding="5"
                   OutlineColor="Green"
                   BackgroundColor="#3000FF00"&gt;
              &lt;Frame.Content&gt;
                &lt;Label Text="أدخل المعاملات التالية لإيجاد حل المعادلة "
                       FontSize="Medium"
                       TextColor="Lime"
                       HorizontalOptions="FillAndExpand"
                       HorizontalTextAlignment="End" /&gt;
              &lt;/Frame.Content&gt;
            &lt;/Frame&gt;

            &lt;StackLayout Orientation="Horizontal"&gt;
              &lt;StackLayout.Children&gt;
                &lt;Entry x:Name="txtA"
                       HorizontalOptions="StartAndExpand"
                       Placeholder="المعامل a"
                       FontSize="Medium"
                       Keyboard="Telephone" /&gt;

                &lt;Entry x:Name="txtB"
                       HorizontalOptions="CenterAndExpand"
                       Placeholder="المعامل b"
                       FontSize="Medium"
                       Keyboard="Telephone" /&gt;

                &lt;Entry x:Name="txtC"
                       HorizontalOptions="EndAndExpand"
                       Placeholder="المعامل c"
                       FontSize="Medium"
                       Keyboard="Telephone" /&gt;
              &lt;/StackLayout.Children&gt; 
            &lt;/StackLayout&gt;
        &lt;/StackLayout.Children&gt;
      &lt;/StackLayout&gt;
      
      &lt;Button Text="حل المعادلة"
              VerticalOptions="EndAndExpand"
              HorizontalOptions="FillAndExpand"
              HeightRequest="64"
              Clicked="btnSolve_Clicked"/&gt;
    &lt;/StackLayout.Children&gt;
  &lt;/StackLayout&gt;
&lt;/ContentPage&gt;
</code></pre>

<p>
	لننتقل إلى ملف الشيفرة البرمجيّة المرافق لملف الرماز السابق. اسم هذا الملف بالطبع هو SDESolverPage.xaml.cs. احرص على أن تكون محتوياته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_6992_7">
<code>
1	using System;
2	using Xamarin.Forms;
3	
4	namespace SDESolverApp
5	{
6	    public partial class SDESolverPage : ContentPage
7	    {
8	        public SDESolverPage()
9	        {
10	            InitializeComponent();
11	        }
12	
13	        private void btnSolve_Clicked(object sender, EventArgs e)
14	        {
15	            double a, b, c;
16	
17	            string txt_a = txtA.Text;
18	            string txt_b = txtB.Text;
19	            string txt_c = txtC.Text;
20	
21	            if (double.TryParse(txt_a, out a) &amp;&amp;
22	                double.TryParse(txt_b, out b) &amp;&amp;
23	                double.TryParse(txt_c, out c))
24	            {
25	                string result;
26	
27	                double delta = b * b - 4 * a * c;
28	
29	                if (delta &gt; 0)
30	                {
31	                    //there are two different solutions.
32	                    double x1 = (-b + Math.Sqrt(delta)) / (2 * a);
33	                    double x2 = (-b - Math.Sqrt(delta)) / (2 * a);
34	
35	                    result = string.Format("يوجد حلين مختلفين في المجموعة R\nx1 = {0}\nx2 = {1}",
36	                        x1.ToString("#0.#"),
37	                        x2.ToString("#0.#"));
38	                }
39	                else if (delta == 0)
40	                {
41	                    //there are two equal solutions.
42	                    double x = -b / (2 * a);
43	
44	                    result = string.Format("يوجد حل مضاعف في المجموعة R\nx1 = x2 = {0}",
45	                        x.ToString("#0.#"));
46	                }
47	                else
48	                {
49	                    //there is no solutions in R.
50	                    result = "المعادلة مستحيلة الحل في المجموعة R";
51	                }
52	
53	                DisplayAlert("الحل", result, "موافق");
54	            }
55	            else
56	            {
57	                DisplayAlert("خطأ في المدخلات", "بعض المعاملات المدخلة غير صحيحة", "موافق");
58	            }
59	        }
60	    }
61	}
</code></pre>

<p>
	يحتوي الصنف SDESolverPage بشكل أساسيّ على معالج الحدث btnSolve_Clicked الذي سيُستدعى عندما ينقر المستخدم زر حل المعادلة من الواجهة. يحتوي هذا المعالج على كامل منطق التطبيق. يحصل البرنامج على قيم المعاملات في الأسطر من 17 حتى 19 حيث تكون قيم نصيّة بالطبع، ثمّ يحوّل هذه القيم النصيّة إلى قيم من النوع double وذلك في الأسطر من 21 حتى 23 من خلال استخدام التابع الساكن TryParse من الصنف double. يحاول هذا التابع أن يحوّل القيمة النصيّة المُمرّرة إليه في الوسيط الأوّل، فإن نجح في ذلك فإنّه يُسند القيمة المُحوّلة إلى المتغيّر a الذي نمرّره كوسيط ثانٍ إلى هذا التابع ويُرجع التابع القيمة true. أمّا إذا فشلت عمليّة التحويل فإنّ التابع سيُرجع القيمة false فيختلّ شرط عبارة if، وبالتالي لن يُتابع البرنامج عمله في حل المعادلة ويعرض رسالة بهذا الخصوص إلى المستخدم بسبب عدم صلاحيّة أحد العوامل المُدخلة على الأقل. لاحظ أنّنا قد مرّرنا الوسيط الثاني الذي سيحمل نتيجة التحويل في حال نجاحه باستخدام الكلمة المحجوزة out. التي تسمح بتمرير عنوان المتغيّر إلى التابع وليس قيمته.
</p>

<p>
	يتابع البرنامج عمله في حال نجحت عمليّة تحويل المعاملات إلى double بحساب مميّز المعادلة ومقارنته بالحالات الثلاث المختلفة التي تحدثنا عنها مسبقًا. توجد ملاحظة أخيرة في أنّ التطبيق يعرض النتائج باستخدام صناديق رسائل قياسيّة في أندرويد، وذلك من خلال استخدام التابع DisplayAlert وهو من الصنف Page (السطران 53 و57) أيّ أنّه ينتمي إلى الصنف SDESolverPage من خلال الوراثة. يخضع التابع DisplayAlert لزيادة التحميل، وقد استخدمت الشكل الذي يتطلّب ثلاثة وسائط وهي بالترتيب عنوان الرسالة، والرسالة المراد عرضها، ثم النص المراد عرضه على الزر.
</p>

<p>
	يمكن بالطبع استخدام وسائل مختلفة لعرض النتائج للمستخدم، كعرضها ضمن صفحة منفصلة مثلًا، وقد يكون هذا الأسلوب أفضل. ولكن بالنسبة إلى هذه المرحلة فالحل المستخدم في هذا التطبيق يُعتبر جيّدًا. سنتعلّم مستقبلًا كيفيّة التعامل مع عرض المعلومات المختلفة عن طريق صفحات مستقلّة.
</p>

<h3>
	الخلاصة
</h3>

<p>
	بنينا في هذا الدرس تطبيقًا عمليًّا، يوضّح التعامل مع رماز XAML بشكل متقدّم أكثر. في الحقيقة ستحتاج إلى تطوير العديد من البرامج البسيطة كهذا البرنامج كي تتمكّن من تصميم الواجهات بشكل جيّد. سنتابع في الدروس القادمة العمل في تطوير تطبيقات عمليّة بسيطة ومفيدة، يمكن من خلالها تعلّم المزيد عن بناء الواجهات باستخدام XAML.
</p>
]]></description><guid isPermaLink="false">457</guid><pubDate>Wed, 14 Dec 2016 21:00:00 +0000</pubDate></item><item><title>&#x628;&#x646;&#x627;&#x621; &#x648;&#x627;&#x62C;&#x647;&#x627;&#x62A; &#x62A;&#x637;&#x628;&#x64A;&#x642;&#x627;&#x62A; Xamarin &#x628;&#x627;&#x633;&#x62A;&#x62E;&#x62F;&#x627;&#x645; XAML</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%A8%D9%86%D8%A7%D8%A1-%D9%88%D8%A7%D8%AC%D9%87%D8%A7%D8%AA-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-%D8%A8%D8%A7%D8%B3%D8%AA%D8%AE%D8%AF%D8%A7%D9%85-xaml-r453/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.cfcb7b588fde4327b65d56d22b70e3a0.png" /></p>

<p>
	يُعتبر هذا الدرس من الدروس المهمّة في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/" rel="">سلسلة تعلّم برمجة تطبيقات أندرويد باستخدام Xamarin.Forms</a>. في الواقع لقد أشرنا إلى هذا الدرس عدّة مرّات خلال الدروس السابقة. تكمن المشكلة في التطبيقات التي تناولناها في الدروس السابقة إلى أنّنا كنّا ننشئ واجهة التطبيق باستخدام الشيفرة البرمجيّة بشكل كامل مما يؤدّي إلى مشكلة كبيرة في تنظيم البرامج لأنّنا في هذه الحالة سنضطر غالبًا إلى وضع الشيفرة المسؤولة عن بناء الواجهات مع الشيفرة البرمجيّة المسؤولة عن تمثيل منطق العمل business logic في البرنامج، وهذا أمر سيء بالطبع.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22539" data-unique="846jq0j24" src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.ecb54c49f7436563e317d84dabdbfcba.png"></p>

<p>
	وفّرت Xamarin حلًا ممتازًا لهذه المشكلة يجعل من البرمجة باستخدامها تجربة غنيّة ومعاصرة، وذلك من خلال إنشاء الواجهات باستخدام رماز XAML. يشبه هذا الرماز إلى حدٍّ كبير رماز XML. حيث يتمّ إنشاء العناصر المرئيّة وضبط خصائصها باستخدام ما يشبه عناصر وسمات XML. تكمن الفائدة الأساسيّة من استخدام هذا الأسلوب هو عزل بناء واجهات البرنامج عن الشيفرة البرمجيّة المسؤولة عن معالجة منطق البرنامج، وهذا أمر مهم وخصوصًا عند بناء تطبيقات كبيرة. لنقارن مثلًا بين إنشاء لصيقة باستخدام الشيفرة البرمجيّة وباستخدام XAML:
</p>

<p style="text-align: center;">
	<img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22534" data-unique="pnir7djkj" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.png.385a40a5b81591c5f6bd5504fb8f0f71.png"></p>

<p>
	لا أعتقد أنّنا سنبذل كثيرًا من الجهد لملاحظة أنّ أسلوب XAML مباشر وواضح أكثر من أسلوب الشيفرة البرمجيّة. تُكتَب العناصر المرئيّة في Xamarin.Forms باستخدام XAML على شكل عناصر XML عاديّة، أمّا خصائصها فتكون على شكل سمات attributes لهذه العناصر. يوجد أسلوب آخر لكتابة خصائص العناصر ضمن XAML سنتحدّث عنه بعد قليل. يُكتب رماز XAML ضمن ملفات مخصّصة لهذه الغرض تحمل الامتداد xaml. وطريقة إضافتها للمشروع بسيطة سنتحدّث عنها أيضًا بعد قليل ضمن برنامج تطبيقي. في الحقيقة يعمل المُعرب parser الخاص بـ XAML على ترجمة كل عنصر يصادفه إلى الصنف المقابل له في الشيفرة. فمثلًا ومن المثال البسيط السابق عند يصادف هذا المُعرب العنصر Label سيعمل على إنشاء كائن برمجي من الصنف Label ثم يعمل على مطابقة السمات الموجودة ضمن العنصر في XAML مع الخصائص الفعليّة للصنف Label ويُسند قيم الخصائص وفقًا لها. فمثلًا، تحمل السمة HorizontalTextAlignment القيمة Center من رماز XAML. وهي تُطابق الخاصيّة ذات الاسم نفسه من الصنف Label. لذلك فعند إنشاء كائن اللصيقة Label سيتم إسناد القيمة TextAlignment.Center إلى الخاصيّة HorizontalTextAlignment. مثال أخر حول السمة FontAttributes التي تحمل القيمة "Bold, Italic" وهي تُطابق الخاصيّة ذات الاسم نفسه من الصنف Label. لذلك فعند إنشاء كائن اللصيقة Label سيتم إسناد القيمة التالية لهذه الخاصيّة:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9500_22">
<span class="typ">FontAttributes</span><span class="pun">.</span><span class="typ">Bold</span><span class="pln"> </span><span class="pun">|</span><span class="pln"> </span><span class="typ">FontAttributes</span><span class="pun">.</span><span class="typ">Italic</span><span class="pln"> 
</span></pre>

<p>
	لاحظ العامل "|" وهو عامل OR على مستوى البتّات bits وهو يفيد في تعيين أكثر من قيمة بنفس الوقت للخاصيّة FontAttributes. ويسري هذا الأمر على باقي السمات للعنصر Label.
</p>

<h3>
	مثال تطبيقي حول استخدام XAML في بناء الواجهات
</h3>

<p>
	أنشئ مشروعًا جديدًا من النوع Blank App (Xamarin.Forms Portable) وسمّه XamlDemoApp، ثم أبق فقط على المشروعين XamlDemoApp (Portable) و XamlDemoApp.Droid كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-visual-studio-2015-community-%D9%88%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-xamarin-%D9%84%D9%84%D8%B9%D9%85%D9%84-r373/" rel="">هذا الدرس</a>. بعد ذلك سنضيف صفحة محتوى تعتمد على رماز XAML. لفعل ذلك انقر بزر الفأرة الأيمن على المشروع XamlDemoApp (Portable) واختر Add ثم New Item. من مربّع الحوار الذي سيظهر لك، اختر من الجانب الأيسر له Cross-Platform، ومن القسم الأيمن احرص على اختيار Forms Xaml Page، وسمّها XamlDemoPage كما في الشكل التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22535" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.png.f09782159d123016eadfe7be9fd69d1b.png" rel=""><img alt="fig02.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22535" data-unique="p9af54crd" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.thumb.png.af3e067ab9a494dfc755f1cc328603e6.png"></a>
</p>

<p>
	انقر بعد ذلك الزر Add لإضافة هذه الصفحة إلى المشروع. ستحصل على الرماز التالي بشكل افتراضي ضمن هذه الصفحة:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9500_19">
<span class="lit">1</span><span class="pln">	</span><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
</span><span class="lit">2</span><span class="pln">	</span><span class="pun">&lt;</span><span class="typ">ContentPage</span><span class="pln"> xmlns</span><span class="pun">=</span><span class="str">"http://xamarin.com/schemas/2014/forms"</span><span class="pln">
</span><span class="lit">3</span><span class="pln">	             xmlns</span><span class="pun">:</span><span class="pln">x</span><span class="pun">=</span><span class="str">"http://schemas.microsoft.com/winfx/2009/xaml"</span><span class="pln">
</span><span class="lit">4</span><span class="pln">	             x</span><span class="pun">:</span><span class="typ">Class</span><span class="pun">=</span><span class="str">"XamlDemoApp.XamlDemoPage"</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">5</span><span class="pln">	  </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"{Binding MainText}"</span><span class="pln"> </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln"> </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">6</span><span class="pln">	</span><span class="pun">&lt;/</span><span class="typ">ContentPage</span><span class="pun">&gt;</span></pre>

<p>
	يحتوي السطر الأوّل على إصدار XML المُستَخدم، أمّا السطر الثاني فيحتوي على عنصر ContentPage مما يشير إلى أنّنا فعليًّا نضيف صفحة محتوى content page ليس إلّا. يحتوي العنصر ContentPage على سمتين xmlns وxmlns:x وهما سمتان تعريفيّتان، أمّا السمة x:Class فهي تُشير إلى الصنف المرتبط مع هذه الصفحة وهو كما يظهر XamlDemoApp.XamlDemoPage حيث XamlDemoApp هو نطاق الاسم الخاص بالتطبيق. سنرى أين يوجد هذا الصنف بعد قليل. يحتوي السطر 5 على عنصر Label تجريبي يتم توليده بشكل افتراضي. أمّا في السطر السادس فيوجد عنصر الإغلاق لعنصر الفتح الموافق الموجود في السطر 2 وذلك كما هو متبع في XML.
</p>

<p>
	في الواقع عندما يضيف Visual Studio الملف XamlDemoPage.xaml فإنّه يضيف بشكل تلقائي الملف XamlDemoPage.xaml.cs أيضًا. واضح أنّ امتداد هذا الملف cs أي أنّه يحتوي على شيفرة سي شارب. انظر إلى الشكل التالي الذي يمثّل مستكشف الحل Solution Explorer بعد إضافة ملف المحتوى:
</p>

<p style="text-align: center;">
	<img alt="fig03.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22536" data-unique="0xnc3z8gy" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig03.png.41e95d929a5d596166449497474d6eca.png"></p>

<p>
	الملف XamlDemoPage.xaml.cs هو ملف الشيفرة البرمجيّة المرافق لملف الواجهة XamlDemoPage.xaml ويحتوي على الصنف XamlDemoApp.XamlDemoPage الذي تحدثنا عنه قبل قليل. يحتوي هذا الصنف على معالجات أحداث event handlers تستجيب للأحداث المختلفة التي قد تحدث ضمن ملف الواجهة والناتجة عن مختلف أنواع العناصر المرئيّة الموجودة ضمنها.
</p>

<p>
	لنعد الآن إلى الملف XamlDemoPage.xaml، احذف العنصر Label الافتراضي الموجود في هذا الملف. سنضيف عناصر مرئيّة جديدة. احرص على أن تكون محتويات الملف XamlDemoPage.xaml على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9500_17">
<span class="lit">1</span><span class="pln">	</span><span class="pun">&lt;?</span><span class="pln">xml version</span><span class="pun">=</span><span class="str">"1.0"</span><span class="pln"> encoding</span><span class="pun">=</span><span class="str">"utf-8"</span><span class="pln"> </span><span class="pun">?&gt;</span><span class="pln">
</span><span class="lit">2</span><span class="pln">	</span><span class="pun">&lt;</span><span class="typ">ContentPage</span><span class="pln"> xmlns</span><span class="pun">=</span><span class="str">"http://xamarin.com/schemas/2014/forms"</span><span class="pln">
</span><span class="lit">3</span><span class="pln">	             xmlns</span><span class="pun">:</span><span class="pln">x</span><span class="pun">=</span><span class="str">"http://schemas.microsoft.com/winfx/2009/xaml"</span><span class="pln">
</span><span class="lit">4</span><span class="pln">	             x</span><span class="pun">:</span><span class="typ">Class</span><span class="pun">=</span><span class="str">"XamlDemoApp.XamlDemoPage"</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">5</span><span class="pln">	  
</span><span class="lit">6</span><span class="pln">	  </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pln"> </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"CenterAndExpand"</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">7</span><span class="pln">	    </span><span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pun">.</span><span class="typ">Children</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">8</span><span class="pln">	      </span><span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"Start"</span><span class="pln">
</span><span class="lit">9</span><span class="pln">	             </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln">       
</span><span class="lit">10</span><span class="pln">	             </span><span class="typ">FontSize</span><span class="pun">=</span><span class="str">"Large"</span><span class="pln">
</span><span class="lit">11</span><span class="pln">	             </span><span class="typ">TextColor</span><span class="pun">=</span><span class="str">"Accent"</span><span class="pln">
</span><span class="lit">12</span><span class="pln">	             x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"lblCurrentTime"</span><span class="pln">
</span><span class="lit">13</span><span class="pln">	             </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"Click the button!"</span><span class="pln"> </span><span class="pun">/&gt;</span><span class="pln">
</span><span class="lit">14</span><span class="pln">	  
</span><span class="lit">15</span><span class="pln">	      </span><span class="pun">&lt;</span><span class="typ">Button</span><span class="pln"> </span><span class="typ">VerticalOptions</span><span class="pun">=</span><span class="str">"End"</span><span class="pln">
</span><span class="lit">16</span><span class="pln">	              </span><span class="typ">HorizontalOptions</span><span class="pun">=</span><span class="str">"Center"</span><span class="pln">
</span><span class="lit">17</span><span class="pln">	              </span><span class="typ">FontSize</span><span class="pun">=</span><span class="str">"Medium"</span><span class="pln">
</span><span class="lit">18</span><span class="pln">	              x</span><span class="pun">:</span><span class="typ">Name</span><span class="pun">=</span><span class="str">"btnGetTime"</span><span class="pln">
</span><span class="lit">19</span><span class="pln">	              </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"Get Current Time"</span><span class="pln">
</span><span class="lit">20</span><span class="pln">	              </span><span class="typ">Clicked</span><span class="pun">=</span><span class="str">"btnGetCurrentTime_Clicked"</span><span class="pun">/&gt;</span><span class="pln">  
</span><span class="lit">21</span><span class="pln">	    </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">.</span><span class="typ">Children</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">22</span><span class="pln">	  </span><span class="pun">&lt;/</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">
</span><span class="lit">23</span><span class="pln">	  
</span><span class="lit">24</span><span class="pln">	</span><span class="pun">&lt;/</span><span class="typ">ContentPage</span><span class="pun">&gt;</span></pre>

<p>
	يحتوي رماز XAML السابق على العديد من المفاهيم الجديدة ولكن البسيطة والتي سنلخّصها من خلال النقاط التالية:
</p>

<ul>
<li>
		يضم الرماز واجهة بسيطة تتكوّن من لصيقة وزر عند نقره سيعرض الوقت الحالي على اللصيقة الموجودة فوقه. كلّ من هذين العنصرين سيكونان ضمن مخطّط مكدّس StackLayout. يبدأ هذا المخطّط في السطر 6 ويحوي سمة (خاصيّة) وحيدة هي VerticalOptions وتحمل القيمة CenterAndExpand.
	</li>
	<li>
		يمثّل عنصر XAML الموجود في السطر 7 وهو <stacklayout.children> الخاصيّة Children لعنصر المكدّس StackLayout. نضع ضمن هذه الخاصيّة كما اعتدنا من قبل العناصر المرئيّة التي نرغب بوجودها ضمن المكدّس، وهذا ما سنفعله تمامًا بوضع عنصر اللصيقة (الأسطر من 8 حتى 13) وعنصر الزر (الأسطر من 15 حتى 20) ضمنه. وكما هو الحال بالنسبة لأي عنصر XML يجب إغلاق العنصر <stacklayout.children> بوسم إغلاق </stacklayout.children> موافق له، وهذا ما فعلناه في السطر 21. </stacklayout.children>
</li>
	<li>
		<stacklayout.children>بالنسبة لعنصر اللصيقة، تمثّل السمات الموجودة ضمنها خصائص الصنف Label التي كنّا نتعامل معها في الشيفرة البرمجيّة في السابق. يوجد أمر بسيط هنا، وهو أنّ عنصر اللصيقة لا يوجد له وسم إغلاق مثل . في الحقيقة لا داعي له أبدًا، لأنّ اللصيقة لا يمكنها أن تحوي عناصر أخرى كما هو الحال بالنسبة لمخطّط المكدّس مثلًا. لقد أغلقنا اللصيقة بالرمزين /&gt; فحسب، كما فعلنا مع الزر في السطر 20 تمامًا. </stacklayout.children>
</li>
	<li>
		<stacklayout.children>توجد سمة اسمها x:Name ضمن عنصر اللصيقة (السطر 12) وأيضًا ضمن عنصر الزر (السطر 18). يمكن من خلال هذه السمة الوصول للعناصر المرئيّة وذلك من خلال الشيفرة البرمجيّة وهذا ما سنراه بعد قليل. في الواقع كان من الممكن ألًّا نستخدم هذه السمة مع عنصر الزر لأنّنا لا نحتاج إلى أن نصل إلى خصائصه بالنسبة لهذا البرنامج. </stacklayout.children>
</li>
	<li>
		<stacklayout.children>معالج حدث النقر Clicked للزر في السطر 20. أسميته btnGetCurrentTime_Clicked، وهو غير موجود في هذا الملف بالطبع. يحتوي هذا الملف على شيفرة برمجيّة بلغة سي شارب تنفّذ المهمّة المطلوبة عند نقر هذا الزر. </stacklayout.children>
</li>
</ul>
<p>
	<stacklayout.children>سيكون معالج الحدث btnGetCurrentTime_Clicked موجودًا في الملف XamlDemoPage.xaml.cs ضمن الصنف XamlDemoPage. انتقل إلى هذا الملف واحرص أن تكون محتوياته على الشكل التالي:</stacklayout.children></p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9500_15">
<span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Globalization</span><span class="pun">;</span><span class="pln">
</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">

</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">XamlDemoApp</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">public</span><span class="pln"> partial </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">XamlDemoPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">XamlDemoPage</span><span class="pun">()</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            </span><span class="typ">InitializeComponent</span><span class="pun">();</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">

        </span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> btnGetCurrentTime_Clicked</span><span class="pun">(</span><span class="pln">object sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">EventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            lblCurrentTime</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">DateTime</span><span class="pun">.</span><span class="typ">Now</span><span class="pun">.</span><span class="typ">ToString</span><span class="pun">(</span><span class="str">"h:mm:ss tt"</span><span class="pun">,</span><span class="pln"> 
                                                </span><span class="typ">CultureInfo</span><span class="pun">.</span><span class="typ">InvariantCulture</span><span class="pun">);</span><span class="pln">
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">}</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	توجد الشيفرة المسؤولة عن إظهار الوقت الحالي على اللصيقة ضمن معالج الحدث btnGetCurrentTime_Clicked كما هو واضح (يمكنك فهم هذه الشيفرة من خلال الانتقال إلى <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-%D8%B9%D9%85%D9%84%D9%8A%D9%91%D8%A9-%D8%AD%D9%88%D9%84-%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D9%82%D9%8A%D8%A7%D8%B3%D8%A7%D8%AA-%D9%81%D9%8A-xamarin-r414/" rel="">هذا الدرس</a> ومراجعة تطبيق الساعة الرقميّة). انتقل إلى الملف App.cs وتأكّد أنّ بانيته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9500_13">
<span class="kwd">public</span><span class="pln"> </span><span class="typ">App</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="com">// The root page of your application</span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">XamlDemoPage</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	نفّذ البرنامج باستخدام F5 ثم انقر الزر Get Current Time لتحصل على الوقت الحالي ضمن اللصيقة. انظر إلى الشكل التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22537" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig04.png.e567e2b8caeff15ddf6fff42872f4b83.png" rel=""><img alt="fig04.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22537" data-unique="dj0vczmgv" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig04.thumb.png.f9570f0f2dd6771cea44c490234a85eb.png"></a>
</p>

<p>
	هناك أمران ملفتان في الشيفرة السابقة:
</p>

<ul>
<li>
		أسندنا قيمة الوقت الحالي إلى الخاصيّة Text من المتغيّر lblCurrentTime الذي يحمل نفس اسم اللصيقة التي صرّحنا عنها في ملف الواجهة. ولكن من أين أتي هذا المتغيّر إذا لم نصرّح عنه مطلقًا في ملف الشيفرة الحالي؟
	</li>
	<li>
		لاحظ وجود استدعاء للتابع InitializeComponent ضمن بانية الصنف XamlDemoPage. هذا التابع ليس موجودًا ضمن الصنف ContentPage الذي يرث منه صنفنا XamlDemoPage، وهذا يعني أنّه يجب أن يكون ضمن الصنف XamlDemoPage ولكن هذا ما لا نراه أمامنا!
	</li>
</ul>
<p>
	الحيلة المستخدمة هنا هو في وجود الكلمة المحجوزة partial ضمن التصريح عن الصنف XamlDemoPage. تشير الكلمة partial إلى وجود جزء آخر لهذا الصنف ولكن في مكان ما! في الواقع هذا الجزء موجود بالفعل ولكن ضمن الملف XamlDemoApp.XamlDemoPage.xaml.g.cs. بما أنَّ هذا الملف له الامتداد cs هذا يعني أنّه يحتوي على شيفرة مكتوبة بلغة سي شارب، كما أنّ اسمه (الطويل نسبيًّا) مكوّن من نطاق الاسم واسم الصنف XamlDemoApp.XamlDemoPage ثم المقطع xaml للإشارة إلى أنّه متعلّق بملف الواجهة الذي يحتوي على رماز XAML والمقطع g الذي يأتي من الكلمة generated للإشارة إلى أنّ هذا الملف يتمّ توليده تلقائيًّا. إذا أردت مشاهدة الملف فاذهب إلى مستكشف الحل Solution Explorer ثم انقل على زر إظهار جميع الملفات Show All Files لتظهر المجلّدات والملفات الموجودة ضمن المشروع. انتقل إلى المجلّد obj ثم انشره لترى محتوياته. ستلاحظ وجود المجلّد Debug فقط ضمنه. انشره أيضًا لتصل إلى الملفات التي ضمنه حيث ستجد عندها الملف XamlDemoApp.XamlDemoPage.xaml.g.cs. انظر إلى الشكل التالي:
</p>

<p style="text-align: center;">
	<img alt="fig05.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22538" data-unique="gs40goto1" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig05.png.673a3ab350a62208c7a91258c28fac57.png"></p>

<p>
	انقره نقرًا مزدوجًا لترى محتوياته. ستجد الصنف XamlDemoPage مرّة أخرى، وهذا هو الجزء الذي نبحث عنه:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9500_11">
<span class="lit">1</span><span class="pln">	</span><span class="kwd">public</span><span class="pln"> partial </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">XamlDemoPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> global</span><span class="pun">::</span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">.</span><span class="typ">ContentPage</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="lit">2</span><span class="pln">	        
</span><span class="lit">3</span><span class="pln">	        </span><span class="pun">[</span><span class="typ">System</span><span class="pun">.</span><span class="typ">CodeDom</span><span class="pun">.</span><span class="typ">Compiler</span><span class="pun">.</span><span class="typ">GeneratedCodeAttribute</span><span class="pun">(</span><span class="str">"Xamarin.Forms.Build.Tasks.XamlG"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"0.0.0.0"</span><span class="pun">)]</span><span class="pln">
</span><span class="lit">4</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> global</span><span class="pun">::</span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">.</span><span class="typ">Label</span><span class="pln"> lblCurrentTime</span><span class="pun">;</span><span class="pln">
</span><span class="lit">5</span><span class="pln">	        
</span><span class="lit">6</span><span class="pln">	        </span><span class="pun">[</span><span class="typ">System</span><span class="pun">.</span><span class="typ">CodeDom</span><span class="pun">.</span><span class="typ">Compiler</span><span class="pun">.</span><span class="typ">GeneratedCodeAttribute</span><span class="pun">(</span><span class="str">"Xamarin.Forms.Build.Tasks.XamlG"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"0.0.0.0"</span><span class="pun">)]</span><span class="pln">
</span><span class="lit">7</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> global</span><span class="pun">::</span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">.</span><span class="typ">Button</span><span class="pln"> btnGetTime</span><span class="pun">;</span><span class="pln">
</span><span class="lit">8</span><span class="pln">	        
</span><span class="lit">9</span><span class="pln">	        </span><span class="pun">[</span><span class="typ">System</span><span class="pun">.</span><span class="typ">CodeDom</span><span class="pun">.</span><span class="typ">Compiler</span><span class="pun">.</span><span class="typ">GeneratedCodeAttribute</span><span class="pun">(</span><span class="str">"Xamarin.Forms.Build.Tasks.XamlG"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"0.0.0.0"</span><span class="pun">)]</span><span class="pln">
</span><span class="lit">10</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> </span><span class="typ">InitializeComponent</span><span class="pun">()</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="lit">11</span><span class="pln">	            </span><span class="kwd">this</span><span class="pun">.</span><span class="typ">LoadFromXaml</span><span class="pun">(</span><span class="kwd">typeof</span><span class="pun">(</span><span class="typ">XamlDemoPage</span><span class="pun">));</span><span class="pln">
</span><span class="lit">12</span><span class="pln">	            lblCurrentTime </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="typ">FindByName</span><span class="pun">&lt;</span><span class="pln">global</span><span class="pun">::</span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">.</span><span class="typ">Label</span><span class="pun">&gt;(</span><span class="str">"lblCurrentTime"</span><span class="pun">);</span><span class="pln">
</span><span class="lit">13</span><span class="pln">	            btnGetTime </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">this</span><span class="pun">.</span><span class="typ">FindByName</span><span class="pun">&lt;</span><span class="pln">global</span><span class="pun">::</span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">.</span><span class="typ">Button</span><span class="pun">&gt;(</span><span class="str">"btnGetTime"</span><span class="pun">);</span><span class="pln">
</span><span class="lit">14</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">15</span><span class="pln">	    </span><span class="pun">}</span></pre>

<p>
	سنجد في السطر 4 التصريح عن المتغيّر lblCurrentTime الذي سيعمل التابع InitializeComponent (الأسطر من 10 حتى 15) على ربطه مع اللصيقة المصرّح عنها ضمن ملف الواجهة. كما أشرنا فإنّ هذا الملف يتم توليده تلقائيًّا وذلك بمجرّد إجراء أي عمليّة حفظ على الملف XamlDemoPage.xaml الذي يحتوي على واجهة التطبيق.
</p>

<blockquote>
	<p>
		 
	</p>

	<blockquote class="ipsQuote" data-ipsquote="">
		<div class="ipsQuote_citation">
			Quote
		</div>

		<div class="ipsQuote_contents ipsClearfix">
			<p>
				أيُّ عنصر يحتوي على عناصر أخرى ينبغي أن يكون له وسم فتح ووسم إغلاق، بحيث تُوضع العناصر المطلوبة بين هذين الوسمين مثل:
			</p>

			<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9500_7">

<span class="pun">&lt;</span><span class="typ">StackLayout</span><span class="pun">&gt;</span><span class="pln">
	</span><span class="pun">-</span><span class="typ">Other</span><span class="pln"> elements</span><span class="pun">-</span><span class="pln">
</span><span class="pun">&lt;/</span><span class="pln"> </span><span class="typ">StackLayout</span><span class="pln"> </span><span class="pun">&gt;</span></pre>

			<p>
				أمّا بالنسبة للعناصر التي لا تحتوي عناصر أخرى، فمن الممكن أن نكتفي بوسم فتح فقط ونغلقه باستخدام الرمزين /&gt; مثل:
			</p>

			<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9500_9">

<span class="pun">&lt;</span><span class="typ">Label</span><span class="pln"> </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Hello"</span><span class="pln"> </span><span class="pun">/&gt;</span></pre>

			<p>
				 
			</p>
		</div>
	</blockquote>

	<pre>
<code>
</code></pre>
</blockquote>

<h3>
	الخلاصة
</h3>

<p>
	تعلّمنا في هذه الدرس المبادئ الأساسيّة لبناء الواجهات باستخدام رماز XAML بدلًا عن أسلوب الشيفرة التي اعتمدناه في الدروس السابقة. ستلمس الفائدة العظيمة لبناء الواجهات بهذا الأسلوب عندما تبدأ ببناء تطبيقات واقعيّة، حيث سيجعل هذا الأسلوب من عمليّة بناء التطبيق أمرًا يسيرًا وواضحًا من خلال فصل الواجهة بما تحتويه من عناصر مرئيّة عن الشيفرة البرمجيّة المخصّصة للتفاعل مع هذه الواجهة، وذلك ضمن ملفّين منفصلين. تساعد هذه العمليّة على ترتيب البرامج وجعلها أسهل للفهم وللصيانة وللتطوير المستقبلي، وخصوصًا عندما تصبح البرامج أكبر ومعقّدة أكثر. هنالك الكثير مما يمكن قوله حول هذه التقنيّة سنتناول ذلك تباعًا من خلال الدروس القادمة. سنبني في الدرس القادم تطبيق عملي رياضيّاتيّ مفيد يتمثّل في حل معادلة من الدرجة الثانيّة حيث سنبني واجهة التطبيق من خلال XAML.
</p>
]]></description><guid isPermaLink="false">453</guid><pubDate>Wed, 23 Nov 2016 21:00:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x639;&#x646;&#x627;&#x635;&#x631; &#x627;&#x644;&#x645;&#x631;&#x626;&#x64A;&#x651;&#x629; &#x627;&#x644;&#x634;&#x627;&#x626;&#x639;&#x629; &#x641;&#x64A; Xamarin &#x2013; &#x627;&#x644;&#x62C;&#x632;&#x621; &#x627;&#x644;&#x62B;&#x627;&#x646;&#x64A;</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%A7%D9%84%D8%B9%D9%86%D8%A7%D8%B5%D8%B1-%D8%A7%D9%84%D9%85%D8%B1%D8%A6%D9%8A%D9%91%D8%A9-%D8%A7%D9%84%D8%B4%D8%A7%D8%A6%D8%B9%D8%A9-%D9%81%D9%8A-xamarin-%E2%80%93-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%AB%D8%A7%D9%86%D9%8A-r456/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.01372a4ca78fe2570e0c61cfccde6543.png" /></p>

<p>
	سنتابع عملنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/" rel="">سلسلة تعلّم تطوير تطبيقات أندرويد باستخدام Xamarin.Forms</a> مع الجزء الثاني للعناصر المرئيّة الشائعة في Xamarin.Forms. تناولنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A7%D9%84%D8%B9%D9%86%D8%A7%D8%B5%D8%B1-%D8%A7%D9%84%D9%85%D8%B1%D8%A6%D9%8A%D9%91%D8%A9-%D8%A7%D9%84%D8%B4%D8%A7%D8%A6%D8%B9%D8%A9-%D9%81%D9%8A-xamarin-%E2%80%93-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%A3%D9%88%D9%91%D9%84-r455/" rel="">الجزء الأوّل</a> بعضًا من هذه العناصر حيث تحدثنا عن عناصر القائمة ListView وحقل الإدخال Entry وعنصر تحويل الحالة المنطقيّة Switch كما تحدثنا أيضًا عن عنصر المنزلق Slider.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22554" data-unique="j6uapmu66" src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.a457ee546be40157440bd87180ab6965.png"></p>

<p>
	سنتحدّث في هذا الدرس عن عنصر DatePicker الذي يسمح باختيار تاريخ محدّد بطريقة جميلة، كما سنتحدّث عن عنصر الاختيار الخطوي Stepper الذي يشبه عنصر المنزلق Slider، وأيضًا عنصر الإطار Frame الذي يُستَخدم لتعزيز الناحية الجمالية لواجهة المستخدم. سنتناول تطبيقين عمليّين لتوضيح عمل هذه العناصر.
</p>

<h3>
	تطبيق التحكّم بعرض الحدود
</h3>

<p>
	وهو تطبيق بسيط للغاية، الغرض منه توضيح كيفيّة استخدام العنصر Stepper. يمتلك هذا العنصر بنية برمجيّة شبيهة بعنصر المنزلق Slider الذي تحدثنا عنه في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A7%D9%84%D8%B9%D9%86%D8%A7%D8%B5%D8%B1-%D8%A7%D9%84%D9%85%D8%B1%D8%A6%D9%8A%D9%91%D8%A9-%D8%A7%D9%84%D8%B4%D8%A7%D8%A6%D8%B9%D8%A9-%D9%81%D9%8A-xamarin-%E2%80%93-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%A3%D9%88%D9%91%D9%84-r455/" rel="">الدرس السابق</a>، رغم أنّه يختلف عنه من الناحية الشكليّة، فهذا العنصر يتكوّن من زرّين متجاورين يظهر عليهما النصّان "+" و "-". توجد ميزة إضافية في هذا العنصر تتمثّل في وجود خاصيّة اسمها Increment قيمتها الافتراضيّة 1. وتُستخدم لتحديد مقدار الزيادة أو النقصان عند كل نقرة على الزرّين السابقين كما سنرى بعد قليل. يُستخدم عنصر Stepper غالبًا لاختيار قيم عدديّة صحيحة (بدون فاصلة عشريّة) مع أنّه من الممكن استخدام القيم العشرية معه.
</p>

<p>
	أنشئ مشروعًا من النوع Blank App (Xamarin.Forms Portable) وسمّه StepperDemoApp، ثم أبق فقط على المشروعين StepperDemoApp (Portable) و StepperDemoApp.Droid كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-visual-studio-2015-community-%D9%88%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-xamarin-%D9%84%D9%84%D8%B9%D9%85%D9%84-r373/" rel="">هذا الدرس</a>. بعد ذلك أضف صفحة محتوى جديدة كما فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D9%86%D8%B5%D9%88%D8%B5-%D9%81%D9%8A-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-r386/" rel="">هذا الدرس</a> وسمّها StepperDemoPage. احرص على أن تكون محتويات الملف StepperDemoPage.cs على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1473_7">
<span class="lit">1</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">
</span><span class="lit">2</span><span class="pln">	
</span><span class="lit">3</span><span class="pln">	</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">StepperDemoApp</span><span class="pln">
</span><span class="lit">4</span><span class="pln">	</span><span class="pun">{</span><span class="pln">
</span><span class="lit">5</span><span class="pln">	    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">StepperDemoPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
</span><span class="lit">6</span><span class="pln">	    </span><span class="pun">{</span><span class="pln">
</span><span class="lit">7</span><span class="pln">	        </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">StepperDemoPage</span><span class="pun">()</span><span class="pln">
</span><span class="lit">8</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">9</span><span class="pln">	            </span><span class="typ">Button</span><span class="pln"> btnDemo </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">
</span><span class="lit">10</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">11</span><span class="pln">	                </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"اختبار سماكة حدود الزر"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">12</span><span class="pln">	                </span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Device</span><span class="pun">.</span><span class="typ">GetNamedSize</span><span class="pun">(</span><span class="typ">NamedSize</span><span class="pun">.</span><span class="typ">Large</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">typeof</span><span class="pun">(</span><span class="typ">Button</span><span class="pun">)),</span><span class="pln">
</span><span class="lit">13</span><span class="pln">	                </span><span class="typ">BorderColor</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Color</span><span class="pun">.</span><span class="typ">FromHex</span><span class="pun">(</span><span class="str">"C0C0C0"</span><span class="pun">),</span><span class="pln">
</span><span class="lit">14</span><span class="pln">	                </span><span class="typ">BackgroundColor</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Color</span><span class="pun">.</span><span class="typ">FromHex</span><span class="pun">(</span><span class="str">"404040"</span><span class="pun">),</span><span class="pln">
</span><span class="lit">15</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">Center</span><span class="pun">,</span><span class="pln">
</span><span class="lit">16</span><span class="pln">	                </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">CenterAndExpand</span><span class="pln">
</span><span class="lit">17</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">18</span><span class="pln">	
</span><span class="lit">19</span><span class="pln">	            </span><span class="typ">Label</span><span class="pln"> lblCurrentBorderWidth </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Label</span><span class="pln">
</span><span class="lit">20</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">21</span><span class="pln">	                </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"السماكة الحالية: 0"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">22</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">FillAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">23</span><span class="pln">	                </span><span class="typ">HorizontalTextAlignment</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">TextAlignment</span><span class="pun">.</span><span class="typ">Center</span><span class="pln">
</span><span class="lit">24</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">25</span><span class="pln">	
</span><span class="lit">26</span><span class="pln">	            </span><span class="typ">Stepper</span><span class="pln"> stepper </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Stepper</span><span class="pln">
</span><span class="lit">27</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">28</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">Center</span><span class="pun">,</span><span class="pln">
</span><span class="lit">29</span><span class="pln">	                </span><span class="typ">Maximum</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">10</span><span class="pun">,</span><span class="pln">
</span><span class="lit">30</span><span class="pln">	                </span><span class="typ">Minimum</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pln">
</span><span class="lit">31</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">32</span><span class="pln">	            stepper</span><span class="pun">.</span><span class="typ">ValueChanged</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">s</span><span class="pun">,</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
</span><span class="lit">33</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">34</span><span class="pln">	                btnDemo</span><span class="pun">.</span><span class="typ">BorderWidth</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> stepper</span><span class="pun">.</span><span class="typ">Value</span><span class="pun">;</span><span class="pln">
</span><span class="lit">35</span><span class="pln">	
</span><span class="lit">36</span><span class="pln">	                lblCurrentBorderWidth</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"السماكة الحالية: "</span><span class="pln"> </span><span class="pun">+</span><span class="pln"> stepper</span><span class="pun">.</span><span class="typ">Value</span><span class="pun">.</span><span class="typ">ToString</span><span class="pun">();</span><span class="pln">
</span><span class="lit">37</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">38</span><span class="pln">	            
</span><span class="lit">39</span><span class="pln">	            </span><span class="typ">StackLayout</span><span class="pln"> changeBorderWidthSLayout </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StackLayout</span><span class="pln">
</span><span class="lit">40</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">41</span><span class="pln">	                </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">CenterAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">42</span><span class="pln">	                </span><span class="typ">Children</span><span class="pln"> </span><span class="pun">=</span><span class="pln">
</span><span class="lit">43</span><span class="pln">	                </span><span class="pun">{</span><span class="pln">
</span><span class="lit">44</span><span class="pln">	                    lblCurrentBorderWidth</span><span class="pun">,</span><span class="pln">
</span><span class="lit">45</span><span class="pln">	                    stepper
</span><span class="lit">46</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">47</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">48</span><span class="pln">	
</span><span class="lit">49</span><span class="pln">	            </span><span class="typ">Content</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StackLayout</span><span class="pln">
</span><span class="lit">50</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">51</span><span class="pln">	                </span><span class="typ">Children</span><span class="pln"> </span><span class="pun">=</span><span class="pln">
</span><span class="lit">52</span><span class="pln">	                </span><span class="pun">{</span><span class="pln">
</span><span class="lit">53</span><span class="pln">	                    btnDemo</span><span class="pun">,</span><span class="pln">
</span><span class="lit">54</span><span class="pln">	                    changeBorderWidthSLayout
</span><span class="lit">55</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">56</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">57</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">58</span><span class="pln">	    </span><span class="pun">}</span><span class="pln">
</span><span class="lit">59</span><span class="pln">	</span><span class="pun">}</span></pre>

<p>
	انتقل إلى الملف App.cs واحرص على أن تكون بانية الصنف App على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1473_9">
<span class="kwd">public</span><span class="pln"> </span><span class="typ">App</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="com">// The root page of your application</span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StepperDemoPage</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	نفّذ البرنامج باستخدام F5، ثم تفاعل مع التطبيق بنقر الزرّين "+" و "-" لتحصل على شكل شبيه بما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22556" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.png.4f1bba6fbfa7fa7e955208aced92c678.png" rel=""><img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22556" data-unique="mld9v8hll" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.thumb.png.f58152cd4eb16112a7e05c500f223fa9.png"></a>
</p>

<p>
	يتكوّن التطبيق من زر في الأعلى يحوي النص "اختبار سماكة الحدود" بالإضافة إلى عنصر Stepper يسمح لك بضبط قيمة الحدود لهذا الزر، وأيضًا توجد لصيقة صغيرة تعلو العنصر Stepper وظيفتها عرض القيمة الحالية المختارة لسماكة حد الزر. صرّحنا في الأسطر من 9 حتى 17 عن عنصر زر جديد وأسندناه إلى المتغيّر btnDemo. لقد جعلنا الخط المُستخدَم في هذا الزر كبيرًا، وأيضًا ضبطنا لون الحد عن طريق الخاصيّة BorderColor (السطر 13) ليكون هذا اللون "C0C0C0" وهي قيمة ست عشرية تتكوّن من 3 مكوّنات لونية هي من اليسار إلى اليمين: الأحمر والأخضر والأزرق بحيث يأخذ كل مكوّن لوني محرفين. فمن خلال القيمة "C0C0C0" سيأخذ كل من الأحمر والأخضر والأزرق القيمة C0 وهي حالة خاصّة بالطبع وسنحصل من خلالها على أحد تدرّجات اللون الرمادي. بنفس الأسلوب قمنا بضبط لون الخلفيّة لهذا الزر من خلال الخاصيّة BackgroundColor (السطر 14) ليكون "404040" وهو أيضًا أحد تدرّجات الرمادي. يمكنك اختيار أيّ لون ترغبه.
</p>

<p>
	سنضع كلًّا من اللصيقة المسؤولة عن عرض قيمة الحد الحالي lblCurrentBorderWidth (الأسطر من 19 حتى 24) وأيضًا عنصر الاختيار الخطوي stepper (الأسطر من 26 حتى 31) ضمن مخطّط مكدّس ليظهرا متجاورين رأسيًّا. مخطّط المكدّس هذا مصرّح عنه في الأسطر من 39 حتى 47 عن طريق المتغيّر changeBorderWidthSLayout. لاحظ أخيرًا أنّنا قد صرّحنا عن معالج الحدث ValueChanged للعنصر stepper بصورة مماثلة تمامًا لما فعلناه مع عنصر المنزلق Slider في الدرس السابق، وذلك في الأسطر من 32 حتى 37 لكي نعالج نقرات المستخدم على هذا العنصر، وبنفس الوقت نحدّث قيمة اللصيقة لتعرض السماكة الحاليّة لحدود الزر (السطر 36).
</p>

<h3>
	تطبيق حساب العمر بالأيّام
</h3>

<p>
	نحتاج لإنجاز هذا التطبيق إلى عنصر DatePicker لاختيار تاريخ الولادة، وعنصر Frame لإكساب صفة جمالية على التطبيق كما سنرى، كما سنحتاج إلى زر لإجراء عمليّة الحساب ولصيقة لعرض النتيجة. سيتم حساب العمر الحالي بالأيّام من تاريخ الولادة حتى تاريخ اليوم. أنشئ مشروعًا من النوع Blank App (Xamarin.Forms Portable) وسمّه AgeCalculatorApp، ثم أبق فقط على المشروعين AgeCalculatorApp (Portable) وAgeCalculatorApp.Droid. بعد ذلك أضف صفحة محتوى جديدة وسمّها AgeCalculatorPage. احرص على أن تكون محتويات الملف AgeCalculatorPage.cs على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1473_11">
<span class="lit">1</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">;</span><span class="pln">
</span><span class="lit">2</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">
</span><span class="lit">3</span><span class="pln">	
</span><span class="lit">4</span><span class="pln">	</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">AgeCalculatorApp</span><span class="pln">
</span><span class="lit">5</span><span class="pln">	</span><span class="pun">{</span><span class="pln">
</span><span class="lit">6</span><span class="pln">	    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">AgeCalculatorPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
</span><span class="lit">7</span><span class="pln">	    </span><span class="pun">{</span><span class="pln">
</span><span class="lit">8</span><span class="pln">	        </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">AgeCalculatorPage</span><span class="pun">()</span><span class="pln">
</span><span class="lit">9</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">10</span><span class="pln">	            </span><span class="typ">Frame</span><span class="pln"> frmWelcome </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Frame</span><span class="pln">
</span><span class="lit">11</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">12</span><span class="pln">	                </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">Start</span><span class="pun">,</span><span class="pln">
</span><span class="lit">13</span><span class="pln">	                </span><span class="typ">Padding</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Thickness</span><span class="pun">(</span><span class="lit">15</span><span class="pun">),</span><span class="pln">
</span><span class="lit">14</span><span class="pln">	                </span><span class="typ">BackgroundColor</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Color</span><span class="pun">.</span><span class="typ">FromRgba</span><span class="pun">(</span><span class="typ">Color</span><span class="pun">.</span><span class="typ">Accent</span><span class="pun">.</span><span class="pln">R</span><span class="pun">,</span><span class="pln"> 
</span><span class="lit">15</span><span class="pln">	                                                </span><span class="typ">Color</span><span class="pun">.</span><span class="typ">Accent</span><span class="pun">.</span><span class="pln">G</span><span class="pun">,</span><span class="pln"> 
</span><span class="lit">16</span><span class="pln">	                                                </span><span class="typ">Color</span><span class="pun">.</span><span class="typ">Accent</span><span class="pun">.</span><span class="pln">B</span><span class="pun">,</span><span class="pln">
</span><span class="lit">17</span><span class="pln">	                                                </span><span class="lit">0.2</span><span class="pun">),</span><span class="pln">
</span><span class="lit">18</span><span class="pln">	                </span><span class="typ">OutlineColor</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Color</span><span class="pun">.</span><span class="typ">Accent</span><span class="pun">,</span><span class="pln">
</span><span class="lit">19</span><span class="pln">	                </span><span class="typ">Content</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Label</span><span class="pln">
</span><span class="lit">20</span><span class="pln">	                </span><span class="pun">{</span><span class="pln">
</span><span class="lit">21</span><span class="pln">	                    </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"تطبيق حساب العمر بالأيّام"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">22</span><span class="pln">	                    </span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Device</span><span class="pun">.</span><span class="typ">GetNamedSize</span><span class="pun">(</span><span class="typ">NamedSize</span><span class="pun">.</span><span class="typ">Large</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">typeof</span><span class="pun">(</span><span class="typ">Label</span><span class="pun">)),</span><span class="pln">
</span><span class="lit">23</span><span class="pln">	                    </span><span class="typ">TextColor</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Color</span><span class="pun">.</span><span class="typ">Aqua</span><span class="pun">,</span><span class="pln">
</span><span class="lit">24</span><span class="pln">	                    </span><span class="typ">HorizontalTextAlignment</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">TextAlignment</span><span class="pun">.</span><span class="typ">Center</span><span class="pln">
</span><span class="lit">25</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">26</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">27</span><span class="pln">	             
</span><span class="lit">28</span><span class="pln">	
</span><span class="lit">29</span><span class="pln">	            </span><span class="typ">DatePicker</span><span class="pln"> birthDate </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">DatePicker</span><span class="pln">
</span><span class="lit">30</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">31</span><span class="pln">	                </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">Start</span><span class="pun">,</span><span class="pln">
</span><span class="lit">32</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">FillAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">33</span><span class="pln">	                
</span><span class="lit">34</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">35</span><span class="pln">	
</span><span class="lit">36</span><span class="pln">	            </span><span class="typ">Label</span><span class="pln"> lblCurrentDate </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Label</span><span class="pln">
</span><span class="lit">37</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">38</span><span class="pln">	                </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">DateTime</span><span class="pun">.</span><span class="typ">Now</span><span class="pun">.</span><span class="typ">ToString</span><span class="pun">(</span><span class="str">"dd/MM/yyyy"</span><span class="pun">),</span><span class="pln">
</span><span class="lit">39</span><span class="pln">	                </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">Start</span><span class="pun">,</span><span class="pln">
</span><span class="lit">40</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">FillAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">41</span><span class="pln">	                </span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Device</span><span class="pun">.</span><span class="typ">GetNamedSize</span><span class="pun">(</span><span class="typ">NamedSize</span><span class="pun">.</span><span class="typ">Medium</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">typeof</span><span class="pun">(</span><span class="typ">Label</span><span class="pun">))</span><span class="pln">
</span><span class="lit">42</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">43</span><span class="pln">	
</span><span class="lit">44</span><span class="pln">	            </span><span class="typ">Label</span><span class="pln"> lblResult </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Label</span><span class="pln">
</span><span class="lit">45</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">46</span><span class="pln">	                </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">FillAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">47</span><span class="pln">	                </span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Device</span><span class="pun">.</span><span class="typ">GetNamedSize</span><span class="pun">(</span><span class="typ">NamedSize</span><span class="pun">.</span><span class="typ">Medium</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">typeof</span><span class="pun">(</span><span class="typ">Label</span><span class="pun">)),</span><span class="pln">
</span><span class="lit">48</span><span class="pln">	                </span><span class="typ">VerticalTextAlignment</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">TextAlignment</span><span class="pun">.</span><span class="typ">Start</span><span class="pun">,</span><span class="pln">
</span><span class="lit">49</span><span class="pln">	                </span><span class="typ">HorizontalTextAlignment</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">TextAlignment</span><span class="pun">.</span><span class="typ">Center</span><span class="pun">,</span><span class="pln">
</span><span class="lit">50</span><span class="pln">	                </span><span class="typ">TextColor</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Color</span><span class="pun">.</span><span class="typ">Accent</span><span class="pln">
</span><span class="lit">51</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">52</span><span class="pln">	
</span><span class="lit">53</span><span class="pln">	            </span><span class="typ">Button</span><span class="pln"> btnCalculate </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">
</span><span class="lit">54</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">55</span><span class="pln">	                </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"احسب"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">56</span><span class="pln">	                </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">Start</span><span class="pln">
</span><span class="lit">57</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">58</span><span class="pln">	            btnCalculate</span><span class="pun">.</span><span class="typ">Clicked</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">s</span><span class="pun">,</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
</span><span class="lit">59</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">60</span><span class="pln">	                </span><span class="typ">TimeSpan</span><span class="pln"> diff </span><span class="pun">=</span><span class="pln"> </span><span class="typ">DateTime</span><span class="pun">.</span><span class="typ">Now</span><span class="pln"> </span><span class="pun">-</span><span class="pln"> birthDate</span><span class="pun">.</span><span class="typ">Date</span><span class="pun">;</span><span class="pln">
</span><span class="lit">61</span><span class="pln">	
</span><span class="lit">62</span><span class="pln">	                lblResult</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> string</span><span class="pun">.</span><span class="typ">Format</span><span class="pun">(</span><span class="str">"عمرك {0} يومًا"</span><span class="pun">,</span><span class="pln"> diff</span><span class="pun">.</span><span class="typ">Days</span><span class="pun">);</span><span class="pln">
</span><span class="lit">63</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">64</span><span class="pln">	
</span><span class="lit">65</span><span class="pln">	            </span><span class="typ">Content</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StackLayout</span><span class="pln">
</span><span class="lit">66</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">67</span><span class="pln">	                </span><span class="typ">Children</span><span class="pln"> </span><span class="pun">=</span><span class="pln">
</span><span class="lit">68</span><span class="pln">	                </span><span class="pun">{</span><span class="pln">
</span><span class="lit">69</span><span class="pln">	                    frmWelcome</span><span class="pun">,</span><span class="pln">
</span><span class="lit">70</span><span class="pln">	                    birthDate</span><span class="pun">,</span><span class="pln">
</span><span class="lit">71</span><span class="pln">	                    lblCurrentDate</span><span class="pun">,</span><span class="pln">
</span><span class="lit">72</span><span class="pln">	                    btnCalculate</span><span class="pun">,</span><span class="pln">
</span><span class="lit">73</span><span class="pln">	                    lblResult
</span><span class="lit">74</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">75</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">76</span><span class="pln">	
</span><span class="lit">77</span><span class="pln">	            </span><span class="typ">Padding</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Thickness</span><span class="pun">(</span><span class="lit">5</span><span class="pun">);</span><span class="pln">
</span><span class="lit">78</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">79</span><span class="pln">	    </span><span class="pun">}</span><span class="pln">
</span><span class="lit">80</span><span class="pln">	</span><span class="pun">}</span></pre>

<p>
	انتقل بعد ذلك إلى الملف App.cs وتأكّد أنّ بانية الصنف App على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_1473_13">
<span class="kwd">public</span><span class="pln"> </span><span class="typ">App</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="com">// The root page of your application</span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">AgeCalculatorPage</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	نفّذ البرنامج باستخدام F5 لتحصل على شكل شبيه بما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22555" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.png.8f87f655692735a9f93681ebc3eedb4a.png" rel=""><img alt="fig02.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22555" data-unique="wl4dn8kef" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.thumb.png.6d36e6dedb9beb5e7aa1f91aa65a5ba9.png"></a>
</p>

<p>
	اختر تاريخ مولدك (الميلادي) ولاحظ الصندوق الذي يملأ حيزًا لا بأس به من الشاشة، وكف يسمح لك باختيار التاريخ بصورة جميلة. بعد أن تختار التاريخ المناسب لك، انقر زر "احسب" لتحصل على عمرك بالأيّام من الأسفل. أنشأنا في الأسطر من 10 حتى 26 كائن جديد من الصنف Frame وأسندناه إلى المتغيّر frmWelcome. تُعتبر عناصر Frame ذات بنية مستطيلة تُستخدم لأغراض تحسين واجهة المستخدم. يعرض عنصر Frame حدًّا مستطيلًا يحيط بمحتوى معيّن. وإليك الآن بعض الملاحظات البسيطة حوله:
</p>

<ul>
<li>
		يحتوي عنصر الإطار Frame على الخاصيّة Content التي يمكن أن نُسند إليها أي عنصر آخر، أو من الممكن أن نسند إليها مخطّط مكدّس يحتوي بدوره على العديد من العناصر الأخرى. في مثالنا هذا أسندنا إلى هذه الخاصيّة كائن لصيقة Label (السطر 19) يحتوي على عنوان التطبيق.
	</li>
	<li>
		يضم عنصر الإطار أيضًا الخاصيّة Padding لإضافة حشوة داخليّة بين حدود الإطار والمحتوى الذي يقع ضمنه (السطر 13).
	</li>
	<li>
		يمكن التحكّم بلون حد الإطار من خلال الخاصيّة OutlineColor (السطر 18) حيث عملنا في هذا التطبيق على إسناد اللون Color.Accent إليه.
	</li>
	<li>
		الخاصيّة BackgroundColor للإطار تتحكّم بلون الخلفيّة كما نعلم، ولكن لاحظ الشكل الجديد الذي استخدمناه في إسناد اللون لها هذه المرّة (الأسطر من 14 حتى 17). استخدمنا هذه المرّة التابع Color.FromRgba الذي يُرجع كائن من النوع Color اعتبارًا من القيم اللونية RGB ومقدار الشفافيّة A الممرّرة إليه. ونستفيد من هذا الشكل في الحصول على ألوان مخصّصة أكثر. أحببت أن أستخدم اللون Accent ولكن بشكل شفّاف لذلك حصلت على المركّبات اللونية له باستخدام Color.Accent.R للأحمر وColor.Accent.G للأخضر وColor.Accent.B للأزرق، ومرّرتها إلى التابع Color.FromRgba بنفس الترتيب السابق. أمّا الوسيط الأخير فقد مرّرت إليه القيمة 0.2 ليظهر اللون شفَّافًا. قيمة الوسيط الأخير (قيمة A) تتراوح بين 0 (شفّاف تمامًا) و1 (معتم تمامًا).
	</li>
</ul>
<p>
	بالنسبة للعنصر DatePicker فيُستخدم كما أشرنا لاختيار تاريخ محدّد بصورة جميلة. صرّحنا عنه في الأسطر من 29 حتى 34 وأسندنا الكائن الناتج إلى المتغيّر birthDate ويُعبّر عن تاريخ الولادة. إليك بعض الملاحظات المتعلّقة بهذا العنصر:
</p>

<ul>
<li>
		يمكن الوصول إلى قيمة التاريخ الموجودة حاليًا ضمن هذا العنصر عن طريق الخاصيّة Date له كما سنرى بعد قليل. نوع هذه الخاصيّة مألوف وهو DateTime.
	</li>
	<li>
		توجد خاصيّتان مفيدتان في بعض الأحيان ولكن لم نستخدمهما في هذا التطبيق، وهما MinimumDate لتحديد التاريخ الأدنى الذي لا يمكن الاختيار قبله، و MaximumDate لتحديد التاريخ الأعلى الذي لا يمكن الاختيار بعده.
	</li>
</ul>
<p>
	خصّصنا لصيقة بسيطة لعرض النتائج (الأسطر من 44 حتى 51) وصرّحنا أيضًا عن الزر الخاص بإجراء عمليّة الحساب (الأسطر من 53 حتى 57) وأسندناه إلى المتغيّر btnCalculate. أسندنا معالج حدث النقر لهذا الزر في الأسطر من 58 حتى 63 على شكل تعبير Lambda. يحتوي هذا المعالج على شيفرة برمجيّة بسيطة للغاية، فهو يقرأ قيمة الخاصيّة Date من المتغيّر birthDate ويطرحها من التاريخ الحالي ويُسند النتيجة إلى المتغيّر diff الذي سيكون في هذه الحالة من النوع TimeSpan وهي بنية يمكن استخدامها لقياس فترات زمنيّة مُحدّدة (السطر 60) في نهاية الأمر نستخدم الخاصيّة Days من المتغيّر diff للحصول على الفترة الزمنية المطلوبة والتي تمثّل عمر الشخص بالأيّام.
</p>

<p>
	قد لا يبدو مظهر هذا التطبيق احترافيًّا كفاية. ولكنّنا سنتعلّم من خلال الدروس القادمة كيفيّة تحسين واجهة المستخدم وجعلها جذّابة من خلال تقنيّات بسيطة نسبيًّا.
</p>

<h3>
	الخلاصة
</h3>

<p>
	تعاملنا في هذا الدرس مع بعض العناصر المرئيّة المستخدمة في Xamarin.Forms. توجد بعض العناصر الأخرى التي لم نتحدّث عنها، أو التي لم نعطها حقّها في الحديث عنها. في الواقع أفضّل تأجيل ذلك إلى دروس قادمة لأنّ استخدام بعض هذه العناصر يتطلّب مفاهيم متقدّمة نسبيًّا في Xamarin.Forms. سنبدأ في الدرس التالي تعلّم كيفيّة بناء الواجهات باستخدام رُماز XAML. حيث سنتمكّن من فصل واجهة المستخدم عن الشيفرة البرمجيّة التي تتفاعل معها.
</p>
]]></description><guid isPermaLink="false">456</guid><pubDate>Sun, 13 Nov 2016 21:00:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x639;&#x646;&#x627;&#x635;&#x631; &#x627;&#x644;&#x645;&#x631;&#x626;&#x64A;&#x651;&#x629; &#x627;&#x644;&#x634;&#x627;&#x626;&#x639;&#x629; &#x641;&#x64A; Xamarin &#x2013; &#x627;&#x644;&#x62C;&#x632;&#x621; &#x627;&#x644;&#x623;&#x648;&#x651;&#x644;</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%A7%D9%84%D8%B9%D9%86%D8%A7%D8%B5%D8%B1-%D8%A7%D9%84%D9%85%D8%B1%D8%A6%D9%8A%D9%91%D8%A9-%D8%A7%D9%84%D8%B4%D8%A7%D8%A6%D8%B9%D8%A9-%D9%81%D9%8A-xamarin-%E2%80%93-%D8%A7%D9%84%D8%AC%D8%B2%D8%A1-%D8%A7%D9%84%D8%A3%D9%88%D9%91%D9%84-r455/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.909ede8ee78e95d09c601d54c273705b.png" /></p>

<p>
	سنهتمّ في هذا الدرس من <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/" rel="">سلسلة تعلّم تطوير تطبيقات أندرويد باستخدام Xamarin.Forms </a>بالعناصر المرئيّة الشائعة في Xamarin.Forms. يحتاج أيّ تطبيق بصورة عامة إلى العديد من العناصر المرئيّة التي تظهر على الشاشة بحيث توفّر معلومات معيّنة للمستخدم أو تسمح له بالتفاعل معها. يرث أيّ عنصر مرئيّ في Xamarin.Forms من الصنف VisualElement، سنتحدّث في هذا الدرس عن العنصر Entry وهو عبارة عن حقل خاص بالإدخال يستقبل مُدخلات المستخدم.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22553" data-unique="cfvxw2d8j" src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.75bf81e4dd094e376bd642e5838ee5c9.png"></p>

<p>
	وأيضًا عن العنصر ListView وهو عنصر القائمة ووظيفته عرض العناصر على شكل قائمة قابلة للتمرير. كما سنتحدّث عن العنصر Switch وهو عنصر تحويل الحالة المنطقيّة ويحمل إحدى قيمتين true أو false. وأخيرًا سنتحدّث عن عنصر المنزلق Slider ووظيفته السماح للمستخدم باختيار قيمة ضمن مجال محدّد عن طريق السحب. سنتناول تطبيقين بسيطين لفهم كيفيّة التعامل مع هذه العناصر.
</p>

<h3>
	تطبيق إدخال النصوص
</h3>

<p>
	فكرة هذا التطبيق بسيطة، حيث سنتعلّم كيف سنستخدم العنصر Entry للسماح للمستخدم بإدخال قيم نصيّة، ستُضاف هذه القيم إلى عنصر القائمة ListView. أنشئ مشروعًا من النوع Blank App (Xamarin.Forms Portable) وسمّه TextEntriesApp، ثم أبق فقط على المشروعين TextEntriesApp (Portable) و TextEntriesApp.Droid كما وسبق أن فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-visual-studio-2015-community-%D9%88%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-xamarin-%D9%84%D9%84%D8%B9%D9%85%D9%84-r373/" rel="">هذا الدرس</a>. بعد ذلك أضف صفحة محتوى جديدة كما فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D9%86%D8%B5%D9%88%D8%B5-%D9%81%D9%8A-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-r386/" rel="">هذا الدرس</a> وسمّها TextEntriesPage. احرص على أن تكون محتويات الملف TextEntriesPage.cs على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_2302_11">
<span class="lit">1</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">.</span><span class="typ">Collections</span><span class="pun">.</span><span class="typ">Generic</span><span class="pun">;</span><span class="pln">
</span><span class="lit">2</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">
</span><span class="lit">3</span><span class="pln">	
</span><span class="lit">4</span><span class="pln">	</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">TextEntriesApp</span><span class="pln">
</span><span class="lit">5</span><span class="pln">	</span><span class="pun">{</span><span class="pln">
</span><span class="lit">6</span><span class="pln">	    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">TextEntriesPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
</span><span class="lit">7</span><span class="pln">	    </span><span class="pun">{</span><span class="pln">
</span><span class="lit">8</span><span class="pln">	        </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">TextEntriesPage</span><span class="pun">()</span><span class="pln">
</span><span class="lit">9</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">10</span><span class="pln">	            </span><span class="typ">List</span><span class="str">&lt;string&gt;</span><span class="pln"> entries </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">List</span><span class="str">&lt;string&gt;</span><span class="pun">();</span><span class="pln">
</span><span class="lit">11</span><span class="pln">	
</span><span class="lit">12</span><span class="pln">	            </span><span class="typ">Entry</span><span class="pln"> txtInput </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Entry</span><span class="pln">
</span><span class="lit">13</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">14</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">FillAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">15</span><span class="pln">	                </span><span class="typ">HorizontalTextAlignment</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">TextAlignment</span><span class="pun">.</span><span class="typ">End</span><span class="pun">,</span><span class="pln">
</span><span class="lit">16</span><span class="pln">	                </span><span class="typ">Placeholder</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"أدخل كلمة"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">17</span><span class="pln">	                </span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Device</span><span class="pun">.</span><span class="typ">GetNamedSize</span><span class="pun">(</span><span class="typ">NamedSize</span><span class="pun">.</span><span class="typ">Medium</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">typeof</span><span class="pun">(</span><span class="typ">Label</span><span class="pun">))</span><span class="pln">
</span><span class="lit">18</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">19</span><span class="pln">	
</span><span class="lit">20</span><span class="pln">	            </span><span class="typ">Button</span><span class="pln"> btnAddEntry </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">
</span><span class="lit">21</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">22</span><span class="pln">	                </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"+"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">23</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">Start</span><span class="pln">
</span><span class="lit">24</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">25</span><span class="pln">	            btnAddEntry</span><span class="pun">.</span><span class="typ">Clicked</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">s</span><span class="pun">,</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
</span><span class="lit">26</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">27</span><span class="pln">	                entries</span><span class="pun">.</span><span class="typ">Add</span><span class="pun">(</span><span class="pln">txtInput</span><span class="pun">.</span><span class="typ">Text</span><span class="pun">);</span><span class="pln">
</span><span class="lit">28</span><span class="pln">	                
</span><span class="lit">29</span><span class="pln">	                txtInput</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">""</span><span class="pun">;</span><span class="pln">
</span><span class="lit">30</span><span class="pln">	                txtInput</span><span class="pun">.</span><span class="typ">Focus</span><span class="pun">();</span><span class="pln">
</span><span class="lit">31</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">32</span><span class="pln">	
</span><span class="lit">33</span><span class="pln">	            </span><span class="typ">StackLayout</span><span class="pln"> inputAreaSLayout </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StackLayout</span><span class="pln">
</span><span class="lit">34</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">35</span><span class="pln">	                </span><span class="typ">Orientation</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">StackOrientation</span><span class="pun">.</span><span class="typ">Horizontal</span><span class="pun">,</span><span class="pln">
</span><span class="lit">36</span><span class="pln">	                </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">Start</span><span class="pun">,</span><span class="pln">
</span><span class="lit">37</span><span class="pln">	                </span><span class="typ">Children</span><span class="pln"> </span><span class="pun">=</span><span class="pln">
</span><span class="lit">38</span><span class="pln">	                </span><span class="pun">{</span><span class="pln">
</span><span class="lit">39</span><span class="pln">	                    btnAddEntry</span><span class="pun">,</span><span class="pln">
</span><span class="lit">40</span><span class="pln">	                    txtInput
</span><span class="lit">41</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">42</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">43</span><span class="pln">	
</span><span class="lit">44</span><span class="pln">	            </span><span class="typ">ListView</span><span class="pln"> lstEntries </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">ListView</span><span class="pln">
</span><span class="lit">45</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">46</span><span class="pln">	                </span><span class="typ">ItemsSource</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> entries</span><span class="pun">,</span><span class="pln">
</span><span class="lit">47</span><span class="pln">	                </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">FillAndExpand</span><span class="pln">
</span><span class="lit">48</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">49</span><span class="pln">	
</span><span class="lit">50</span><span class="pln">	            
</span><span class="lit">51</span><span class="pln">	            </span><span class="typ">Content</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StackLayout</span><span class="pln">
</span><span class="lit">52</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">53</span><span class="pln">	                </span><span class="typ">Children</span><span class="pln"> </span><span class="pun">=</span><span class="pln">
</span><span class="lit">54</span><span class="pln">	                </span><span class="pun">{</span><span class="pln">
</span><span class="lit">55</span><span class="pln">	                    inputAreaSLayout</span><span class="pun">,</span><span class="pln">
</span><span class="lit">56</span><span class="pln">	                    lstEntries
</span><span class="lit">57</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">58</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">59</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">60</span><span class="pln">	    </span><span class="pun">}</span><span class="pln">
</span><span class="lit">61</span><span class="pln">	</span><span class="pun">}</span></pre>

<p>
	انتقل إلى الملف App.cs واحرص على أن تكون بانيته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_2302_13">
<span class="kwd">public</span><span class="pln"> </span><span class="typ">App</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="com">// The root page of your application</span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">TextEntriesPage</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	نفّذ البرنامج باستخدام F5 لتحصل على شكل شبيه بما يلي:
</p>

<p>
	 
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22551" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.png.e0647f9359c9c650d18eec0cdd7ed5f5.png" rel=""><img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22551" data-unique="m4vpiik94" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.thumb.png.1f7107b6551637d83dd8ddf6c260cebf.png"></a>
</p>

<p>
	 
</p>

<p>
	البرنامج السابق بسيط، اكتب كلمة ثم انقر الزر (+). تابع على هذا المنوال حتى تختفي الكلمات أسفل الشاشة، ثم اسحب بإصبعك على هذه القائمة لتظهر الكلمات المختفية.
</p>

<p>
	 
</p>

<p>
	بدأنا في السطر 10 بالتصريح عن المتغيّر entries من نوع <code>List&lt;string&gt;</code> وأسندنا إليه كائنًا جديدًا. يحتوي هذا المتغيّر على المُدخلات التي يدخلها المستخدم، وذلك عند النقر على الزر (+) عند كل إضافة. سنسند هذا المتغيّر إلى الخاصيّة ItemSource لكائن القائمة ListView كما سنرى بعد قليل. أنشأنا في الأسطر من 12 حتى 18 كائن Entry جديد وأسندناه إلى المتغيّر txtInput. لقد أسندنا القيمة TextAlignment.End للخاصية HorizontalTextAlignment لكي يظهر النص محاذًا نحو اليمين (باعتبار أنّنا نستخدم اللغة العربية في إدخال النصوص)، كما تجدر ملاحظة الخاصيّة الجديدة Placeholder التي تسمح بإظهار علامة مائيّة ضمن كائن Entry لإرشاد المستخدم حول وظيفة حقل الإدخال هذا. توجد أيضًا خاصيّة أخرى اسمها PlaceholderColor للتحكّم بلون خط هذه العلامة المائيّة. يمكن الوصول إلى محتوى حقل الإدخال عن طريق الخاصيّة Text له. قمنا بعد ذلك في الأسطر من 20 حتى 31 بإضافة زر جديد وأسندناه إلى المتغيّر btnAddEntry وجهزّنا معالج حدث النقر الخاص به.
</p>

<p>
	بالنسبة لمخطّط المكدّس الذي أنشأناه وأسندناه إلى المتغيّر inputAreaSLayout في الأسطر من 33 حتى 42، فتنحصر وظيفته في جعل كلّ من حقل الإدخال txtInput وزر الإضافة btnAdd يظهران بشكل أفقي متجاور. نأتي الآن إلى أكثر العناصر أهميّةً ألا وهو عنصر القائمة ListView الذي أنشأنا كائنًا جديدًا منه وأسندناه إلى المتغيّر lstEntries في الأسطر من 44 حتى 48. يُستخدَم عنصر القائمة بكثرة في تطبيقات الأجهزة المحمولة، إذ أنّ طبيعته التي تساعد على تمرير محتوياته تجعل منه مناسبًا جدًّا للاستخدام على الشاشات الصغيرة. في الواقع لم نستخدمه في هذا التطبيق إلًّا بأبسط صوره، حيث سنفرد له درسين كاملين للحديث عنه مستقبلًا. يمتلك عنصر القائمة الخاصيّة ItemSource حيث أسندنا لها المتغيّر entries ليقوم بعرض محتوياته ضمنه. وفي كلّ مرّة سنضيف فيها عنصرًا جديدًا على entries سينعكس ذلك على محتويات القائمة أيضًا. ضبطنا أيضًا الخاصيّة VerticalOptions للقائمة بحيث تشغل الحيّز المتبقّي ضمن الصفحة.
</p>

<h3>
	تطبيق التحكّم بالخط
</h3>

<p>
	تعتمد فكرة هذا التطبيق على وجود عنصر Switch بالإضافة إلى عنصر Slider وأخيرًا لصيقة تحتوي على نصٍّ بسيط نريد التحكّم بحجمه (عن طريق العنصر Slider) والتحكّم بميول الخط (عن طريق العنصر Switch). أنشئ مشروعًا من النوع Blank App (Xamarin.Forms Portable) وسمّه FontControlApp، ثم أبق فقط على المشروعين FontControlApp (Portable) و FontControlApp.Droid. بعد ذلك أضف صفحة محتوى جديدة وسمّها FontControlPage. احرص على أن تكون محتويات الملف FontControlPage.cs على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_2302_15">
<span class="lit">1</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">
</span><span class="lit">2</span><span class="pln">	
</span><span class="lit">3</span><span class="pln">	</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">FontControlApp</span><span class="pln">
</span><span class="lit">4</span><span class="pln">	</span><span class="pun">{</span><span class="pln">
</span><span class="lit">5</span><span class="pln">	    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">FontControlPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
</span><span class="lit">6</span><span class="pln">	    </span><span class="pun">{</span><span class="pln">
</span><span class="lit">7</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> </span><span class="typ">Label</span><span class="pln"> lblText</span><span class="pun">;</span><span class="pln">
</span><span class="lit">8</span><span class="pln">	        </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">FontControlPage</span><span class="pun">()</span><span class="pln">
</span><span class="lit">9</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">10</span><span class="pln">	            </span><span class="typ">Switch</span><span class="pln"> swtItalicFont </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Switch</span><span class="pln">
</span><span class="lit">11</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">12</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">EndAndExpand</span><span class="pln">
</span><span class="lit">13</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">14</span><span class="pln">	            swtItalicFont</span><span class="pun">.</span><span class="typ">Toggled</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">s</span><span class="pun">,</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
</span><span class="lit">15</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">16</span><span class="pln">	                </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">e</span><span class="pun">.</span><span class="typ">Value</span><span class="pun">)</span><span class="pln">
</span><span class="lit">17</span><span class="pln">	                    lblText</span><span class="pun">.</span><span class="typ">FontAttributes</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">FontAttributes</span><span class="pun">.</span><span class="typ">Italic</span><span class="pun">;</span><span class="pln">
</span><span class="lit">18</span><span class="pln">	                </span><span class="kwd">else</span><span class="pln">
</span><span class="lit">19</span><span class="pln">	                    lblText</span><span class="pun">.</span><span class="typ">FontAttributes</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">FontAttributes</span><span class="pun">.</span><span class="typ">None</span><span class="pun">;</span><span class="pln">
</span><span class="lit">20</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">21</span><span class="pln">	
</span><span class="lit">22</span><span class="pln">	            </span><span class="typ">StackLayout</span><span class="pln"> fontItalicSLayout </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StackLayout</span><span class="pln">
</span><span class="lit">23</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">24</span><span class="pln">	                </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">Start</span><span class="pun">,</span><span class="pln">
</span><span class="lit">25</span><span class="pln">	                </span><span class="typ">Orientation</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">StackOrientation</span><span class="pun">.</span><span class="typ">Horizontal</span><span class="pun">,</span><span class="pln">
</span><span class="lit">26</span><span class="pln">	                </span><span class="typ">Children</span><span class="pln"> </span><span class="pun">=</span><span class="pln">
</span><span class="lit">27</span><span class="pln">	                </span><span class="pun">{</span><span class="pln">
</span><span class="lit">28</span><span class="pln">	                    swtItalicFont</span><span class="pun">,</span><span class="pln">
</span><span class="lit">29</span><span class="pln">	                    </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Label</span><span class="pln">
</span><span class="lit">30</span><span class="pln">	                    </span><span class="pun">{</span><span class="pln">
</span><span class="lit">31</span><span class="pln">	                        </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"خط مائل"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">32</span><span class="pln">	                        </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">End</span><span class="pln">
</span><span class="lit">33</span><span class="pln">	                    </span><span class="pun">}</span><span class="pln">
</span><span class="lit">34</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">35</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">36</span><span class="pln">	
</span><span class="lit">37</span><span class="pln">	            </span><span class="typ">Slider</span><span class="pln"> sldFontSize </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Slider</span><span class="pln">
</span><span class="lit">38</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">39</span><span class="pln">	                </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">Center</span><span class="pun">,</span><span class="pln">
</span><span class="lit">40</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">FillAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">41</span><span class="pln">	                </span><span class="typ">Maximum</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">40</span><span class="pun">,</span><span class="pln">
</span><span class="lit">42</span><span class="pln">	                </span><span class="typ">Minimum</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">10</span><span class="pun">,</span><span class="pln">
</span><span class="lit">43</span><span class="pln">	                </span><span class="typ">Value</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">20</span><span class="pln">
</span><span class="lit">44</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">45</span><span class="pln">	            sldFontSize</span><span class="pun">.</span><span class="typ">ValueChanged</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">s</span><span class="pun">,</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
</span><span class="lit">46</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">47</span><span class="pln">	                lblText</span><span class="pun">.</span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> e</span><span class="pun">.</span><span class="typ">NewValue</span><span class="pun">;</span><span class="pln">
</span><span class="lit">48</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">49</span><span class="pln">	
</span><span class="lit">50</span><span class="pln">	            lblText </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Label</span><span class="pln">
</span><span class="lit">51</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">52</span><span class="pln">	                </span><span class="typ">VerticalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">FillAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">53</span><span class="pln">	                </span><span class="typ">VerticalTextAlignment</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">TextAlignment</span><span class="pun">.</span><span class="typ">Center</span><span class="pun">,</span><span class="pln">
</span><span class="lit">54</span><span class="pln">	                </span><span class="typ">HorizontalTextAlignment</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">TextAlignment</span><span class="pun">.</span><span class="typ">Center</span><span class="pun">,</span><span class="pln">
</span><span class="lit">55</span><span class="pln">	                </span><span class="typ">Text</span><span class="pun">=</span><span class="str">"This is a sample text to demonstrate Switch and Slider elements"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">56</span><span class="pln">	                </span><span class="typ">TextColor</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Color</span><span class="pun">.</span><span class="typ">Accent</span><span class="pun">,</span><span class="pln">
</span><span class="lit">57</span><span class="pln">	                </span><span class="typ">FontFamily</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"Tahoma"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">58</span><span class="pln">	                </span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="lit">20</span><span class="pln">
</span><span class="lit">59</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">60</span><span class="pln">	
</span><span class="lit">61</span><span class="pln">	            </span><span class="typ">Content</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StackLayout</span><span class="pln">
</span><span class="lit">62</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">63</span><span class="pln">	                </span><span class="typ">Children</span><span class="pln"> </span><span class="pun">=</span><span class="pln">
</span><span class="lit">64</span><span class="pln">	                </span><span class="pun">{</span><span class="pln">
</span><span class="lit">65</span><span class="pln">	                    fontItalicSLayout</span><span class="pun">,</span><span class="pln">
</span><span class="lit">66</span><span class="pln">	                    sldFontSize</span><span class="pun">,</span><span class="pln">
</span><span class="lit">67</span><span class="pln">	                    lblText
</span><span class="lit">68</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">69</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">70</span><span class="pln">	
</span><span class="lit">71</span><span class="pln">	            </span><span class="typ">Padding</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Thickness</span><span class="pun">(</span><span class="lit">5</span><span class="pun">);</span><span class="pln">
</span><span class="lit">72</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">73</span><span class="pln">	    </span><span class="pun">}</span><span class="pln">
</span><span class="lit">74</span><span class="pln">	</span><span class="pun">}</span></pre>

<p>
	ثم انتقل إلى الملف App.cs واحرص على أن تكون بانيته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_2302_17">
<span class="kwd">public</span><span class="pln"> </span><span class="typ">App</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="com">// The root page of your application</span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">FontControlPage</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	نفّذ البرنامج باستخدام F5، وتعامل معه قليلًا لتحصل على شكل شبيه بما يلي:
</p>

<p>
	 
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22552" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.png.2a2916c76242127208be1fa490ad1b05.png" rel=""><img alt="fig02.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22552" data-unique="v5re1a7ac" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.thumb.png.d80794d432dfd94d757e751d578e457c.png"></a>
</p>

<p>
	 
</p>

<p>
	صرّحنا في الأسطر من 10 حتى 20 عن كائن Switch جديد وأسندناه إلى المتغيّر swtItalicFont، كما قمنا بإسناد معالج للحدث Toggle كما هو واضح (السطر 14). يتم تفعيل الحدث Toggle عندما ينقر المستخدم على عنصر Switch ليغيّر حالته المنطقيّة من true إلى false أو بالعكس. من الممكن معرفة الوضع الحالي لعنصر Switch بقراءة الخاصيّة Value من الكائن المرّر كوسيط e كما فعلنا في السطر 16. ومن ثمّ نتخذ القرار المناسب في جعل الخط مائلًا أم لا من خلال استخدام المعدودة FontAttributes كما فعلنا في السطرين 17 و19. أنشأنا في الأسطر من 22 حتى 35 مخطّط مكدّس جديد تنحصر وظيفته في جعل عنصر Switch بالإضافة إلى لصيقة صغيرة توضّح عمله بشكل متجاور أفقيًّا وعلى الجهة اليمنى كما هو واضح.
</p>

<p>
	بالنسبة لعنصر Slider فقد صرّحنا عنه في الأسطر من 37 حتى 44. حيث أنشأنا كائن جديد من الصنف Slider وأسندناه إلى المتغيّر sldFontSize. تُعتبر عناصر Slider من العناصر المفيدة في واجهة المستخدم، وتُستخدم عادةً لاختيار قيم محصورة ضمن مجال يمكن تحديده مسبقًا. طريقة اختيار هذه القيم هي التي تجعل منها عناصر مميّزة. فأنت تحتاج فقط إلى لمس الدائرة الصغيرة وسحبها إلى اليمين أو اليسار لكي تختار القيمة التي تناسبك. يتم تحديد مجال الاختيار عن طريق الخاصيتين Minimum وMaximum. احرص دومًا على تعيين قيمة الخاصية Maximum قبل Minimum. يمكن قراءة القيمة الحالية ضمن عنصر Slider عن طريق الخاصيّة Value له. لقد عملنا في الشيفرة السابقة على ضبط قيمة افتراضيّة لعنصر Slider وهي 15 (انظر السطر 43) كما جعلنا مجال الاختيار يتراوح بين 10 و40 (السطران 41 و42). الأمر المفيد الآخر في هذا العنصر هو الحدث ValueChanged الذي يُفعّل كلّما تغيّرت القيمة الحالية لعنصر Slider. لقد أسندنا معالج حدث في الأسطر 45 حتى 48 للاستفادة من هذا الحدث، حيث نستفيد من قيمة عنصر Slider مباشرةً في تغيير حجم الخط للنص الموجود ضمن اللصيقة lblText المصرّح عنها في الأسطر من 50 حتى 59. لقد عيّنّا نوع الخط المستخدم في هذه اللصيقة عن طريقة ضبط القيمة "Tahoma" للخاصيّة FontFamily لها (السطر 57). لقد اخترت الخط Tahoma لكي يظهر الخط المائل بشكل واضح.
</p>

<p>
	توجد ملاحظة بسيطة أخيرة في الشيفرة السابقة، وهي استخدام شكل جديد لبانية الصنف Thickness (السطر 71) حيث مرّرنا إليها وسيطًا واحدًا فقط بدلًا من أربعة وسائط كما كنّا نفعل من قبل. في الحقيقة عندما تريد تمرير نفس القيمة لكلّ من الجهات الأربع (top، left، right، bottom) فيكفيك أن تمرّر قيمة واحدة فقط تمثّل القيمة الثابتة لهذه الاتجاهات.
</p>

<h3>
	الخلاصة
</h3>

<p>
	تحدثنا في هذا الدرس عن بعض العناصر المرئيّة المفيدة في Xamarin.Forms. حيث تناولنا عنصر حقل الإدخال Entry وعنصر تحويل الحالة المنطقية Switch وعنصر المنزلق Slider لاختيار قيمة ضمن مجال محدّد يمكن تعيينه. والعنصر المهم ListView وهو عنصر القائمة. سنتعامل مع هذه العناصر مجّددًا في هذه السلسلة، وسنتوسّع بالحديث عن بعض منها في دروس مخصّصة. سنتناول في الدرس التالي المزيد من هذه العناصر مع تطبيقات ممتعة لها.
</p>
]]></description><guid isPermaLink="false">455</guid><pubDate>Wed, 09 Nov 2016 21:00:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x62A;&#x639;&#x627;&#x645;&#x644; &#x645;&#x639; &#x627;&#x644;&#x635;&#x648;&#x631; &#x641;&#x64A; Xamarin</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D8%B5%D9%88%D8%B1-%D9%81%D9%8A-xamarin-r454/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.ab8c921f774ab0638626ecdb1a74a9d5.png" /></p>

<p>
	تُعتبر الصور كما نعلم من العناصر الأساسيّة في أيّ تطبيق، فهي تضفي لمسة جمالية بالإضافة إلى إعطائها انطباعًا توضيحيًّا لوظائف التطبيق الأساسيّة. سنتابع عملنا في هذه السلسلة من خلال شرح كيفيّة استخدام الصور في Xamarin.Froms. يتعامل Xamarin مع الصور النقطيّة bitmaps التي قد يختلف مفهومها قليلًا بالنسبة لأنظمة تشغيل Android وiOS وWindows، ولكن إذا اعتمدت على صيغ مثل JPEG وPNG وBMP فلن تعاني من أيّة مشاكل.
</p>

<p style="text-align: center;">
	<img alt="main.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22550" data-unique="67urhis3z" src="https://academy.hsoub.com/uploads/monthly_2017_04/main.png.ca2386c825625a23f255b8095326a7e3.png"></p>

<p>
	يتعامل Xamarin.Forms مع الصور بأسلوبين رئيسيّين. يعتمد الأسلوب الأوّل على الصور المستقلة عن نوع الجهاز platform-independent أمّا الأسلوب الثاني فيعتمد على الصور المرتبطة بالجهاز platform-specific أو بمعنى أدق المرتبطة بنظام التشغيل الذي يعمل على الجهاز. ستناول الأسلوب الأوّل في درسنا هذا من خلال تطبيقين بسيطين يوضّحان ذلك. أمّا الأسلوب الثاني فسنؤجّل الحديث عنه لدرس آخر.
</p>

<p>
	يمكن عرض الصور ضمن تطبيقات Xamarin عن طريق عنصر مرئي يمثّله الصنف Image. وكما مع بقية العناصر المرئية التي ترث من الصنف VisualElement يمتلك هذا العنصر العديد من الخصائص المشتركة بينه وبين أي عنصر مرئي آخر كاللصيقة Label مثلًا. بالإضافة إلى خصائص أخرى تميّزه كالخاصيّة Source التي تُعبّر عن مصدر الصورة التي ستُعرض ضمنه. ستكون هذه الخاصيّة محور اهتمامنا في هذا الدرس. يمكن الحصول على الصور المستقلة عن الجهاز بأسلوبين مختلفين. ستحتاج في كلّ أسلوب منهما إلى إسناد كائن من الصنف ImageSource إلى الخاصيّة Source لكائن الصورة Image.
</p>

<p>
	يتمثّل الأسلوب الأوّل في الحصول على صور من الإنترنت مباشرةً، ويكون ذلك من خلال استدعاء التابع الساكن FromUri من الصنف ImageSource وتمرير عنوان Uri لملف الصورة على الإنترنت.
</p>

<p>
	أمّا الأسلوب الثاني فيتمثّل باستدعاء التابع الساكن FromResource من الصنف ImageSource أيضًا وتمرير اسم المصدر resource (الصورة) إليه. سيوضّح التطبيقين البسيطين التاليّين كيفيّة فعل ذلك.
</p>

<h3>
	الحصول على صورة من الإنترنت
</h3>

<p>
	أنشئ تطبيقًا جديدًا سمّه WebImageApp من النوعBlank App (Xamarin.Forms Portable) وأبق فقط على المشروعين WebImageApp (Portable) و WebImageApp.Droid كما <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%AA%D9%86%D8%B5%D9%8A%D8%A8-visual-studio-2015-community-%D9%88%D8%AA%D8%AC%D9%87%D9%8A%D8%B2-xamarin-%D9%84%D9%84%D8%B9%D9%85%D9%84-r373/" rel="">اتفقنا من قبل</a>. أضف صفحة محتوى جديدة ContentPage كما فعلنا في <a href="https://academy.hsoub.com/programming/c-sharp/%D9%85%D9%86%D8%B5%D8%A9-xamarin/%D8%A7%D9%84%D8%AA%D8%B9%D8%A7%D9%85%D9%84-%D9%85%D8%B9-%D8%A7%D9%84%D9%86%D8%B5%D9%88%D8%B5-%D9%81%D9%8A-%D8%AA%D8%B7%D8%A8%D9%8A%D9%82%D8%A7%D8%AA-xamarin-r386/" rel="">هذا الدرس</a>. سمّها WebImagePage واحرص على أن تكون محتويات الملف WebImagePage.cs على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3551_9">
<span class="pln">using System;
using Xamarin.Forms;

namespace WebImageApp
{
    public class WebImagePage : ContentPage
    {
        public WebImagePage()
        {
            Image webImage = new Image
            {
                VerticalOptions = LayoutOptions.FillAndExpand,
                HorizontalOptions = LayoutOptions.FillAndExpand,
                Source = ImageSource.FromUri(new Uri("https://developer.xamarin.com/demo/IMG_2138.JPG?width=800")),
                Aspect = Aspect.AspectFit,
                BackgroundColor = Color.Accent
            };

            Content = new StackLayout
            {
                Children = {
                    webImage
                }
            };
        }
    }
}</span></pre>

<p>
	ثم انتقل إلى الملف App.cs واحرص على أن تكون بانيته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3551_11">
<span class="pln">public App()
{
    // The root page of your application
    MainPage = new WebImagePage();
}</span></pre>

<p>
	شيفرة التطبيق بسيطة، فهي تعمل على إنشاء كائن صورة جديد وتُسنده إلى المتغيّر webImage، ثم تعمل على جعل كائن الصورة هذا ابنًا لمخطّط المكدّس كما هو واضح.
</p>

<p>
	ما يهمنا الآن هو خصائص كائن الصورة، فقد أسندنا القيمة LayoutOptions.FillAndExpand إلى كلّ من الخاصيّتين VerticalOptions وHorizontalOptions لكي تشغل الصورة كامل المساحة المتاحة لمخطّط المكدّس. أمّا بالنسبة للخاصيّة Source فهي تعبّر عن المصدر الذي سنحصل منه على الصورة. في تطبيقنا هذا سنحصل على الصورة من الإنترنت لذلك سنستخدم التابع الساكن ImageSource.FromUri الذي يُرجع كائنًا من الصف ImageSource. لاحظ أنّنا قد مرّرنا كائن جديد من النوع Uri إلى هذا التابع:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3551_9">
<code>
ImageSource.FromUri(new Uri("https://developer.xamarin.com/demo/IMG_2138.JPG?width=800"))
</code></pre>

<p>
	العنوان المستخدم هنا هو:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3551_9">
<code>
"https://developer.xamarin.com/demo/IMG_2138.JPG?width=800"
</code></pre>

<p>
	بالنسبة للخاصيّة Aspect فهي تُحدّد كيفيّة عرض الصورة ضمن عنصر الصورة Image. حيث أنّها تقبل قيمًا من المعدودة Aspect التي تحمل نفس الاسم. لهذه المعدودة ثلاثة عناصر: AspectFit وAspectFill وFill. استخدمنا في هذا التطبيق القيمة AspectFit وهي القيمة الافتراضيّة. وإليك ما تعنيه القيم الثلاث السابقة:
</p>

<ul>
<li>
		AspectFit: تعني أنّ الصورة ستظهر ضمن العنصر بحيث تنسجم مع المساحة المخصّصة له، مع احترام النسبة الخاصّة بمظهر الصورة aspect ratio.
	</li>
	<li>
		AspectFill: في هذه الحالة ستظهر الصورة ضمن العنصر بحيث تحترم النسبة الخاصّة بمظهر الصورة aspect ratio، ولكنّها لن تهتم بالمساحة المخصّصة لهذا العنصر. لذلك فقد تظهر الصورة مقتطعةً إذا كانت أكبر من العنصر.
	</li>
	<li>
		Fill: تعني هذه القيمة أنّ الصورة ستظهر بحيث تشغل كامل المساحة المخصّص للعنصر بدون أيّ اعتبار النسبة الخاصّة بمظهر الصورة aspect ratio. لذلك فقط تظهر الصورة ممطوطة أفقيًّا أو رأسيًّا. لقد أسندت اللون Color.Accent إلى خاصيّة لون الخلفيّة BackgroundColor لعنصر الصورة لكي نرى المساحة الفعليّة التي يشغلها هذا العنصر. نفّذ البرنامج السابق باستخدام F5 لتحصل على شكل شبيه بما يلي، مع الانتباه إلى أنّني أجري التجارب على جهاز ذي شاشة قياسها 4.5 بوصة، لذلك قد تختلف النتائج التي تحصل عليها على جهازك في حال كان لديك شاشة ذات قياس أكبر. إذا كان الأمر كذلك فأنصح بحذف المقطع "?width=800" من عنوان Uri للصورة من الخاصيّة Source:
	</li>
</ul>
<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22546" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.png.1defb4cdfafd1e6236f6f7409cf1c522.png" rel=""><img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22546" data-unique="ld5alknau" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig01.thumb.png.b0717b5d01b91d48ff5b3250471b0f90.png"></a>
</p>

<p>
	لاحظ كيف ظهرت الصورة بحيث بقيت مساحة فارغة من الأعلى والأسفل. هذا بسبب أنّها احترمت النسبة الخاصّة بمظهر الصورة الأصليّة aspect ratio. إذا أجريت تعديلًا على الخاصيّة Aspect لتحمل القيمة Aspect.AspectFill فستحصل في هذه الحالة على شكل شبيه بما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22547" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.png.f6dc343f53c23cd8103f9303c450f1eb.png" rel=""><img alt="fig02.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22547" data-unique="az1zt7tmt" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig02.thumb.png.041f6c992fed502376b3149f4e1e0a28.png"></a>
</p>

<p>
	لاحظ هنا كيف ظهرت الصورة مقتطعة قليلًا. جرّب الآن الحالة الأخيرة، وهي إسناد القيمة Aspect.Fill إلى الخاصيّة Aspect لتحصل على شكل شبيه بما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22541" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig03.png.7f257d3f942c4083844ea08a42029bec.png" rel=""><img alt="fig03.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22541" data-unique="ie2w0axua" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig03.thumb.png.af2eaa93b521de6ea3a8ba7d6fb1e464.png"></a>
</p>

<p>
	وكما هو متوّقع ظهرت الصورة بشكل ممطوط رأسيًّا لأنّها ستملأ كامل المساحة المتاحة لعنصر الصورة دون اعتبار للنسبة الخاصّة بمظهر الصورة الأصليّة كما أشرنا.
</p>

<h3>
	الحصول على صورة من مصدر resource محلّي
</h3>

<p>
	لا يختلف التعامل مع الصور في هذا الأسلوب مع أسلوب التعامل مع الصور التي نحصل عليها من الويب. باستثناء أنّنا نستخدم التابع الساكن FromResource من الصنف ImageSource. سنتناول في هذه الفقرة تطبيقًا عمليًّا لتصفّح مجموعة من الصور التي أعددتها خصيصًا لهذا الغرض. سيتم التصفّح عن طريق زرّين: "التالي" و"السابق" بالإضافة إلى وجود لصيقة تعرض معلومة بسيطة عن رقم الصورة الحالية التي يتم عرضها على عنصر الصورة. ستكون هذه الصور موجودة محلّيًّا ضمن التطبيق. لنبدأ الآن بإنشاء تطبيق جديد اسمه ResourceImageApp من النوعBlank App (Xamarin.Forms Portable) . أبق فقط على المشروعين ResourceImageApp (Portable) و ResourceImageApp.Droid. أضف صفحة محتوى جديدة ContentPage سمّها ResourceImagePage واحرص على أن تكون محتويات الملف ResourceImagePage.cs على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3551_9">
<code>
1	using System;
2	using Xamarin.Forms;
3	
4	namespace ResourceImageApp
5	{
6	    public class ResourceImagePage : ContentPage
7	    {
8	        private Button btnPrev;
9	        private Button btnNext;
10	        private Image resourceImage;
11	        private Label lblInfo;
12	        private int currentIndex = 1;
13	
14	        public ResourceImagePage()
15	        {
16	            lblInfo = new Label
17	            {
18	                VerticalOptions = LayoutOptions.Start,
19	                HorizontalOptions = LayoutOptions.FillAndExpand,
20	                HorizontalTextAlignment = TextAlignment.Center,
21	                TextColor = Color.Accent,
22	                FontSize = Device.GetNamedSize(NamedSize.Medium, typeof(Label))
23	            };
24	
25	            resourceImage = new Image
26	            {
27	                VerticalOptions = LayoutOptions.FillAndExpand,
28	                HorizontalOptions = LayoutOptions.FillAndExpand,
29	                Aspect = Aspect.AspectFit
30	            };
31	
32	            btnPrev = new Button
33	            {
34	                Text = "السابق",
35	                HorizontalOptions = LayoutOptions.FillAndExpand,
36	                IsEnabled = false
37	            };
38	            btnPrev.Clicked += BtnPrev_Clicked;
39	
40	            btnNext = new Button
41	            {
42	                Text = "التالي",
43	                HorizontalOptions = LayoutOptions.FillAndExpand
44	            };
45	            btnNext.Clicked += BtnNext_Clicked;
46	
47	            StackLayout buttonsLayout = new StackLayout
48	            {
49	                Orientation = StackOrientation.Horizontal,
50	                VerticalOptions = LayoutOptions.End,
51	                HorizontalOptions = LayoutOptions.FillAndExpand,
52	                Children =
53	                {
54	                    btnNext,
55	                    btnPrev
56	                }
57	            };
58	
59	            Content = new StackLayout
60	            {
61	                Children = {
62	                    lblInfo,
63	                    resourceImage,
64	                    buttonsLayout
65	                }
66	            };
67	
68	            Padding = new Thickness(5, 5, 5, 5);
69	
70	            UpdateScreen();
71	        }
72	
73	        private void BtnPrev_Clicked(object sender, EventArgs e)
74	        {
75	            currentIndex--;
76	            if (currentIndex == 1)
77	            {
78	                btnPrev.IsEnabled = false;
79	            }
80	
81	            btnNext.IsEnabled = true;
82	
83	            UpdateScreen();
84	        }
85	
86	        private void BtnNext_Clicked(object sender, EventArgs e)
87	        {
88	            currentIndex++;
89	            if (currentIndex == 5)
90	            {
91	                btnNext.IsEnabled = false;
92	            }
93	
94	            btnPrev.IsEnabled = true;
95	
96	            UpdateScreen();
97	        }
98	
99	        private void UpdateScreen()
100	        {
101	            lblInfo.Text = string.Format("الصورة {0} من 5", currentIndex);
102	            string path = string.Format("ResourceImageApp.Images.res0{0}.jpg", currentIndex);
103	            resourceImage.Source = ImageSource.FromResource(path);
104	        }
105	    }
106	}
</code></pre>

<p>
	ثم انتقل إلى الملف App.cs واحرص على أن تكون بانيته على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3551_9">
<code>
public App()
{
    // The root page of your application
    MainPage = new ResourceImagePage();
}
</code></pre>

<p>
	انقر بزر الفأرة الأيمن على المشروع المشترك ResourceImageApp (Portable) ثم اختر Add ومن القائمة الجانبيّة التي ستظهر اختر New Folder. سينشئ ذلك مجلّدًا جديدًا ضمن هذا المشروع، سمّه Images. ثم انقر بعد ذلك بزر الفأرة الأيمن على مجلّدنا الجديد Images واختر Add وبعدها Existing Item سيظهر مربّع حوار يسمح لك باختيار الصور المراد إضافتها كمصادر resources إلى هذا المجلّد. اختر ملفّات الصور: res01.jpg وres02.jpg وres03.jpg و res04.jpg وres05.jpg (انقر هنا لتحميلها<a class="ipsAttachLink" data-fileid="22549" href="https://academy.hsoub.com/applications/core/interface/file/attachment.php?id=22549" rel="">Images.zip</a>). تحتوي هذه الصور بالترتيب على العبارة التالية "مرحبًا بكم في أكاديميّة حسّوب". انقر بزر الفأرة الأيمن مجدّدًا على كل اسم ملف أضفته قبل قليل إلى المشروع واختر من القائمة الأمر Properties. ستظهر خصائص الملف، اضبط الخاصيّة Build Action لتصبح Embedded Resource كما هو واضح من الشكل التالي لأحد الملفات:
</p>

<p style="text-align: center;">
	<img alt="fig04.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22548" data-unique="fv3snyd5u" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig04.png.cce5c6352eb61ee6e638ffbc232c71f3.png"></p>

<p>
	نفّذ البرنامج باستخدام F5 لتحصل على شكل شبيه بما يلي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22543" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig05.png.c952115a6474a97d64d1cffda15431c3.png" rel=""><img alt="fig05.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22543" data-unique="4bz3ma2r8" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig05.thumb.png.d108c7637e6611ae5c3f717c141a5fa9.png"></a>
</p>

<p>
	لنلاحظ في البداية أنّ التطبيق يعرض الصورة الأولى التي يمثّلها الملف res01.jpg. كما نلاحظ أنّ زر "السابق" غير مفعّل أي أنّنا لا نستطيع الرجوع إلى الوراء، وأيضًا العبارة التوضيحيّة في الأعلى التي تعرض رقم الصورة الحاليّة. إذا جرّبت نقر زر "التالي" ستنتقل إلى الصورة رقم 2 (الملف res02.jpg) وسيصبح الزر "السابق" مفعّلًا ليسمح لنا بالعودة إلى الصورة رقم 1. إذا تابعت النقر على زر "التالي" ستستعرض تباعًا الملفات بالترتيب، حتى إذا وصلت إلى الملف رقم 5 سيصبح الزر "التالي" غير مفعّل لأنّه لا توجد أيّة صور بعد الملف رقم 5. انظر إلى الشكل التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22544" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig06.png.20ab2902560a1d77bf368b2ab8df4319.png" rel=""><img alt="fig06.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22544" data-unique="7t5nsvdv2" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig06.thumb.png.0eefe0f516a8cf5848c53dd9e1b60f51.png"></a>
</p>

<p>
	بمجرّد أن تنقر الزر "السابق" سيعود زر "التالي" مفعّلًا من جديد. لنناقش الشيفرة البرمجيّة المشغّلة لهذا التطبيق. نلاحظ في الأسطر من 8 حتى 11 أنّني قد صرّحت عن حقول خاصّة تمثّل معظم العناصر المرئيّة التي سنتعامل معها في هذا التطبيق وهي عنصر صورة وعنصر لصيقة وزرّين للتالي والسابق. كما صرّحت في السطر 12 عن متغيّر خاص currentIndex يمثّل رقم الملف الحالي الذي نرغب بعرضه ضمن ملف الصورة وأسندت له القيمة التمهيديّة 1. بالنسبة لبانية الصنف ResourceImagePage فهي تعمل على تهيئة جميع العناصر المرئيّة المستخدمة كما نعلم. حيث نضبط في الأسطر من 16 حتى 23 خصائص اللصيقة lblInfo حيث أسندنا القيمة LayoutOptions.Start للخاصيّة VerticalOptions لكي تظهر أوّل (أعلى) الشاشة. كما أسندنا القيمة TextAlignment.Center لخاصيّة محاذاة النص الأفقيّة HorizontalTextAlignment لكي يظهر النص موسّطًا بشكل أفقي. أمّا بالنسبة لعنصر الصورة resourceImage فقمنا بضبط خصائصه في الأسطر من 25 حتى 30 حيث جعلنا قيمة الخاصيّة Aspect له تساوي Aspect.AspectFit لكي تملأ الصورة الحيّز المتاح لها مع احترام النسبة الخاصّة بمظهر الصورة. تأتي بعد ذلك عمليّة ضبط الزرّين btnPrev (السابق) و btnNext (التالي) من الأسطر 32 حتى 45. سنضيف هذين الزرّين لاحقًا إلى مخطّط مكدّس خاص بهما هو buttonsLayout والسبب في ذلك أنّنا نريد أن نجعل هذين الزرّين متجاورين أفقيًّا مع تعبئة المساحة الأفقيّة المتاحة لهما (لاحظ القيمة LayoutOptions.FillAndExpand للخاصيّة HorizontalOptions لكل منهما). نصرّح عن مخطّط المكدّس buttonsLayout في الأسطر من 47 حتى 57. سنضيف لهذا المخطّط الزرّين btnPrev و btnNext كما سنضبط خاصيّة الاتجاه Orientation له لتكون أفقيّة StackOrientation.Horizontal لكي يُظهِر الزرّين السابقين بشكل أفقيّ وليس رأسيّ. سنضيف مخطّط المكدّس هذا بعد قليل إلى مخطّط المكدّس الأساسيّ للصفحة.
</p>

<p>
	نضبط الخاصيّة Content للصفحة في الأسطر 59 حتى 66 بحيث ننشئ مخطّط مكدّس جديد يحتوي على العناصر: اللصيقة والصورة ومخطّط المكدّس الخاص بالأزرار على الترتيب. وهذا هو سبب ظهور العناصر السابقة بهذا الترتيب. انظر إلى المخطّط التمثيلي التالي الذي يوضّح التموضع التقريبي للعناصر السابقة على الصفحة:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="22545" href="https://academy.hsoub.com/uploads/monthly_2017_04/fig07.png.d09d16edd83bb2fa318fca43d6274516.png" rel=""><img alt="fig07.png" class="ipsImage ipsImage_thumbnailed" data-fileid="22545" data-unique="zq0frjoo2" src="https://academy.hsoub.com/uploads/monthly_2017_04/fig07.thumb.png.d856aad1c5fd9c798db7861ad36fb627.png"></a>
</p>

<p style="text-align: center;">
	<span style="color:#c0392b;">المستطيل البني في الأسفل يمثّل مخطّط المكدّس buttonsLayout</span>
</p>

<p>
	بالنسبة لمعالجيّ حدثيّ النقر بالنسبة للزرّين btnPrev (الأسطر من 73 إلى 84) وbtnNext (الأسطر من 86 إلى 97) فيحتويان على منطق برمجيّ بسيط يضمن التنقّل الصحيح بين الصور الخمس الموجودة ضمن مصدر resource التطبيق. وأخيرًا يعمل التابع UpdateScreen (الأسطر من 99 إلى 104) على تحديث البيانات التي تظهر على عنصري اللصيقة والصورة عند كلّ نقر لزر "التالي" و"السابق". يتطلّب التابع FromResource من الصنف ImageSource وسيطًا نصيًّا يمثّل معرّف الملف. يتكوّن معرّف الملف من اسم التطبيق (أو بمعنى أدق التجميعة Assembly) متبوعًا بنقطة ثم اسم المجلّد الذي يحتوي على ملف الصورة متبوعًا بنقطة أخرى، ثم أخيرًا اسم الملف مع امتداده. في مثالنا هذا يكون معرّف الملف res01.jpg مثلًا على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-html prettyprinted" id="ips_uid_3551_15">
<span class="pln">ResourceImageApp.Images.res01.jpg
</span></pre>

<p>
	نُشكّل هذا المعرّف في السطر 102 من خلال التابع الساكن Format من الصنف string. حيث نختار الملف المطلوب من خلال قيمة المتغيّر currentIndex الذي يمثّل رقم ملف الصورة الحالي.
</p>

<p>
	ربما تبدو شيفرة هذا التطبيق كبيرة نسبيًّا، ولكن أؤكّد لك أنّك ستكتب أضعافًا منها في أيّ برنامج تجاري من الممكن أن تعمل عليه! يعود سبب ذلك إلى الأسلوب الذي انتهجناه منذ بداية هذه السلسلة حتى الآن، وهو الاعتماد على الشيفرة البرمجيّة في إنشاء واجهة المستخدم بالكامل. ورغم أنّه من الممكن اتباع أساليب جيّدة تساهم في ترتيب وتنظيم هذه الشيفرة بشكل كبير، إلّا أنّ العديد من المطوّرين يفضّلون استخدام الأسلوب الآخر في تطوير تطبيقات باستخدام Xamarin.Forms والذي يتمثّل في استخدام XAML (رُماز شبيه بـ XML) والذي يسمح بفصل واجهة المستخدم عن الشيفرة البرمجيّة. سنتناول هذا الموضوع بالطبع في دروس قادمة.
</p>

<h3>
	الخلاصة
</h3>

<p>
	تعاملنا في هذا الدرس مع الصور في Xamarin.Forms. حيث ناقشنا الموضوع من جانبين مختلفين. يهتم الجانب الأوّل بتحميل الصورة من الإنترنت (ومن الممكن من شبكة محليّة أيضًا)، أمّا الجانب الثاني فيهتمّ بتحميل الصورة من مصدر محلّي. هناك المزيد للحديث عنه في هذا الموضوع، وخاصّةً فيما يتعلّق بالحصول على الصور من خلال مصادر الصور المرتبطة بالجهاز platform-specific أو بمعنى أدق المرتبطة بنظام التشغيل الذي يعمل على الجهاز والذي هو نظام أندرويد في حالتنا. أي ما يشبه الأسلوب المتبع عند العمل مع مصادر الصور من خلال Android Studio. سنغطّي هذا الموضوع لاحقًا في هذه السلسلة.
</p>
]]></description><guid isPermaLink="false">454</guid><pubDate>Wed, 02 Nov 2016 21:00:00 +0000</pubDate></item><item><title>&#x627;&#x644;&#x627;&#x633;&#x62A;&#x62C;&#x627;&#x628;&#x629; &#x644;&#x623;&#x62D;&#x62F;&#x627;&#x62B; &#x627;&#x644;&#x646;&#x642;&#x631; &#x641;&#x64A; Xamarin</title><link>https://academy.hsoub.com/programming/c-sharp/xamarin/%D8%A7%D9%84%D8%A7%D8%B3%D8%AA%D8%AC%D8%A7%D8%A8%D8%A9-%D9%84%D8%A3%D8%AD%D8%AF%D8%A7%D8%AB-%D8%A7%D9%84%D9%86%D9%82%D8%B1-%D9%81%D9%8A-xamarin-r415/</link><description><![CDATA[
<p><img src="https://academy.hsoub.com/uploads/monthly_2017_02/xamarin-009.png.51aaa247ae991238aa59bb08c1d5602a.png" /></p>

<p>
	تعاملنا في الدروس السابقة في هذه السلسلة مع عناصر مرئيّة وظيفتها الأساسيّة عرض البيانات بشكل مناسب إلى المستخدم. في الحقيقة يوجد نوع آخر من العناصر المرئيّة، يتضمّن تلك العناصر التي يمكن أن يتفاعل المستخدم معها لتنفيذ أمر أو مهمّة معيّنة. سنتناول في هذا الدرس الممتع عنصر الزر Button وهو عنصر مرئي يسمح للمستخدم عند نقره (أو بالأحرى لمسه) بأن ينفّذ أمرًا معيّنًا.
</p>

<p style="text-align: center;">
	<img class="ipsImage ipsImage_thumbnailed" data-fileid="21078" data-unique="2djr2ccly" src="https://academy.hsoub.com/uploads/monthly_2017_02/xamarin-009.png.8b69260ebdf9d1215e5c1c26678f77fd.png" alt="xamarin-009.png"></p>

<h2 id="تطبيق-العداد">
	تطبيق العدّاد
</h2>

<p>
	وهو تطبيق بسيط، الغرض منه فهم كيفيّة التعامل مع الأزرار في Xamarin.Forms. تتكوّن واجهة هذا التطبيق من زرّين بالإضافة إلى لصيقة. فكرة التطبيق بسيطة، فعندما ينقر المستخدم أحد الزرّين يزداد العدد المعروض على اللصيقة بمقدار واحد، وعندما ينقر على الزر الآخر ينقص هذا العدد بمقدار واحد أيضًا.<br>
	أنشئ تطبيقًا جديدًا من النوع Blank App (Xamarin.Forms Portable) كما هو معتاد وسمّه CounterApp، وأبق فقط على المشروعين CounterApp.Droid و CounterApp (Portable) ضمنه. أضف صفحة محتوى ContentPage جديدة سمّها CounterPage. احرص على أن يكون محتوى الملف CounterPage.cs على الشكل التالي:
</p>

<pre>
 </pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9186_7">
<span class="lit">1</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">System</span><span class="pun">;</span><span class="pln">
</span><span class="lit">2</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">
</span><span class="lit">3</span><span class="pln">
</span><span class="lit">4</span><span class="pln">	</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">CounterApp</span><span class="pln">
</span><span class="lit">5</span><span class="pln">	</span><span class="pun">{</span><span class="pln">
</span><span class="lit">6</span><span class="pln">	    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">CounterPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
</span><span class="lit">7</span><span class="pln">	    </span><span class="pun">{</span><span class="pln">
</span><span class="lit">8</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> </span><span class="typ">int</span><span class="pln"> counter </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
</span><span class="lit">9</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> </span><span class="typ">Label</span><span class="pln"> lblDisplay</span><span class="pun">;</span><span class="pln">
</span><span class="lit">10</span><span class="pln">
</span><span class="lit">11</span><span class="pln">	        </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">CounterPage</span><span class="pun">()</span><span class="pln">
</span><span class="lit">12</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">13</span><span class="pln">	            </span><span class="typ">Button</span><span class="pln"> btnIncrement </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">
</span><span class="lit">14</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">15</span><span class="pln">	                </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"+"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">16</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">CenterAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">17</span><span class="pln">	                </span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Device</span><span class="pun">.</span><span class="typ">GetNamedSize</span><span class="pun">(</span><span class="typ">NamedSize</span><span class="pun">.</span><span class="typ">Large</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">typeof</span><span class="pun">(</span><span class="typ">Label</span><span class="pun">))</span><span class="pln">
</span><span class="lit">18</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">19</span><span class="pln">	            btnIncrement</span><span class="pun">.</span><span class="typ">Clicked</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> btnIncrement_Clicked</span><span class="pun">;</span><span class="pln">
</span><span class="lit">20</span><span class="pln">
</span><span class="lit">21</span><span class="pln">	            </span><span class="typ">Button</span><span class="pln"> btnDecrement </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">
</span><span class="lit">22</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">23</span><span class="pln">	                </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"-"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">24</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">CenterAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">25</span><span class="pln">	                </span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Device</span><span class="pun">.</span><span class="typ">GetNamedSize</span><span class="pun">(</span><span class="typ">NamedSize</span><span class="pun">.</span><span class="typ">Large</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">typeof</span><span class="pun">(</span><span class="typ">Label</span><span class="pun">))</span><span class="pln">
</span><span class="lit">26</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">27</span><span class="pln">	            btnDecrement</span><span class="pun">.</span><span class="typ">Clicked</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> </span><span class="typ">BtnDecrement_Clicked</span><span class="pun">;</span><span class="pln">
</span><span class="lit">28</span><span class="pln">
</span><span class="lit">29</span><span class="pln">	            lblDisplay </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Label</span><span class="pln">
</span><span class="lit">30</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">31</span><span class="pln">	                </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"0"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">32</span><span class="pln">	                </span><span class="typ">TextColor</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Color</span><span class="pun">.</span><span class="typ">Accent</span><span class="pun">,</span><span class="pln">
</span><span class="lit">33</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">CenterAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">34</span><span class="pln">	                </span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Device</span><span class="pun">.</span><span class="typ">GetNamedSize</span><span class="pun">(</span><span class="typ">NamedSize</span><span class="pun">.</span><span class="typ">Large</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">typeof</span><span class="pun">(</span><span class="typ">Label</span><span class="pun">))</span><span class="pln">
</span><span class="lit">35</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">36</span><span class="pln">
</span><span class="lit">37</span><span class="pln">	            </span><span class="typ">Content</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StackLayout</span><span class="pln">
</span><span class="lit">38</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">39</span><span class="pln">	                </span><span class="typ">Children</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="lit">40</span><span class="pln">	                    </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StackLayout</span><span class="pln">
</span><span class="lit">41</span><span class="pln">	                    </span><span class="pun">{</span><span class="pln">
</span><span class="lit">42</span><span class="pln">	                        </span><span class="typ">Orientation</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">StackOrientation</span><span class="pun">.</span><span class="typ">Horizontal</span><span class="pun">,</span><span class="pln">
</span><span class="lit">43</span><span class="pln">	                        </span><span class="typ">Padding</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Thickness</span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="lit">64</span><span class="pun">,</span><span class="lit">0</span><span class="pun">,</span><span class="lit">64</span><span class="pun">),</span><span class="pln">
</span><span class="lit">44</span><span class="pln">	                        </span><span class="typ">Children</span><span class="pln"> </span><span class="pun">=</span><span class="pln">
</span><span class="lit">45</span><span class="pln">	                        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">46</span><span class="pln">	                            btnIncrement</span><span class="pun">,</span><span class="pln">
</span><span class="lit">47</span><span class="pln">	                            btnDecrement
</span><span class="lit">48</span><span class="pln">	                        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">49</span><span class="pln">	                    </span><span class="pun">},</span><span class="pln">
</span><span class="lit">50</span><span class="pln">	                    lblDisplay
</span><span class="lit">51</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">52</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">53</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">54</span><span class="pln">
</span><span class="lit">55</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> </span><span class="typ">BtnDecrement_Clicked</span><span class="pun">(</span><span class="pln">object sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">EventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
</span><span class="lit">56</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">57</span><span class="pln">	            counter</span><span class="pun">--;</span><span class="pln">
</span><span class="lit">58</span><span class="pln">	            lblDisplay</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> counter</span><span class="pun">.</span><span class="typ">ToString</span><span class="pun">();</span><span class="pln">
</span><span class="lit">59</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">60</span><span class="pln">
</span><span class="lit">61</span><span class="pln">	        </span><span class="kwd">private</span><span class="pln"> </span><span class="kwd">void</span><span class="pln"> btnIncrement_Clicked</span><span class="pun">(</span><span class="pln">object sender</span><span class="pun">,</span><span class="pln"> </span><span class="typ">EventArgs</span><span class="pln"> e</span><span class="pun">)</span><span class="pln">
</span><span class="lit">62</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">63</span><span class="pln">	            counter</span><span class="pun">++;</span><span class="pln">
</span><span class="lit">64</span><span class="pln">	            lblDisplay</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> counter</span><span class="pun">.</span><span class="typ">ToString</span><span class="pun">();</span><span class="pln">   
</span><span class="lit">65</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">66</span><span class="pln">	    </span><span class="pun">}</span><span class="pln">
</span><span class="lit">67</span><span class="pln">	</span><span class="pun">}</span></pre>

<p>
	<strong>ملاحظة</strong><br>
	تذكّر أنّنا نضيف صفحة محتوى جديدة بالنقر بزر الفأرة الأيمن على المشروع CounterApp (Portable) ثم نختار Add وبعدها New Item، ومن النافذة التي تظهر، تختار Cross-Platform من القسم الأيسر، ومن القسم الأيمن نختار Forms ContentPage
</p>

<p>
	لقد صادفنا العديد من التقنيّات المستخدمة في هذا التطبيق وذلك في الدروس السابقة. مع وجود بعض الأمور الجديدة. فمثلًا ولأوّل مرّة وضعنا مخطّط مكدّس ضمن آخر، وهذا أمر شائع كثيرًا في تصميم الواجهات.<br>
	صرّحنا في السطر 8 عن الحقل الخاص <code>counter</code> وهو العدّاد الذي سيحتفظ بالقيمة الحالية للعدد المعروض ضمن اللصيقة، وأسندنا له القيمة الابتدائيّة 0. كما صرّحنا في السطر 9 عن الحقل الخاص <code>lblCounter</code> الذي سيمثّل اللصيقة التي سنعرض ضمنها قيمة العدّاد <code>Counter</code>. سنحتاج إلى كلّ من الحقلين السابقين ضمن توابع مختلفة من الصنف <code>CounterPage</code> لذلك وضعناهما على شكل حقلين خاصّين بهذه الصورة.<br>
	صرّحنا ضمن البانية <code>CounterPage</code> عن المتغيّر <code>btnIncrement</code> من النوع <code>Button</code> وأسندنا إليه كائن جديد من نوع زر <code>Button</code> حيث أسندنا قيم الخصائص مباشرةً عند الإنشاء، ووظيفة هذا الزر زيادة قيمة المتغيّر <code>counter</code> بمقدار واحد وعرض النتيجة ضمن اللصيقة كما سنرى لاحقًا. لاحظ أنّنا في السطر 19 قد أسندنا معالج الحدث <code>Clicked</code> لهذا الزر. اسم هذا المعالج <code>btnIncrement_Clicked</code> وقد صرّحنا عنه في الأسفل في الأسطر من 61 حتى 65. تكرّر نفس الأمر من أجل الزر <code>btnDecrement</code> (الأسطر من 21 حتى 27) ومعالج الحدث الخاص به <code>btnDecrement_Clicked</code> (الأسطر من 55 حتى 59) ووظيفة هذا الزر هي إنقاص قيمة المتغيّر <code>counter</code> بمقدار واحد وعرض النتيجة ضمن اللصيقة.<br>
	إذا انتقلنا إلى الخاصيّة <code>Content</code> للصنف <code>CounterPage</code> (السطر 37)، فنجد أنّه يتم إسناد مخطّط مكدّس جديد وهو يمتلك اتجاهًا رأسيًّا افتراضيًّا كما وسبق أن أوضحنا في درس سابق. سنُسند الخاصيّة <code>Children</code> له فحسب (السطر 39). تصرّح هذه الخاصيّة عن وجود ابنين لهذا المخطّط، الابن الأوّل هو مخطّط مكدّس آخر (الأسطر من 40 حتى 49)، والثاني هو اللصيقة <code>lblDisplay</code> التي ستعرض العدد الحالي:
</p>

<pre>
 </pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9186_9">
<span class="typ">Children</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StackLayout</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
        </span><span class="typ">Orientation</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">StackOrientation</span><span class="pun">.</span><span class="typ">Horizontal</span><span class="pun">,</span><span class="pln">
        </span><span class="typ">Padding</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Thickness</span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="lit">64</span><span class="pun">,</span><span class="lit">0</span><span class="pun">,</span><span class="lit">64</span><span class="pun">),</span><span class="pln">
        </span><span class="typ">Children</span><span class="pln"> </span><span class="pun">=</span><span class="pln">
        </span><span class="pun">{</span><span class="pln">
            btnIncrement</span><span class="pun">,</span><span class="pln">
            btnDecrement
        </span><span class="pun">}</span><span class="pln">
    </span><span class="pun">},</span><span class="pln">
    lblDisplay
</span><span class="pun">}</span></pre>

<p>
	بالنسبة لمخطّط المكدّس الابن كما يظهر من الشيفرة الأخيرة، لاحظ أنّنا نضبط خاصيّة الاتجاه <code>Orientation</code> له لتكون أفقيّة <code>StackOrientation.Horizontal</code>، كما وضعنا حشوة Padding مناسبة من الأعلى والأسفل لمحتواه، وأخيرًا أسندنا الخاصيّة <code>Children</code> له بحيث تحتوي على ابنين هنا زرّي الزيادة <code>btnIncrement</code> والإنقاص <code>btnDecrement</code> كما هو واضح.<br>
	إذًا سيحتوي المخطّط المكدّس الابن (الداخلي) على زرّين متموضّعين في الوسط أفقيًّا، وسيحتوي المخطّط المكدّس الأب (الخارجي) على مخطّط مكدّس ابن، وعلى لصيقة وهما متموضّعان رأسيًّا.<br>
	انتقل إلى الملف App.cs واحرص على أن تكون بانية الصنف <code>App</code> على الشكل التالي:
</p>

<pre>
 </pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9186_11">
<span class="kwd">public</span><span class="pln"> </span><span class="typ">App</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="com">// The root page of your application</span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">CounterPage</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	عند تنفيذ البرنامج باستخدام F5 ستحصل على شكل شبيه بما يلي، علمًا أنّني أجريت عدّة نقرات على كلّ من الزرّين:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="21079" href="https://academy.hsoub.com/uploads/monthly_2017_02/fig01.png.6202ce4a249feadd21919514cad365a7.png" rel=""><img alt="fig01.png" class="ipsImage ipsImage_thumbnailed" data-fileid="21079" data-unique="3bf8pirhv" src="https://academy.hsoub.com/uploads/monthly_2017_02/fig01.thumb.png.e870753ce5d88d7441cdd251b6969d50.png" style=""></a>
</p>

<h2 id="تحسين-تطبيق-العداد">
	تحسين تطبيق العدّاد
</h2>

<p>
	سنُجري بعض التحسينات البسيطة على تطبيق العدّاد السابق. حيث سنعيد هيكلة الشيفرة البرمجيّة بحيث نستخدم تعابير Lambda كمعالجات أحداث، بدلًا من توابع مستقلّة ضمن الصنف، وفي ذلك فائدة كبيرة، حيث يجعل ذلك الشيفرة البرمجيّة سهلة القراءة والصيانة إلى حدٍّ كبير، كما يمكننا عند ذلك أن نجعل الحقلين <code>counter</code> و <code>lblDisplay</code> عبارة عن متغيّرين محليّين ضمن بانية الصنف. سنضيف ميّزة بسيطة أخرى إلى هذا التطبيق تتمثّل في أنّ البرنامج سيرفض جعل قيمة العدّاد سالبة، حيث سيعرض رسالة بهذا الخصوص، ولا يُغيّر قيمة العدّاد في هذه الحالة.<br>
	أضف صفحة محتوى جديدة سمّها <code>EnhancedCounterPage</code> واحرص على أن تكون محتويات الملف <code>EnhancedCounterPage.cs</code> على الشكل التالي:
</p>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9186_13">
<span class="lit">1</span><span class="pln">	</span><span class="kwd">using</span><span class="pln"> </span><span class="typ">Xamarin</span><span class="pun">.</span><span class="typ">Forms</span><span class="pun">;</span><span class="pln">
</span><span class="lit">2</span><span class="pln">
</span><span class="lit">3</span><span class="pln">	</span><span class="kwd">namespace</span><span class="pln"> </span><span class="typ">CounterApp</span><span class="pln">
</span><span class="lit">4</span><span class="pln">	</span><span class="pun">{</span><span class="pln">
</span><span class="lit">5</span><span class="pln">	    </span><span class="kwd">public</span><span class="pln"> </span><span class="kwd">class</span><span class="pln"> </span><span class="typ">EnhancedCounterPage</span><span class="pln"> </span><span class="pun">:</span><span class="pln"> </span><span class="typ">ContentPage</span><span class="pln">
</span><span class="lit">6</span><span class="pln">	    </span><span class="pun">{</span><span class="pln">
</span><span class="lit">7</span><span class="pln">	        </span><span class="kwd">public</span><span class="pln"> </span><span class="typ">EnhancedCounterPage</span><span class="pun">()</span><span class="pln">
</span><span class="lit">8</span><span class="pln">	        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">9</span><span class="pln">	            </span><span class="typ">int</span><span class="pln"> counter </span><span class="pun">=</span><span class="pln"> </span><span class="lit">0</span><span class="pun">;</span><span class="pln">
</span><span class="lit">10</span><span class="pln">	
</span><span class="lit">11</span><span class="pln">	            </span><span class="typ">Label</span><span class="pln"> lblDisplay </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Label</span><span class="pln">
</span><span class="lit">12</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">13</span><span class="pln">	                </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"0"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">14</span><span class="pln">	                </span><span class="typ">TextColor</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Color</span><span class="pun">.</span><span class="typ">Accent</span><span class="pun">,</span><span class="pln">
</span><span class="lit">15</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">CenterAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">16</span><span class="pln">	                </span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Device</span><span class="pun">.</span><span class="typ">GetNamedSize</span><span class="pun">(</span><span class="typ">NamedSize</span><span class="pun">.</span><span class="typ">Large</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">typeof</span><span class="pun">(</span><span class="typ">Label</span><span class="pun">))</span><span class="pln">
</span><span class="lit">17</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">18</span><span class="pln">	
</span><span class="lit">19</span><span class="pln">	            </span><span class="typ">Button</span><span class="pln"> btnIncrement </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">
</span><span class="lit">20</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">21</span><span class="pln">	                </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"+"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">22</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">CenterAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">23</span><span class="pln">	                </span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Device</span><span class="pun">.</span><span class="typ">GetNamedSize</span><span class="pun">(</span><span class="typ">NamedSize</span><span class="pun">.</span><span class="typ">Large</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">typeof</span><span class="pun">(</span><span class="typ">Label</span><span class="pun">))</span><span class="pln">
</span><span class="lit">24</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">25</span><span class="pln">	            btnIncrement</span><span class="pun">.</span><span class="typ">Clicked</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">s</span><span class="pun">,</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
</span><span class="lit">26</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">27</span><span class="pln">	                counter</span><span class="pun">++;</span><span class="pln">
</span><span class="lit">28</span><span class="pln">	                lblDisplay</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> counter</span><span class="pun">.</span><span class="typ">ToString</span><span class="pun">();</span><span class="pln">
</span><span class="lit">29</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">30</span><span class="pln">	
</span><span class="lit">31</span><span class="pln">	            </span><span class="typ">Button</span><span class="pln"> btnDecrement </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Button</span><span class="pln">
</span><span class="lit">32</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">33</span><span class="pln">	                </span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="str">"-"</span><span class="pun">,</span><span class="pln">
</span><span class="lit">34</span><span class="pln">	                </span><span class="typ">HorizontalOptions</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">LayoutOptions</span><span class="pun">.</span><span class="typ">CenterAndExpand</span><span class="pun">,</span><span class="pln">
</span><span class="lit">35</span><span class="pln">	                </span><span class="typ">FontSize</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">Device</span><span class="pun">.</span><span class="typ">GetNamedSize</span><span class="pun">(</span><span class="typ">NamedSize</span><span class="pun">.</span><span class="typ">Large</span><span class="pun">,</span><span class="pln"> </span><span class="kwd">typeof</span><span class="pun">(</span><span class="typ">Label</span><span class="pun">))</span><span class="pln">
</span><span class="lit">36</span><span class="pln">	                </span><span class="pun">};</span><span class="pln">
</span><span class="lit">37</span><span class="pln">	                btnDecrement</span><span class="pun">.</span><span class="typ">Clicked</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">s</span><span class="pun">,</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
</span><span class="lit">38</span><span class="pln">	                </span><span class="pun">{</span><span class="pln">
</span><span class="lit">39</span><span class="pln">	                    </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">counter </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln">
</span><span class="lit">40</span><span class="pln">	                    </span><span class="pun">{</span><span class="pln">
</span><span class="lit">41</span><span class="pln">	                    </span><span class="typ">DisplayAlert</span><span class="pun">(</span><span class="str">"تحذير"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"لا يمكن لقيمة العدّاد أن تكون أصغر من الصفر"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"موافق"</span><span class="pun">);</span><span class="pln">
</span><span class="lit">42</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">43</span><span class="pln">	                </span><span class="kwd">else</span><span class="pln">
</span><span class="lit">44</span><span class="pln">	                </span><span class="pun">{</span><span class="pln">
</span><span class="lit">45</span><span class="pln">	                    counter</span><span class="pun">--;</span><span class="pln">
</span><span class="lit">46</span><span class="pln">	                    lblDisplay</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> counter</span><span class="pun">.</span><span class="typ">ToString</span><span class="pun">();</span><span class="pln">
</span><span class="lit">47</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">48</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">49</span><span class="pln">	
</span><span class="lit">50</span><span class="pln">	            </span><span class="typ">Content</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StackLayout</span><span class="pln">
</span><span class="lit">51</span><span class="pln">	            </span><span class="pun">{</span><span class="pln">
</span><span class="lit">52</span><span class="pln">	                </span><span class="typ">Children</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="pun">{</span><span class="pln">
</span><span class="lit">53</span><span class="pln">	                    </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">StackLayout</span><span class="pln">
</span><span class="lit">54</span><span class="pln">	                    </span><span class="pun">{</span><span class="pln">
</span><span class="lit">55</span><span class="pln">	                        </span><span class="typ">Orientation</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="typ">StackOrientation</span><span class="pun">.</span><span class="typ">Horizontal</span><span class="pun">,</span><span class="pln">
</span><span class="lit">56</span><span class="pln">	                        </span><span class="typ">Padding</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">Thickness</span><span class="pun">(</span><span class="lit">0</span><span class="pun">,</span><span class="lit">64</span><span class="pun">,</span><span class="lit">0</span><span class="pun">,</span><span class="lit">64</span><span class="pun">),</span><span class="pln">
</span><span class="lit">57</span><span class="pln">	                        </span><span class="typ">Children</span><span class="pln"> </span><span class="pun">=</span><span class="pln">
</span><span class="lit">58</span><span class="pln">	                        </span><span class="pun">{</span><span class="pln">
</span><span class="lit">59</span><span class="pln">	                            btnIncrement</span><span class="pun">,</span><span class="pln">
</span><span class="lit">60</span><span class="pln">	                            btnDecrement
</span><span class="lit">61</span><span class="pln">	                        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">62</span><span class="pln">	                    </span><span class="pun">},</span><span class="pln">
</span><span class="lit">63</span><span class="pln">	                    lblDisplay
</span><span class="lit">64</span><span class="pln">	                </span><span class="pun">}</span><span class="pln">
</span><span class="lit">65</span><span class="pln">	            </span><span class="pun">};</span><span class="pln">
</span><span class="lit">66</span><span class="pln">	        </span><span class="pun">}</span><span class="pln">
</span><span class="lit">67</span><span class="pln">	    </span><span class="pun">}</span><span class="pln">
</span><span class="lit">68</span><span class="pln">	</span><span class="pun">}</span></pre>

<p>
	جعلنا كل من الحقلين <code>counter</code> و<code>lblDisplay</code> عبارة عن متغيّرين محليّين (السطرين 9 و11). كما تجدر الملاحظة أنّ معالجات الأحداث التقليديّة قد اختفت، وحلّ محلّها تعابير Lambda. انظر إلى الزر <code>btnIncrement</code> في الأسطر من 25 حتى 29:
</p>

<pre>
 </pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9186_15">
<span class="pln">btnIncrement</span><span class="pun">.</span><span class="typ">Clicked</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">s</span><span class="pun">,</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    counter</span><span class="pun">++;</span><span class="pln">
    lblDisplay</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> counter</span><span class="pun">.</span><span class="typ">ToString</span><span class="pun">();</span><span class="pln">
</span><span class="pun">};</span></pre>

<p>
	صرّحنا عن تعبير Lambda يقبل وسيطين <code>s</code> و <code>e</code>، ويعمل على زيادة قيمة المتغيّر <code>counter</code> بمقدار 1 ويعرض النتيجة ضمن اللصيقة. نفس الأمر تمامًا يسري على الزر <code>btnDecrement</code>. انظر إلى الأسطر من 37 حتى 48:
</p>

<pre>
 </pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9186_21">
<span class="pln">btnDecrement</span><span class="pun">.</span><span class="typ">Clicked</span><span class="pln"> </span><span class="pun">+=</span><span class="pln"> </span><span class="pun">(</span><span class="pln">s</span><span class="pun">,</span><span class="pln"> e</span><span class="pun">)</span><span class="pln"> </span><span class="pun">=&gt;</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="kwd">if</span><span class="pln"> </span><span class="pun">(</span><span class="pln">counter </span><span class="pun">==</span><span class="pln"> </span><span class="lit">0</span><span class="pun">)</span><span class="pln">
    </span><span class="pun">{</span><span class="pln">
    </span><span class="typ">DisplayAlert</span><span class="pun">(</span><span class="str">"تحذير"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"لا يمكن لقيمة العدّاد أن تكون أصغر من الصفر"</span><span class="pun">,</span><span class="pln"> </span><span class="str">"موافق"</span><span class="pun">);</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="kwd">else</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    counter</span><span class="pun">--;</span><span class="pln">
    lblDisplay</span><span class="pun">.</span><span class="typ">Text</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> counter</span><span class="pun">.</span><span class="typ">ToString</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span><span class="pln">
</span><span class="pun">};</span></pre>

<p>
	الفرق الوحيد هنا أنّنا نختبر قيمة المتغيّر <code>counter</code> في حال كان يساوي الصفر قبل إنقاصه، وبالتالي عرض رسالة مناسبة في حال كان كذلك من خلال التابع <code>DisplayAlert</code> (وهو من الصنف <code>ContentPage</code> وكان يمكن أن نصل إليه عن طريق الكلمة المحجوزة <code>this</code> أيضًا). يحتاج التابع <code>DisplayAlert</code> في أحد أشكاله (وهو الشكل المستخدم هنا) إلى ثلاثة وساط هي: عنوان الرسالة، والنص المعروض ضمنها، والنص المعروض على زر الإلغاء، على الترتيب. توجد أشكال أخرى سنتناولها تباعًا ضمن هذه السلسلة.<br>
	انتقل إلى الملف <code>App.cs</code> وتأكّد أنّ بانية الصنف <code>App</code> على الشكل التالي:
</p>

<pre>
 </pre>

<pre class="ipsCode prettyprint lang-c prettyprinted" id="ips_uid_9186_23">
<span class="kwd">public</span><span class="pln"> </span><span class="typ">App</span><span class="pun">()</span><span class="pln">
</span><span class="pun">{</span><span class="pln">
    </span><span class="com">// The root page of your application</span><span class="pln">
    </span><span class="typ">MainPage</span><span class="pln"> </span><span class="pun">=</span><span class="pln"> </span><span class="kwd">new</span><span class="pln"> </span><span class="typ">EnhancedCounterPage</span><span class="pun">();</span><span class="pln">
</span><span class="pun">}</span></pre>

<p>
	نفّذ البرنامج وانقر الزر (-) مباشرةً أي عندما تكون القيمة الظاهرة على اللصيقة هي صفر، مما سيؤدّي إلى ظهور رسالة التنبيه كما في الشكل التالي:
</p>

<p style="text-align: center;">
	<a class="ipsAttachLink ipsAttachLink_image" data-fileid="21080" href="https://academy.hsoub.com/uploads/monthly_2017_02/fig02.png.abe937f09b5f7dd71c5e8ddca82bff07.png" rel=""><img alt="fig02.png" class="ipsImage ipsImage_thumbnailed" data-fileid="21080" data-unique="sbpo5k7be" src="https://academy.hsoub.com/uploads/monthly_2017_02/fig02.thumb.png.bec1bf8447674854c8c58b144ecf6cd2.png" style=""></a>
</p>

<h2 id="الخلاصة">
	الخلاصة
</h2>

<p>
	تناولنا في هذا الدرس مبادئ التعامل مع الأزرار في Xamarin.Forms من خلال تطبيقين أساسيّين يتفاعلان مع المستخدم. بالإضافة إلى الحديث عن كيفيّة عرض رسائل مخصّصة للمستخدم باستخدام التابع <code>DisplayAlert</code>. هناك العديد من المزايا التي تتمتّع بها الأزرار في Xamarin.Forms. سنستعرض لاحقًا في هذه السلسلة للمزيد من المزايا الإضافيّة للأزرار بالإضافة إلى عناصر مرئيّة أخرى يمكن للمستخدم أن يتفاعل معها.
</p>
]]></description><guid isPermaLink="false">415</guid><pubDate>Tue, 18 Oct 2016 23:00:00 +0000</pubDate></item></channel></rss>
