الفريق العربي للبرمجةأرشيف المنتديات · 2000 – 2023
نسخة أرشيفية للقراءة فقط — التسجيل والمشاركة مغلقان، والمحتوى محفوظ كما كان.

تعلم Xaml

بدأه HassanAlattas في 3 سبتمبر 2009 · 11 رد · 8,661 مشاهدة · في Microsoft Visual C#.NET
مشاركة: واتساب X فيسبوك تيليجرام
#1 صاحب الموضوع

مقدمة:

XAML (اختصار لـ Extensible Application Markup Language وتلفظ "زامل")، وهي لغة وسوم لتمثيل الكائنات في الدوت نت، تم إنشائها خصيصاً من اجل WPF وتستخدم في تقنيات اخرى مثل WF (Workflow Foundation) و Silverlight.

في WPF تستخدم XAML اساسا من اجل تعريف واجهات المستخدم والغاية من هذا هو فصل الأجزاء المتعلقة بتعريف الواجهة عن الكود في التطبيق. بحيث يكون بامكان المصممين إنشاء الواجهات باستخدام ادوات مخصصة للتعامل مع الصور والرسومات مثل Microsoft Expression Blend، بينما يقوم المطورين بتعريف منطق وسلوك تلك الواجهات من خلال الكود باستخدام ادوات مثل Visual Studio.

تعتمد لغة XAML اساسا على لغة XML ، لذا فإن اي مستند XAML في الواقع هو ملف XML ، ويخضع لنفس القواعد والشروط، مثلها مثل اي لغة وسوم اخرى ، إلا ان XAML اكثر صرامة من غيرها حيث ان كل عنصر فيها يتم تحويله إلى كائن في الدوت نت.

وكونها تعتمد على XML ، فإن هذا اضاف سهولة ومرونة كبيرة ، فيمكن لاكثر من اداة ان تتعامل مع نفس المستند في نفس الوقت ، ومن السهل جدا قراءة مستندات XML ونقلها او حملها من جهاز إلى آخر.

وقد يظن البعض ان اعتماد XAML على XML له اثر على الأداء ، فمن المعروف ان XML لديها بعض المشاكل المتعلقة بهذا الشأن نظرا لأن المستند يمكن ان يحتوي على الكثير من الوسوم ما يجعل عملية الأعراب تأخذ وقتا اطول.

وللتغلب على هذه المشكلة فإن WPF تقوم بتحويل مستند XAML إلى الصورة الثنائية المكافئة له والتي تسمى بـ BAML (اختصار لـ Binary Application Markup Language)، وهذه التحويل يحدث بدون ان يشعر المبرمج خلال عملية الترجمة.

اساسيات XAML:

حتى نفهم XAML ، علينا ان نتذكر القواعد التالية:

- كل عنصر في مستند XAML يتم ترجمته إلى مثيل من فئة في الدوت نت. ودائما يكون اسم العنصر مطابقا لأسم فئة معينة، مثلا العنصر <Button> يمثل امر لـ XAML من اجل إنشاء كائن من الفئة Button.

- كما هو الحال في اي مستند XML ، يمكن للعناصر ان تتداخل، وتقوم XAML بتفسير هذا التداخل على انه احتواء ، فإذا وجدت عنصر Button داخل عنصر Grid ، فإن هذا يعني ان الواجهة سوف تتضمن Grid يحتوي على زر

- يمكن تعيين الخصائص من خلال الواصفات (Attributes) ، لكن في بعض الحالات تكون الواصفة غير كافية لتحديد قيمة الخاصية ، لذا فإننا نستخدم صيغة اخرى تسمى بالعنصر الخاصية (Property Element).

لكن قبل ان ندخل في التفاصيل ، لنحاول اولاً ان نلقي نظرة على مستند XAML يمثل نافذة جديدة في الفيجوال استديو(الأسطر مرقمة للتوضيح فقط):

1 <Window x:Class="WpfApplication1.Window1"
2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
4 Title="Window1" Height="300" Width="300">
5   <Grid>

6   </Grid>
7 </Window>

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

وبشكل عام يمكن ان يكون العنصر الجذر من اي نوع ، لكنه في WPF غالبا ما يكون احد الأنواع التالية:

- Window

- Page

- Application

- ResourceDictionary

