24-06-2011, 11:32 AM
اساسيات XAML:
حتى نفهم XAML ، علينا ان نتذكر القواعد التالية:
- كل عنصر في مستند XAML يتم ترجمته إلى مثيل من فئة في الدوت نت. ودائما يكون اسم العنصر مطابقا لأسم فئة معينة، مثلا العنصر <Button> يمثل امر لـ XAML من اجل إنشاء كائن من الفئة Button.
- كما هو الحال في اي مستند XML ، يمكن للعناصر ان تتداخل، وتقوم XAML بتفسير هذا التداخل على انه احتواء ، فإذا وجدت عنصر Button داخل عنصر Grid ، فإن هذا يعني ان الواجهة سوف تتضمن Grid يحتوي على زر
- يمكن تعيين الخصائص من خلال الواصفات (Attributes) ، لكن في بعض الحالات تكون الواصفة غير كافية لتحديد قيمة الخاصية ، لذا فإننا نستخدم صيغة اخرى تسمى بالعنصر الخاصية (Property Element).
لكن قبل ان ندخل في التفاصيل ، لنحاول اولاً ان نلقي نظرة على مستند XAML يمثل نافذة جديدة في الفيجوال استديو(الأسطر مرقمة للتوضيح فقط):
كما تلاحظ إن هذا المستند يحتوي على عنصرين فقط ، هما العنصر الجذر والمتمثل في النافذة والعنصر الآخر هو Grid يمكن وضع عناصر اخرى بداخله مثل الكنترولات والأشكال والصور وغيرها.
وبشكل عام يمكن ان يكون العنصر الجذر من اي نوع ، لكنه في WPF غالبا ما يكون احد الأنواع التالية:
- Window
- Page
- Application
- ResourceDictionary
وكما هو الحال مع اي مستند XML فإن كل مستند XAML يجب ان يحتوي على عنصر جذر واحد فقط ، ما يعني انه بمجرد ان نغلق عنصرالنافذة بالوسم </Window> فإن المستند ينتهي عند هذا الحد ولا يمكن ان يأتي اي شئ بعده.
إذا نظرنا إلى الوسم الأفتتاحي للنافذة فإننا سوف نجد العديد من الواصفات التي تم استخدامها، فهناك واصفة الفئة المقابلة ، وواصفتين من اجل تحديد مجالين للاسماء ، بينما الواصفات:
يمثل كل منها خاصية معينة في النافذة وبالتالي فإن النافذة يكون عنوانها Window1 وحجمها 300 في 300 وحدة.
مجالات الأسماء في XAML
من المعروف ان الفئات في الدوت نت تكون داخل مجالات الأسماء(Namespaces) ، وحتى تستطيع XAML تحديد الفئة المقابلة فإنها تحتاج إلى اسم الفئة واسم المجال الذي يحتويها.
وكما عرفنا إن اسم الفئة يتم تحديده في اسم العنصر ، بينما اسم المجال يتم تحديده من خلال الواصفة xmlns الخاصة بـ XML . وعندما ننظر في مستند XAML السابق فإننا نجد ان هناك مجالين اسماء هما:
هذين المجالين سوف نجدهما في معظم مستندات XAML وكل مجال يؤدي وظيفة معينة:
- المجال http://schemas.microsoft.com/winfx/2006/...esentation وهو خاص بـ WPF و يتضمن جميع الفئات في WPF بما فيها الكنترولات التي سوف نستخدمها من اجل إنشاء الواجهة. هذا المجال تم التصريح عنه بدون اي بادئة لذا يتم التعامل معه على انه المجال الأفتراضي في المستند، واي عنصر سوف ينتمي لهذا المجال بشكل افتراضي.
- المجال http://schemas.microsoft.com/winfx/2006/xaml وهو خاص بـ XAML ويتضمن بعض الوظائف والعناصر ال****** في إنشاء المستند. نلاحظ ان هذا المجال قد تم التصريح عنه مع البادئة x ، وهذا يعني انه من اجل استخدام اي عنصر ينتمي له فيجب ان نكتب اسمه مسبوقا بتلك البادئة ، مثل : <x:ElementName>.
هذا النوع من التصريح عن مجال الأسماء يسمى بالمجال القائم على اساس URI ، وهناك نوع آخر سوف نتطرق له لاحقا، لكن ما يميز هذه الطريقة ان المجال في XML يتضمن اكثر من مجال مقابل في الدوت نت ، مثلا http://schemas.microsoft.com/winfx/2006/...esentation يتضمن الكثير من المجالات في الدوت نت (جميعها تبدأ بـ System.Windows).
Code-Behind
نستطيع من خلال XAML إنشاء وتعريف واجهة المستخدم ، لكن من اجل تعريف الوظائف في التطبيق التي ستستجيب لأحداث المستخدم فإننا نحتاج إلى كتابة الكود .
ربط مستند XAML بفئة في كود التطبيق يتم من خلال الواصفة x:Class التي تكون صيغتها بهذا الشكل:
في المثال السابق سوف نجد:
وهي تخبر XAML بإن يقوم بإنشاء فئة جديدة اسمها Windows1 في المجال WpfApplication1 وتكون مشتقة من الفئة Window .
لاحظ ان هذه الواصفة تبدأ بـ x ما يعني انها تنتمي إلى المجال الخاص بـ XAML ويمكن استخدامها مع العنصر الجذر فقط.
يتم تجزئة الفئة Windows1 في ملفين هما:
- الملف الأول(Window1.g.cs) : يحتوي على الكود الذي يتم توليده تلقائيا في زمن الترجمة (compile time).
- الملف الثاني (Window1.xaml.cs): من اجل ان نقوم بتعريف الدوال التي تعالج الأحداث التي تصدر من العناصر في النافذة، وهذا الملف هو الذي سنتعامل معه بشكل اساسي.
عندما نقوم بالقاء نظرة على الملف Window1.xaml.cs سوف نجده بهذا الشكل:
وكما نرى ان هذه الفئة حتى الآن لا تحتوي على اي دالة باستثناء المشيد الأفتراضي الذي يقوم باستدعاء الدالة InitializeComponent() ، وهذه الدالة يتم توليدها تلقائيا خلال عملية الترجمة ، ولا تحتاج منا إلى اي تعديل (في الواقع اي تعديل عليها بشكل يدوي سوف يختفي خلال عملية التوليد التالية).
وإذا احتجنا إلى ان نضيف كود إلى المشيد ، فيجب ان نتأكد انه يقوم باستدعاء InitializeComponent().
تسمية العناصر:
غالبا ما نحتاج إلى كتابة الكود (Code-Behind) الذي يقوم بتغيير خصائص عنصر او اكثر في واجهة المستخدم ، ويمكننا الوصول إلى اي عنصر بشرط ان نقوم بتسميته.
تسمية العناصر في XAML تتم من خلال الواصفة x:Name التي يمكن استخدامها مع اي عنصر يمثل كائن، فلو اردنا ان نسمي العنصر Grid:
ويقوم XAML تلقائيا بإضافة حقل إلى الفئة يمثل ذلك العنصر:
ومن خلال هذا الحقل يمكننا التعامل مع العنصر Grid
تذكر ان الواصفة x:Name تنتمي إلى لغة XAML ، ويمكن تطبيقها على اي عنصر في XAML .
استخدام الخاصية Name في العناصر:
الكثير من العناصر في WPF تحتوي على الخاصية Name . ومثل هذا العناصر يمكن تسميتها سواء باستخدام الواصفة x:Name او باستخدام الخاصية Name .
فالعنصر Grid على سبيل المثال يحتوي على الخاصية Name (المعرفة اساسا في الفئة الأب FrameworkElement) ويمكن تسميته من خلالها بالشكل التالي:
وسواء استخدمت الواصفة x:Name او الخاصية Name فإن النتيجة تكون متساوية ، حيث يتم تحديد اسم الحقل وتحديد قيمة الخاصية Name .
حتى نفهم XAML ، علينا ان نتذكر القواعد التالية:
- كل عنصر في مستند XAML يتم ترجمته إلى مثيل من فئة في الدوت نت. ودائما يكون اسم العنصر مطابقا لأسم فئة معينة، مثلا العنصر <Button> يمثل امر لـ XAML من اجل إنشاء كائن من الفئة Button.
- كما هو الحال في اي مستند XML ، يمكن للعناصر ان تتداخل، وتقوم XAML بتفسير هذا التداخل على انه احتواء ، فإذا وجدت عنصر Button داخل عنصر Grid ، فإن هذا يعني ان الواجهة سوف تتضمن Grid يحتوي على زر
- يمكن تعيين الخصائص من خلال الواصفات (Attributes) ، لكن في بعض الحالات تكون الواصفة غير كافية لتحديد قيمة الخاصية ، لذا فإننا نستخدم صيغة اخرى تسمى بالعنصر الخاصية (Property Element).
لكن قبل ان ندخل في التفاصيل ، لنحاول اولاً ان نلقي نظرة على مستند XAML يمثل نافذة جديدة في الفيجوال استديو(الأسطر مرقمة للتوضيح فقط):
كود :
1 <Window x:Class="WpfApplication1.Window1"
2 xmlns="[url=http://schemas.microsoft.com/winfx/2006/xaml/presentation]http://schemas.microsoft.com/winfx/2006/xaml/presentation[/url]"
3 xmlns:x="[url=http://schemas.microsoft.com/winfx/2006/xaml]http://schemas.microsoft.com/winfx/2006/xaml[/url]"
4 Title="Window1" Height="300" Width="300">
5 <Grid>
6 </Grid>
7 </Window>وبشكل عام يمكن ان يكون العنصر الجذر من اي نوع ، لكنه في WPF غالبا ما يكون احد الأنواع التالية:
- Window
- Page
- Application
- ResourceDictionary
وكما هو الحال مع اي مستند XML فإن كل مستند XAML يجب ان يحتوي على عنصر جذر واحد فقط ، ما يعني انه بمجرد ان نغلق عنصرالنافذة بالوسم </Window> فإن المستند ينتهي عند هذا الحد ولا يمكن ان يأتي اي شئ بعده.
إذا نظرنا إلى الوسم الأفتتاحي للنافذة فإننا سوف نجد العديد من الواصفات التي تم استخدامها، فهناك واصفة الفئة المقابلة ، وواصفتين من اجل تحديد مجالين للاسماء ، بينما الواصفات:
كود :
4 Title="Window1" Height="300" Width="300">مجالات الأسماء في XAML
من المعروف ان الفئات في الدوت نت تكون داخل مجالات الأسماء(Namespaces) ، وحتى تستطيع XAML تحديد الفئة المقابلة فإنها تحتاج إلى اسم الفئة واسم المجال الذي يحتويها.
وكما عرفنا إن اسم الفئة يتم تحديده في اسم العنصر ، بينما اسم المجال يتم تحديده من خلال الواصفة xmlns الخاصة بـ XML . وعندما ننظر في مستند XAML السابق فإننا نجد ان هناك مجالين اسماء هما:
كود :
2 xmlns="[url=http://schemas.microsoft.com/winfx/2006/xaml/presentation]http://schemas.microsoft.com/winfx/2006/xaml/presentation[/url]"
3 xmlns:x="[url=http://schemas.microsoft.com/winfx/2006/xaml]http://schemas.microsoft.com/winfx/2006/xaml[/url]"- المجال http://schemas.microsoft.com/winfx/2006/...esentation وهو خاص بـ WPF و يتضمن جميع الفئات في WPF بما فيها الكنترولات التي سوف نستخدمها من اجل إنشاء الواجهة. هذا المجال تم التصريح عنه بدون اي بادئة لذا يتم التعامل معه على انه المجال الأفتراضي في المستند، واي عنصر سوف ينتمي لهذا المجال بشكل افتراضي.
- المجال http://schemas.microsoft.com/winfx/2006/xaml وهو خاص بـ XAML ويتضمن بعض الوظائف والعناصر ال****** في إنشاء المستند. نلاحظ ان هذا المجال قد تم التصريح عنه مع البادئة x ، وهذا يعني انه من اجل استخدام اي عنصر ينتمي له فيجب ان نكتب اسمه مسبوقا بتلك البادئة ، مثل : <x:ElementName>.
هذا النوع من التصريح عن مجال الأسماء يسمى بالمجال القائم على اساس URI ، وهناك نوع آخر سوف نتطرق له لاحقا، لكن ما يميز هذه الطريقة ان المجال في XML يتضمن اكثر من مجال مقابل في الدوت نت ، مثلا http://schemas.microsoft.com/winfx/2006/...esentation يتضمن الكثير من المجالات في الدوت نت (جميعها تبدأ بـ System.Windows).
Code-Behind
نستطيع من خلال XAML إنشاء وتعريف واجهة المستخدم ، لكن من اجل تعريف الوظائف في التطبيق التي ستستجيب لأحداث المستخدم فإننا نحتاج إلى كتابة الكود .
ربط مستند XAML بفئة في كود التطبيق يتم من خلال الواصفة x:Class التي تكون صيغتها بهذا الشكل:
كود :
<object x:Class="namespace.classname"...>
...
</object>في المثال السابق سوف نجد:
كود :
1 <Window x:Class="WpfApplication1.Window1"وهي تخبر XAML بإن يقوم بإنشاء فئة جديدة اسمها Windows1 في المجال WpfApplication1 وتكون مشتقة من الفئة Window .
لاحظ ان هذه الواصفة تبدأ بـ x ما يعني انها تنتمي إلى المجال الخاص بـ XAML ويمكن استخدامها مع العنصر الجذر فقط.
يتم تجزئة الفئة Windows1 في ملفين هما:
- الملف الأول(Window1.g.cs) : يحتوي على الكود الذي يتم توليده تلقائيا في زمن الترجمة (compile time).
- الملف الثاني (Window1.xaml.cs): من اجل ان نقوم بتعريف الدوال التي تعالج الأحداث التي تصدر من العناصر في النافذة، وهذا الملف هو الذي سنتعامل معه بشكل اساسي.
عندما نقوم بالقاء نظرة على الملف Window1.xaml.cs سوف نجده بهذا الشكل:
كود :
namespace WpfApplication1 ;
interface
type
Window = public partial class(System.Windows.Window)
public constructor;
end;
implementation
constructor Window;
begin
InitializeComponent();
end;
end.وكما نرى ان هذه الفئة حتى الآن لا تحتوي على اي دالة باستثناء المشيد الأفتراضي الذي يقوم باستدعاء الدالة InitializeComponent() ، وهذه الدالة يتم توليدها تلقائيا خلال عملية الترجمة ، ولا تحتاج منا إلى اي تعديل (في الواقع اي تعديل عليها بشكل يدوي سوف يختفي خلال عملية التوليد التالية).
وإذا احتجنا إلى ان نضيف كود إلى المشيد ، فيجب ان نتأكد انه يقوم باستدعاء InitializeComponent().
تسمية العناصر:
غالبا ما نحتاج إلى كتابة الكود (Code-Behind) الذي يقوم بتغيير خصائص عنصر او اكثر في واجهة المستخدم ، ويمكننا الوصول إلى اي عنصر بشرط ان نقوم بتسميته.
تسمية العناصر في XAML تتم من خلال الواصفة x:Name التي يمكن استخدامها مع اي عنصر يمثل كائن، فلو اردنا ان نسمي العنصر Grid:
كود :
<Grid x:Name="grid1">كود :
internal System.Windows.Controls.Grid grid1;كود :
MessageBox.Show(grid1.ActualHeight.ToString());استخدام الخاصية Name في العناصر:
الكثير من العناصر في WPF تحتوي على الخاصية Name . ومثل هذا العناصر يمكن تسميتها سواء باستخدام الواصفة x:Name او باستخدام الخاصية Name .
فالعنصر Grid على سبيل المثال يحتوي على الخاصية Name (المعرفة اساسا في الفئة الأب FrameworkElement) ويمكن تسميته من خلالها بالشكل التالي:
كود :
<Grid Name="grid1">