وكما هو الحال مع اي مستند XML فإن كل مستند XAML يجب ان يحتوي على عنصر جذر واحد فقط ، ما يعني انه بمجرد ان نغلق عنصرالنافذة بالوسم </Window> فإن المستند ينتهي عند هذا الحد ولا يمكن ان يأتي اي شئ بعده.

إذا نظرنا إلى الوسم الأفتتاحي للنافذة فإننا سوف نجد العديد من الواصفات التي تم استخدامها، فهناك واصفة الفئة المقابلة ، وواصفتين من اجل تحديد مجالين للاسماء ، بينما الواصفات:

4 Title="Window1" Height="300" Width="300">

يمثل كل منها خاصية معينة في النافذة وبالتالي فإن النافذة يكون عنوانها Window1 وحجمها 300 في 300 وحدة.

مجالات الأسماء في XAML

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

وكما عرفنا إن اسم الفئة يتم تحديده في اسم العنصر ، بينما اسم المجال يتم تحديده من خلال الواصفة xmlns الخاصة بـ XML . وعندما ننظر في مستند XAML السابق فإننا نجد ان هناك مجالين اسماء هما:

2  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
3  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

هذين المجالين سوف نجدهما في معظم مستندات XAML وكل مجال يؤدي وظيفة معينة:

- المجال http://schemas.microsoft.com/winfx/2006/xaml/presentation وهو خاص بـ WPF و يتضمن جميع الفئات في WPF بما فيها الكنترولات التي سوف نستخدمها من اجل إنشاء الواجهة. هذا المجال تم التصريح عنه بدون اي بادئة لذا يتم التعامل معه على انه المجال الأفتراضي في المستند، واي عنصر سوف ينتمي لهذا المجال بشكل افتراضي.

- المجال http://schemas.microsoft.com/winfx/2006/xaml وهو خاص بـ XAML ويتضمن بعض الوظائف والعناصر المساعدة في إنشاء المستند. نلاحظ ان هذا المجال قد تم التصريح عنه مع البادئة x ، وهذا يعني انه من اجل استخدام اي عنصر ينتمي له فيجب ان نكتب اسمه مسبوقا بتلك البادئة ، مثل : <x:ElementName>.

هذا النوع من التصريح عن مجال الأسماء يسمى بالمجال القائم على اساس URI ، وهناك نوع آخر سوف نتطرق له لاحقا، لكن ما يميز هذه الطريقة ان المجال في XML يتضمن اكثر من مجال مقابل في الدوت نت ، مثلا http://schemas.microsoft.com/winfx/2006/xaml/presentation يتضمن الكثير من المجالات في الدوت نت (جميعها تبدأ بـ 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
{
	/// <summary>
	/// Interaction logic for Window1.xaml
	/// </summary>
	public partial class Window1 : Window
	{
		public Window1()
		{
			InitializeComponent();
		}
	}
}

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

وإذا احتجنا إلى ان نضيف كود إلى المشيد ، فيجب ان نتأكد انه يقوم باستدعاء InitializeComponent().

تسمية العناصر:

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

تسمية العناصر في XAML تتم من خلال الواصفة x:Name التي يمكن استخدامها مع اي عنصر يمثل كائن، فلو اردنا ان نسمي العنصر Grid:

<Grid x:Name="grid1">

ويقوم XAML تلقائيا بإضافة حقل إلى الفئة يمثل ذلك العنصر:

internal System.Windows.Controls.Grid grid1;

ومن خلال هذا الحقل يمكننا التعامل مع العنصر Grid

MessageBox.Show(grid1.ActualHeight.ToString());

تذكر ان الواصفة x:Name تنتمي إلى لغة XAML ، ويمكن تطبيقها على اي عنصر في XAML .

استخدام الخاصية Name في العناصر:

الكثير من العناصر في WPF تحتوي على الخاصية Name . ومثل هذا العناصر يمكن تسميتها سواء باستخدام الواصفة x:Name او باستخدام الخاصية Name .

فالعنصر Grid على سبيل المثال يحتوي على الخاصية Name (المعرفة اساسا في الفئة الأب FrameworkElement) ويمكن تسميته من خلالها بالشكل التالي:

<Grid Name="grid1">

وسواء استخدمت الواصفة x:Name او الخاصية Name فإن النتيجة تكون متساوية ، حيث يتم تحديد اسم الحقل وتحديد قيمة الخاصية Name .

التعامل مع الخصائص البسيطة:

اصبح معروفا لدينا ان الواصفات في العنصر تقوم بتعيين الخصائص في الكائن المقابل في الدوت نت.

فلو اردنا إنشاء زر يحتوي على النص "This is a button" ويكون لون الخط احمر وخلفيته زرقاء ، فإننا نكتب:

<Button Background="Blue" Foreground="Red" Content="This is a button"/>

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

يمكننا ايضاً عمل نفس الزر السابق من خلال كود C# بالشكل التالي:

Button btn = new Button();
btn.Background = Brushes.Yellow;
btn.Foreground = Brushes.Red;
btn.Content = "This is a button";

محولات الأنواع:

تكون القيمة الواصفة دائما عبارة عن نص ، و المشكلة ان نوع الخصائص المقابلة قد يكون من اي نوع ، ففي الزر السابق ، سوف نجد ان الخاصية Background من النوع Brush .

وحتى تستطيع XAML تعيين مثل هذه الخصائص فلا بد لها اولا ان تقوم بتحويل القيمة النصية إلى قيمة مكافئة من نوع الخاصية المقابلة.

عملية التحويل تتم من خلال محولات النوع (TypeConverters) التي تقوم اساسا بتحويل قيمة من نوع إلى آخر. مثلا المحول BrushConverter مختص بتحويل القيمة من وإلى كائن من النوع Brush.

إذا لم يستطع المحول تحويل القيمة ، او إذا لم تستطع XAML تحديد المحول المرافق للخاصية (او نوعها) فإنها تقوم بتوليد خطأ وتتوقف العملية.

لاحظ ايضاً ان XAML متحسسة لحالة الأحرف فيما يتعلق باسماء العناصر والواصفات، بينما لا تكون متحسسة لحالة الأحرف مع القيم ، لإن محولات الأنواع يمكنها تحويل القيمة النصية بغض النظر عن حالة الأحرف فيها.

التعامل مع الخصائص المركبة

هناك بعض الخصائص التي لا يمكن تعيينها من خلال الواصفات ، بسبب ان قيمتها قد تمثل كائن او عدة كائنات يصعب التعبير عنها بنص بسيط.

لهذا وفرت XAML صيغة اخرى لتعيين الخصائص في الكائنات تسمى بـ "صيغة العنصر الخاصية" (Property Element Syntax) ، وفيها نقوم بإضافة عنصر XML يمثل الخاصية ويكون اسمه على شكل <TypeName.Property> وينتهي بـ </TypeName.Property> ، ويتم تحديد القيمة او القيم المطلوبة داخل هذا العنصر.

مثلا لو اردنا إنشاء نفس الزر السابق باستخدام العنصر الخاصية فإننا نكتب:

<Button>
  <Button.Background>
	<SolidColorBrush Color="Blue"/>
  </Button.Background>
  <Button.Foreground>
	<SolidColorBrush Color="Red"/>
  </Button.Foreground>
  <Button.Content>
	This is a button
  </Button.Content>
</Button>

لاحظ انه من خلال "العنصر الخاصية" نستطيع ان نحدد او نخصص نوع الكائن الذي يمثل القيمة واي خصائص اخرى بداخله.

فلو اردنا ان نجعل الزر محتويا على صورة بدل النص فإننا سوف نقوم بإضافة عنصر يمثل الصورة بداخل الخاصية:

<Button>
	<Button.Content>
		<Image Source="help.png"/>
	</Button.Content>
</Button>

و لو اردنا استخدام Brush من نوع LinearGradientBrush لكي نجعل لون الخلفية بلون متدرج فإننا سوف نستخدم :

<Button>
  <Button.Background>
	<LinearGradientBrush>
	</LinearGradientBrush>
  </Button.Background>
</Button>

ومن اجل ان يعمل هذا التدرج بشكل سليم، فلا بد من تحديد الألوان في LinearGradientBrush ، من خلال تعبئة الخاصية GradientStops والتي تمثل كولكشن كائنات من النوع GradientStop، ومثل هذه الخاصية يمكن تعيينها في XAML من خلال "العنصر الخاصية" فقط:

<Button>
	<Button.Background>
		<LinearGradientBrush>
			<LinearGradientBrush.GradientStops>
			</LinearGradientBrush.GradientStops>
		</LinearGradientBrush>
	</Button.Background>
</Button>

يمكننا بعد ذلك إضافة الكائنات GradientStop وتحديد الألوان المطلوبة :

<Button>
	<Button.Background>
		<LinearGradientBrush>
			<LinearGradientBrush.GradientStops>
				<GradientStop Offset="0.00" Color="Red" />
				<GradientStop Offset="0.50" Color="Indigo" />
				<GradientStop Offset="1.00" Color="Violet" />
			</LinearGradientBrush.GradientStops>
		</LinearGradientBrush>
	</Button.Background>
</Button>

يكون الكود المكافئ بهذا الشكل:

LinearGradientBrush brush = new LinearGradientBrush();
GradientStop gradientStop1 = new GradientStop();
gradientStop1.Offset = 0;
gradientStop1.Color = Colors.Red;
brush.GradientStops.Add(gradientStop1);

GradientStop gradientStop2 = new GradientStop();
gradientStop2.Offset = 0.5;
gradientStop2.Color = Colors.Indigo;
brush.GradientStops.Add(gradientStop2);

GradientStop gradientStop3 = new GradientStop();
gradientStop3.Offset = 1;
gradientStop3.Color = Colors.Violet;
brush.GradientStops.Add(gradientStop3);

button.Background = brush;

يمكننا ايضاً مع بعض الخصائص (التي يكون لها set) تحديد نوع الكولكشن المستخدم :

<LinearGradientBrush>
	<LinearGradientBrush.GradientStops>
		<GradientStopCollection>
			<GradientStop Offset="0.00" Color="Red" />
			<GradientStop Offset="0.50" Color="Indigo" />
			<GradientStop Offset="1.00" Color="Violet" />
		</GradientStopCollection>
	</LinearGradientBrush.GradientStops>
</LinearGradientBrush>

خصائص الأحتواء:

تسمح XAML لأي فئة بإن تحدد احدى الخصائص فيها كخاصية احتواء افتراضية، واي عنصر من تلك الفئة يمكن ان يحتوي على عنصر او عدة عناصر بداخله مباشرة بدون الحاجة إلى تحديد عنصر الخاصية.

مثلا خاصية الأحتواء الأفتراضية في الزر هي الخاصية Content لذا يمكننا عمل نفس الزر السابق بدون تحديد هذه الخاصية :

<Button>
	<Image Source="help.png"/>
</Button>

ايضا خاصية الأحتواء الأفتراضية في LinearGradientBrush هي GradientStops فيمكننا إنشاء التدرج السابق بالشكل التالي:

<LinearGradientBrush>
	<GradientStop Offset="0.00" Color="Red" />
	<GradientStop Offset="0.50" Color="Indigo" />
	<GradientStop Offset="1.00" Color="Violet" />
</LinearGradientBrush>

تعددت الطرق والنتيجة واحدة:

مما سبق ، يمكن تعيين اي خاصية باكثر من طريقة ، مثلا من اجل تعيين الخاصية Content في الزر فإننا نستخدم اي طريقة من التالي:

<Button Content="Click Me"/>

<Button>
	<Button.Content>
		Click Me
	</Button.Content>
</Button>

<Button>
	Click Me
</Button>

الخصائص المرفقة (Attached Properties)

بإلاضافة إلى الخصائص الاعتيادية والتي نتعامل معها دائما ، قامت XAML بإضافة مبدأ جديد يسمى بـ "الخصائص المرفقة" ، وهي خصائص يمكن تطبيقها على العديد من العناصر رغم انها معرفة اصلا في فئات مختلفة.

عادة ما تستخدم الخصائص المرفقة من خلال الواصفات حيث يكون اسم الواصفة على الشكل OwnerType.PropertyName وهذه الصيغة تشبه إلى حد كبير الأسم في "صيغة العنصر الخاصية" لكن الفئة المالكة للخاصية هنا (OwnerType) غالبا ما تكون مختلفة عن فئة العنصر الكائن.

تستخدم الخصائص المرفقة في WPF كثيرا مع الواح التخطيط (Layout Panels) مثل Grid و DockPanel.

مثلا من اجل تحديد رقم الصف الذي سوف يوضع فيه العنصر داخل Grid فإننا نستخدم الخاصية المرفقة Grid.Row:

<Button Grid.Row="1" Content="Click Me"/>

لا تقوم الفئة المالكة للخاصية المرفقة بتعريف خاصية مقابلة بداخلها ، انما تقوم بتعريف دالة لتعيين القيمة تكون على شكل SetPropertyName() ودالة اخرى لأحضار القيمة تكون على شكل GetPropertyName().

مثلا الخاصية المرفقة Grid.Row يتم تحقيقها بهذا الشكل:

public class Grid
	{
		public static int GetRow(UIElement element);

		public static void SetRow(UIElement element, int value);
	}

كما يمكننا تعيين اي خاصية مرفقة من خلال الكود على هذا النحو:

Grid.SetRow(btn, 1);

تمديدات الوسوم (Markup Extensions)

من خلال الواصفات او العناصر الخاصية نقوم بتعيين خاصية الكائن إلى قيمة جديدة دائما.

بعض الحالات تتطلب منا تعيين الخاصية إلى قيمة موجودة من قبل ، او تعيينها إلى القيمة الخالية (null)، او ربط الخاصية بخاصية اخرى في كائن آخر ، ومثل هذه العمليات وغيرها يمكن إنجازها من خلال ما يسمى بـ" تمديدات الوسوم" (Markup Extensions) .

جميع التمديدات مشتقة من الفئة MarkupExtension (في المجال System.Windows.Markup)، وغالبا ما يكون اسمها منتهيا باللاحقة Extension التي يمكن اهمالها مع XAML.

غالبا ما تستخدم تمديدات الوسوم (Markup Extensions) مع الواصفات ، حيث يكون تمديد الوسم محاطاً بمربعات متعرجة { }.

المثال التالي على بعض تمديدات الوسوم (Markup Extensions):

<Button Background="{x:Null}" 
		Height="{x:Static SystemParameters.IconHeight}" 
		Content="{Binding Path=Height, RelativeSource={RelativeSource Self}}"/>

x:Null

التعيين إلى القيمة الخالية (null). حيث قمنا في هذا المثال بتعيين الخاصية Background إلى القيمة الخالية.

x:Static

التعيين إلى خاصية ساكنة في فئة في الدوت نت. في المثال قمنا بتعيين ارتفاع الزر إلى الخاصية الساكنة IconHeight في الفئة SystemParameters.

Binding

من اجل عمليات الربط (Data Binding) في WPF .

وكما نرى فإن هناك تمديدات تنتمي إلى XAML (تبدأ بـ x) واخرى تنتمي إلى WPF، كما يمكننا تعريف تمديدات مخصصة من خلال الأشتقاق من الفئة MarkupExtension.

ملاحظة:

إذا اردنا ان نعين الواصفة إلى نص يبدأ بقوس الأفتتاح { ، فإن علينا استخدام حروف الهروب.

مثلا لو اردنا تعيين الخاصية Content في الزر إلى النص "{some text}" فإننا نكتبها بهذه الطريقة :

<Button Content="{}{some text}"/>

ولا نحتاج إلى اي حروف هروب مع العنصر الخاصية:

<Button>
	{some text}
</Button>

الأحداث

يمكننا من خلال الواصفات ايضاً تحديد الإجراء او الدالة المعالجة لحدث في عنصر معين. وتكون الصيغة بهذا الشكل:

<Button ... Click="Button_Click ">

ويجب ان يحتوي الكود(Code-Behind) على الدالة Button_Click يتفق توقيعها مع توقيع الحدث:

private void Button_Click(object sender, RoutedEventArgs e)
		{
			MessageBox.Show(txtMessage.Text);
		}

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

لاحظ اننا نستخدم الواصفات من اجل تعيين الخصائص و الأحداث في الكائن، خلال عملية الأعراب يتم تعيين الأحداث قبل الخصائص في الكائن، باستثناء الخاصية Name التي يتم تعينها اولا(في حال استخدمت فعلاً)، ما يعني ان اي حدث مرتبط بتغيرات خاصية (مثل TextChanged ) سوف يقدح خلال هذه العملية.

استخدام فئات من مجالات اسماء اخرى:

إلى جانب التصريح عن مجال الأسم من خلال URI ، يوجد نوع آخر من التصريح يستخدم من اجل تحديد مجال اسم بعينه في الدوت نت .

وتكون صيغته بهذا الشكل:

xmlns:Prefix="clr-namespace:Namespace;assembly=AssemblyName"

حيث:

- Prefix: تمثل البادئة التي نريد استخدامها عند التعامل مع الكائنات التي تنتمي لهذا المجال.

- Namespace: يمثل مجال الأسم الذي نريد التصريح عنه.

- AssemblyName: اسم التجمع الذي يحتوي على مجال الأسم. يمكننا اهمال هذا الجزء إذا كان المجال ينتمي إلى المشروع الحالي.

عادة ما يتم التصريح عن المجالات في العنصر الجذر في المستند.

مثلا من اجل التصريح عن المجال MyNamespace في المشروع الحالي:

xmlns:local="clr-namespace:MyNamespace"

ومن اجل إنشاء كائن في المجال MyNamespace:

<local:MyObject ...></local:MyObject>

ومن اجل التصريح عن المجال System في الدوت نت:

xmlns:sys="clr-namespace:System;assembly=mscorlib"

ومن اجل إنشاء كائن من النوع DateTime :

<sys:DateTime>10/30/2010 4:30 PM</sys:DateTime>

===========================================

المراجع:

- Pro WPF in C# 2008

- Windows Presentation Foundation Unleashed

[وسط]لا اله الا انت سبحانك انى كنت من الظالمين

[/وسط]

#2

مقال أكثر من رائع

لقد قرأت منه عدة مقتطفات و قد أستفدت حقا

جزاك الله خيرا

أظن أننى سوف أفكر جديا فى ترك الإصدارة الثانية التى أعمل عليها الأن من الدوت نت !

حيث أن أسلوب العمل الذى تقدمت بشرحه مثير للإهتمام حقا

لا إله إلا الله محمد رسول الله

アッラー以外に神はなし。ムハンマドはアッラーの使徒である

#3

أخى حسن أشكرك كثيرا على الموضوع الرائع

من المزايا الرائعة لل WPF أنها تجعلك تستغنى عن اى اداة إضافية قد يستخدمها المبرمج لتحسين الواجهة الرسومية ، على سبيل المثال Iris Skin من شركة Suni Soft و ايضا Skin Crafter الشهيرة .

أة لو تعلم كم المتاعب التى مررنا بها عند استخدامنا لهذة الأدوات ( الموضوع قد يصل فى بعض الأحيان إلى أخطاء فى البرنامج ) RunTime Errors و غير ثمن الأدوات الباهظ لكن مع Microsoft Expression Blend أعتقد إن الموضوع يحتلف كثيرا على الأقل بفصل الكود عن الواجهة .

أكثر ما يعجبنى عند التعامل مع WPF هو إستخدام XAML كلغة تعامل (أرى إنها سهلة جدا ) و اعتقد ان ايضا ان ال WPF سوف يكون لها مستقبل كبير فى الأصدارات القادمة من Visual Studio

أشكرك مرة أخرى على الموضوع الجميل و على طريقة صياغتك الممتعة

تقبل خالص تحياتى و جزيل شكرى و كل عام و حضرتك بخير

#4

جزاكم الله كل خير اخواني الأفاضل، وكل عام وانتم بخير.

[وسط]لا اله الا انت سبحانك انى كنت من الظالمين

[/وسط]

#5

شكرا لك على الموضوع

أخي انا حابب اسئلك كم سؤال بس ببيطلبوا انو يكون في اتصال مباشر اون لاين بيناتنا

ممكن تضع لي ايمليك

او اذا بتحب تضيفني من عندك ads2100@hotmail.com

وأكون لك من الشاكرين

#6

تسلم ايدك اخى حسن

بارك الله فيك

#7

مقال جميل نتمنى الشرح بتفصيل اكثر فى انتظار شرحك

#8

شكرا" على الشرح الرائع ... كيف أجعل ملف قمت بعمله في microsoft expression blend ثم فمت بإضافته لمشروع windows application - كيف اجعل هذا الملف هو الفورمة الرئيسية للبرنامج؟ الملف طبعا" من النوع XAML...

#9

جزاك الله كل خير

الصراحة أنا استخدام XAML وما عرف الكثير عنه

وما شاء الله افدتني أخي الكريم

C4Z00890.gif
#10

شرح على اعلى مستوى , جزاك الله خيرا وبارك الله فيك

#11

شكرا على الشرح الجميل وباريت تستمر باادرج بعض الامثله والاستمرار في ادرج دروس مقالات ااخرى عن هذا اللغه !

#12

بارك الله فيك وجزاك الله خيرا

مواضيع مشابهة