مقدمه
در اين بخش قصد دارم، زبان XAML را که نوعي زبان نشانه گذاري مي باشد را تشريح کنم و نحوه استفاده از آن و جايگاه آن را در تکنولوژي WPF و نيز در ويژوال استوديو را بيان کنم.
همانطور که در بخش قبلي (مقدمه اي بر WPF) اشاره اي مختصر کردم، XAML مخفف عبارت EXtensible Application Markup Language مي باشد. زبان XAML که يک زبان توصيفي مي باشد، بر پايه قواعد XML مي باشد. اين زبان در ايجاد برنامه هاي WPF نقش بسيار موثري را بازي مي کند.
اين زبان که همراه با ويژوال استوديو 2008 درون آن موجود و نصب شده مي باشيد، براي نمونه سازي وتعريف آبجکت هاي WPF به کار مي رود. منظور از آبجکت، در اينجا يک واژه کلي مي باشد. از يک خط ساده گرفته تا توليد و ايجاد کنترل هاي پيچيده، همگي قابل پياده سازي با اين زبان توصيفي مي باشند. در واقع WPF اين زبان را براي ايجاد واسط هاي کاربري برنامه هاي خود به کار مي گيرد.
اگر چه در ابتدا ممکن است اينگونه به نظر آيد که استفاده از XAML براي طراحي پنجره ها و يا صفحات و يا هر آبجکت ديگري درون WPF مشکل تر از نحوه ايجاد فرم هاي ويندوزي در مدل هاي برنامه نويسي پيشين باشد، ولي به واقع اينگونه نيست. با کمي تلاش و استفاده از اين زبان، پس از مدتي متوجه خواهيد شد که توسعه برنامه ها و طراحي پنجره هاي برنامه به همراه محتويات درون آن ها، توسط XAML بسيار سريعتر و روان تر از روش هاي پيشين که معمولا به صورت Drag کردن کنترل ها و اشياء بر روي فرم ها بود، مي باشد. علاوه بر اين پس از مدتي خواهيد ديد که ايجاد آبجکت ها و به ويژه ايجاد انواع اشکال با انواع افکت هاي گوناگون بر روي آن ها، توسط XAML به راحتي صورت مي پذيرد. يکي ديگر از ويژگيهاي اين زبان اين است که در ويژوال استوديو، تقريبا بيش از 99% موارد داراي Intellisence بسيار موثر و کارا مي باشد که عمل کد نويسي در اين زبان را بسيار راحت تر مي کند. در ادامه نگاهي گذرا به روش هاي پيشين طراحي خواهيم انداخت و مقايسه خواهيم کرد که استفاده از XAML در توليد برنامه هاي WPF چه اثراتي دارد.
طراحي واسط هاي گرافيکي کاربر قبل از WPF
طراحي واسط هاي کاربري در مدل هاي برنامه نويسي قبل از WPF (برنامه هاي ويندوزي ) هميشه با بخش کد و منطق برنامه درگير بوده است. در بهترين حالت، در دات نت فريم ورک 2.0، هر فرم که به عنوان بالاترين آبجکت و به عنوان پدر تمامي آبجکت ها در برنامه هاي استفاده مي شد، درااي دو کلاس مجزا بود.(هست) يکي از اين کلاس ها که داراي متدي به نام InitializedComponents بود، (هست). اين متد وظيفه طراحي فرم و آبجکت هاي درون آن را بر عهده داشت. به محض قرار گيري آبجکتي مانند Button بر روي فرم، کدهايي درون متد مذکور به صورت اتوماتيک و توسط خود محيط برنامه نويسي ويژوال استوديو نوشته مي شد. اين کد ها مربوط به نحوه قرار گيري آبجکت مورد نطر بر روي فرم بود.(هست). و کلاس ديگر معمولا براي کد نويسي و ايجاد منطق برنامه و مشخص کردن عملکرد فم مربوطه و آبجکت هاي مربوطه به کار مي رفت.(مي رود). اين مسئله ممکن است هيچ ايرادي در يک نگاه سطحي به همراه نداشته باشد. اما در گروه هاي برنامه نويسي، اين يک معضل مي باشد. به اين دليل که هميشه طراح با کد نويس درگير است. اين مشکل زماني بيشتر خود را نشان مي دهد که طراح برنامه، ( منظور از طراح، گرافيست برنامه مي باشد) از کد نويسي و منطق هاي برنامه نويسي اطلاعات چنداني نداشته باشد.
اين موضوع با ورود ASP.NET 2.0 و به وجود آمدن مبحث Code Behind که منطق برنامه را از طراحي آن جدا مي کرد، تا حدي مرتفع گرديد. البته کماکان براي برنامه هاي ويندوزي هيچ راه حل مناسبي وجود نداشت.
اين مسئله با آمدن تکنولوژي WPF و همراه ان زبان نشانه گذاري XAML به خوبي مرتفع شده و بسياري از مشکلات را کاهش داده است. در اين روش، گرافيست برنامه بدون داشتن دغدغه هايي از منطق و نحوه عملکرد برنامه، اقدام به ايجاد و طراحي پنجره هاي برنامه نمايد.
در واقع نکته کليدي و تفاوت WPF با فرم هاي ويندوزي اين است که WPF طراحي پنجره ها و آبجکت ها را بر خلاف فرم هاي ويندوزي به کد تبديل نمي کند. و در نتيجه طراحي برناکمه از کد نويسي و منطق آن کاملا جدا سازي شده است. اين موضوع هميشه ذهن برنامه نويسان را درگير کرده بود. در واقع برنامه نويسان حرفه اي، همواره در تلاش براي توليد برنامه هايي بودن که منطق برنامه از طراحي آن جدا باشد.
نکته: البته توجه به اين نکته بسيار مهم است که وجود XAML به اين معنا نيست که WPF حتما به اين زبان نياز دارد. اگر چنين تصوري داريد بايد بگم که در اشتباه هستيد. هم اکنون هم مي توان طراحي برنامه را تماما به صورت کد نويسي انجام داد. اما اين مسئله مشکلاتي را که پيش تر به آن ها پرداختم را به وجود مي آورد.
عادت بد:
با وجود نر م افزار هاي گرافيکي که روز به روز بر تعداد آن ها هم افزوده ميشه و با اضافه کردن plug in هايي به اون ها و گرفتن خروجي XAML از آن هاي نبايد موجب اين شود که نحوه کار کردن با XAML را کنار بگذاريم و از برنامه هاي آماده استفاده کنيم.. شديدا و با تاکيد بسيار توصيه مي کنم که زياد وابسته اينگونه نرم افزار ها نشويد. تعدادي از اين نرم افزار ها را در بخش هاي بعدي معرفي خواهم کرد.
کاربرد هاي مختلف XAML
زماني که صحبت از نام XAML به ميان مي آيد، ذهن خيلي از افراد به سمت WPF سوق داده مي شود. اگر چه صحيح است که XAML يک ابزار قدرتمند و کارامد در هنگام کار کردن با برنامه هاي WPF مي باشد، اما اين موضوع صرفا به اين معني نيست که از XAML تنها مي توان در WPF استفاده نمود. در زير ليستي از کاربرد هاي XAML به همراه توضيح مختصري در باره آن آمده است.
XAML در WPF
همانطور که قبلا و از ابتداي موضوعات تا بدين جا چندين بار متذکر شدم، يکي از کاربرد هاي XAML در هنگام برنامه نويسي WPF مي باشد که امکانات بسياري را براي شما فراهم مي کند. هر سند XAML در WPF مي تواند نگهدارنده آبجکت هاي WPF باشد. اين آبجکت هاي مي توانند در بالاترين سطح، پنجره هاي باشند و يا تنها يک آبجکت خط و يا يک مستطيل طراحي شده توسط شما باشد. با ساختار XAML در WPF بيشتر آشنا خواهيد شد.
XAML در WF
همانطور که XAML در WPF مي تواند نگهدارنده آبجکت هاي WPF باشد، XAML در WF نيز مي تواند نگهدارنده آبجکت ها در WF باشد. WF نيز مانند WPF دراي آبجکت هاي بسياري از جمله Activity Class ها و .. باشد.
XAML در SilverLight
نسخه اي ديگر از WPF وحود دارد به نام WPF/E که به نام SilverLight نيز معروف است و نام آن را بار ها شنيده ايد. در واقع توسط WPF/E يا همان SilverLight مي تواند بسياري از کارهايي را که با WPF قادر به انجام آن ها در برنامه هاي ويندوزي هستيد، مانند اشکال دو بعدي، صدا، تصوير، انيميشن و ... را در برنامه هاي تحت وب به کار ببريد.
نکته: XAML کاربرد هاي ديگري در زيمنه هاي مختلف ديگري دارد. به عنوان مثال XPS Documentation ها يکي ديگر از زمينه هايي است که XAML در آن استفاده مي شود. XPS مخفف Xml Paper Specification مي باشد. براي آشنايي با اين نوع document ها، خواندن
اين مطلب خالي از لطف نيست.
کامپايل XAML به فايل هاي BAML تزريق شونده به اسمبلي ها
زماني که طراحي هاي برنامه انجام گرفت، در زمان کامپايل برنامه، ويژوال استوديو تگ هاي XAML را به فرمتي جديد به نام BAML که مخفف Binary Application Markup Language مي باشد، ترجمه مي کند. فايل هاي BAML درواقع فرمت دودويي شده فايل هاي XAML مي باشند. علاوه بر اين فايل هاي BAML چون به صورت مجموعه اي از نشانه هاي مي باشند، هم از لحاظ حجم کمتر از فايل هاي XAML مي باشند و هم از لحاظ سرعت Load شدن، سريعتر از فايل هاي XAML مي باشند. درواقع تعداد خطوط زيادي در فايل هاي XAML به چندين توکن در فايل هاي BAML تبديل مي شوند. البته تصميم گيري در مورد اينکه چه تعداد خطوط از فايل هاي BAML به چه تعدادي توکن از فايل هاي BAML و به چه نوع توکن هايي تبديل مي شوند، بر عهده کامپايلر است.
پس از ايجاد فايل هاي BAML آن ها به اسمبلي هاي برنامه شما ( فايل exe يا dll) ملحق مي شوند. ( اين عمل را اصطلاحا Embed کردن BAML به اسمبلي مي گويند.
نکته مهم
از بزرگترين محاسن فايل هاي BAML اين است که مي تواند هر نوع فايلي را درون خودش نگه داري کند. به عنوان مثال فرض کنيد که برنامه شما از فونتي به نام X استفاده مي کند. در مدل هاي برنامه نويسي پيشين، چنانچه فونت X بر روي سيستم مقصد وجود نداشت، برنامه در قسمتي که از آن فونت استفاده مي کرد، دچار اخلال مي شد(هر نوع اخلالي اعم از جايگزين شدن با يک فونت ديگر و...) البته راه هايي براي مقابله با اين مشکل وجود داشت. به عنوان مثال مي توانستيد، در هنگام ايجاد فايل هاي Setup فونت هاي مشخصي را به آن اضافه کنيد تا در هنگام نصب برنامه در سيستم مقصد، فونت هاي مربوطه به پوشه فونت در سيستم مقصد کپي شوند.
اما به روشي که به زودي خواهم گفت، مي توانيد فونت ها و يا فايل هاي ديگري را به فايل exe خود تزريق کنيد. در نتيجه ديگر نياز نيست که نگران وجود فونت خاصي بر روي سيستم مقصد باشيد و مطمئن خواهيد بود که هر جا که فايل exe شما وجود داشته باشد، آن فونت نيز وجود خواهد داشت. البته اين تنها نقطه قوت BAML ها نيست. دستورات بسيار کوتاهي که قابل استفاده در XAML هستند براي دسترسي ساده و آسان به فايل هاي Resource شما، از ديگر مزاياي آن ها مي باشد ک هدر اين مورد در بخش هاي آتي بيشتر خواهيد دانست.
ساختار فايل هاي XAML
همانطور که قبلا نيز بدان اشاره شد، زبان XAML يک زبان XML base مي باشد. پس طبيعتا شباهت بسيار زياد و نزديکي به قايل هاي XML دارد که تاکنون زياد با آن ها سرو کار داشته ايد. اما توجه به چهار نکته زير که به نحوي قوانين فايل هاي XAML را بيان مي کنند، مي تواند در درک ساختار XAML ههآ بسيار مفيد
باشد.
همواره چهار نکته زير را به خاط ر داشته باشيد
الف:
هر تگ آغاز شونده XAML نشان دهنده به نمونه اي از کلاس خاص در WPF نگاشت خواهد شد به عنوان مثال تگ <TextBlock> نشان دهنده آبجکتي از کلاس TextBlock مي باشد. منظور از کلاس، هر کلاسي مي تواند باشد. بهعنوان مثال فرض کنيد، کلاسي با نام MyCustomTextBox ايجاد کرده ايد. حال مي توانيد با دستوري مشابه <cl:MyCustomTextBox> نمونه اي از آبجکت MyCustomTextBox را مشخص نماييد.
نکته:
کلمه cl به کار رفته در دستور فوق، جزء کلمات کليدي نيست. در واقع نبايد اين تصور را بکنيد، براي ايجاد نگاشت به کلاس هاي ساخته شده توسط خودمان، حتما کلمه cl را قبل از به کار ببريم. در واقع در اين مثال من فرض کرده ام، که cl ، اشاره به فضاي نامي دارد که کلاس MyCustomTextBox درون آن قرار گرفته است. نحوه مشخص کردن و اضافه کردن اسمبلي ها را در اسناد XAML را به زودي فرا خواهيد گرفت.
ب:
به دو صورت مي توانيد پايان تگ هاي XAML را مشخص نماييد.
حالت اول: در اين حالت از علامت (/>) در پايان تگ استفاده مي کنيد. که بيانگر پايان تگ مي باشد.
قاعده نحوي:
<[Object Name] [ Object Attributes ] />
نمونه:
<TextBlock Text="this is a sample textBlock"/>
حالت دوم: از تگ (</[ObjectName]>) در پايان کد استفاده نماييد.
قاعده نحوي:
<[Object Name] [ Object Attributes ] ></[ObjectName]>
نمونه:
<TextBlock Text="this is a sample textBlock"></TextBlock>
ج:
پس از ام آبجکت در تگ شروع کد، مي توانيد صفات آن آبجکت را مشخص نماييد. به عنوان مثال تکه کد زير، يک Button را مشخص مي کند که خواصي براي آن تنظيم شده است. همچنين رويداد کليک براي آن تعريف شده است.
<Button Name="btnSum" Content="Calculate" Click="btnSum_Click"></Button>
د:
مي توانيد خواص هر آبجکت را بين تگ هاي آغازين و پاياني آبجکت مورد نظر قرار دهيد. به عنوان مثال کد فوق، با کد زير برابر است
<Button Click="btnSum_Click">
<Button.Name>btnSum</Button.Name>
<Button.Content>Calculate</Button.Content>
</Button>
عادت خوب:
سعي کنيد، عادت به استفاده از روش دوم ( روش د ) در تنظيم خواص آبجکت ها کنيد. البته اين موضوع بيشتر براي زماني استفاده مي شود که بخواهيد از خواص پيچيده و ترکيبي براي يک آبجکت استفاده کنيد.( اين موضوع را کمي جلوتر خواهيد ديد). ولي به عنوان نمونه براي مثال فوق، بهتر است که از روش ( ج ) به جاي روش ( د) استفاده گردد.
شکل ساده يک سند XAML
در قطعه کد زير، ساده ترين شکل يک فايل XAML را مي بينيد. اين کدها هنگام ايجاد Window هاي جديد به برنامه، براي هر Window توسط خود ويوژوال استوديو ايجاد مي گردد.
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window1" Height="300" Width="300">
<Grid>
</Grid>
</Window>
حال در ادامه اجزاي قطعه کد فوق را با هم خواهيم ديد:
اگر خوب دقت کنيد، کد فوق داراي دو تگ کلي مي باشد. يکي تگ Window و ديگري تگ Grid مي باشد.
تگ Window بيانگر اين است، که اين فايل اشاره به يک آبجکت Window دارد. همانطور که قبلا گفتم Window ها در WPF به مانند Form ها در WinApp مي باشند.
تگ Grid اشاره به آبجکتي به نام Grid دارد که يکي از پر کاربردترين آبجکت هاي WPF مي باشد که جزء کنترل هاي Container است. اين کنترل به همراه کنترل هاي ديگر که همه از کلاسي به نام panel ارث بري مي کنند، وظيفه طرح بندي (Layout) پنجره هاي شما را دارند در مورد اين کنترل به همراه کنترل هاي مربوطه، در بخش Layout مفصل صحبت خواهم کرد.
در خط اول قطعه کد فوق، دستور زير را مشاهده مي کنيد:
x:Class="WpfApplication1.Window1
اين دستور، بيانگر اين است که فايل XAML جاري، مربوط به کلاس Window1 که در فضاي نام WpfAplication1 قرار گرفته است مي باشد. به عنوان مثال چناچه يک Button به فايل XAML فوق اضافه کنيد، و براي آن رويدادي (مثلا Click) تعريف کنيد، کد هاي اين رويداد درون کلاس Window1 در درون فضاي نام WpfApplication1 خواهد بود. اين نوع تعريف کلاس و ربط دادن آن به کد هاي مروبوط به طراحي فرم، براي برنامه نويسان ASP.NET 2.0 آشنا مي باشند. ( اصطلاحا به آن Code-Behind Class گفته مي شود) در آن جا هم از تکنيکي مشابه اين استفاده مي گردد.
اين موضوع باعث جدايي واسط کاربري ما از منطق برنامه مي شود. علاوه بر اين شما مي توانيد، فايل هاي XAML را به صورت پويا و در هنگام زمان اجراي برنامه، فراخواني کرده و توسط ان ها، واسط کاربري پنجره مربوطه را ايجاد نماييد.
حال به دوخط کد زير که در قطعه کد فوق قرار گرفته اند توجه کنيد:
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
اين دوخط، دو فضاي نام کلي را در برنامه هاي WPF مشص مي کند. در واقع هر سند XAML مربوط به WPF شامل اين دو فضاي نام خواهد بود. توضيحات بيشتر در مورد فضاي نام ها در XAML را در بخش بعدي توضيح خواهد داد. همچنين در آن بخش خواهيد ديد که دو فضاي نام فوق شامل چه عناصري در WPF مي باشند.
در نهايت، سه خاصيت براي Window تعريف شده است. خاصيت اول مربوط Tilte پنجره مي باشد. اين خاصيت مانند خاصيت Text در فرم هاي ويندوزي مي باشد. در واقع متني که به عنوان مقدار در اين خاصيت قرار بگيرد، به نوار عنوان پنجره و همچنين در زماني که پنجره در حالت minimize قرار دارد، در Taskbar ويندوز، نشان داده خواهد شد.
دو خاصيت بعدي هم به ترتيب ارتفاع و عرض Window را مشخص مي کند.
فضاي نام ها در XAML
در بخش قبل با دو دستور زير آشنا شديد.
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
دانستيد که آن ها فضاي نام هاي اساسي WPF مي باشند و بنابراين، هر سند XAML مربوط به WPF بايستي اين دو فضاي نام را در خود تعريف کند. حال ببينيم تعريف يک فضاي نام در XAML به چه نحوي مي باشد.
اعلان فضاي نام در XAML
با به کار بردن کلمه xmlns مي توانيد فضاي نام هاي مورد نظر را در اسناد XAML خود، تعريف کنيد. قاعده نحوي تعريف فضاي نام ها به صورت زير مي باشد:
xmlns="clr-namespace:[NameSpace Name];assembly=[Assembly Name]"
در تعريف فوق، به جاي [NameSpace Name] بايستي نام فضاي نام مروبطه را قرار دهيد. و به جاي [Assembly Name] بايستي نام فايل اسمبلي را که آن فضاي نام در آن قرار گرفته است را قرار دهيد. براي درک بهتر موضوع به مثال زير توجه کنيد :
فرض کنيد که يک کلاس اختصاصي با عنوان AdvanceMathClass ايجاد کرده ايد که اين کلاس در فضاي نام MathClasses و در اسمبليMyCustomClasses قرار دارند. حال براي دسترسي به کلاس AdvanceMathClass بايستي فضاي نام آن را و نيز اسمبلي که آن کلاس در آن قرار گرفته است را مشخص نماييد.
با توجه به توضيحات پيشين، بايستي دستور زير را در ابتداي فايل XAML خود اضافه نماييد:
xmlns="clr-namespace:MathClasses;assembly=MyCustomClasses"
حال مي توانيد به راحتي از کلاس AdvanceMathClass در سند XAML خود استفاده کنيد.
نکته: اگر به خاطر داشته باشيد، مي توانستيد براي فضاي نام هاي موجود، يک اسم مستعار معرفي کنيد و از از آن اسم در برنامه خود استفاده نماييد. به عنوان مثال مي توانيد کدي به صورت زير داشته باشيد:
using sys=System;
توسط اين کد، شما نام مستعار sys را براي System انتخاب کرده ايد. حال به راحتي مي توانيد از کلمه sys به جاي کلمه Systsem در برنامه خود استفاده کنيد و به فضاي نام ها و کلاس هاي داخلي آن دسترسي داشته باشيد.
در فايل هاي XAML نيز مي توانيد، عملي مشابه به اين را انجام دهيد. به قطعه کد زير توجه کنيد:
xmlns:cc="clr-namespace:MathClasses"
همانطور که مشاهده مي کنيد، از کلمه cc به عنوان نام مستعار براي فضاي نام مذکور، استفاده شده است. حال مي توانيد توسط اين کلمه به کلاس هاي درون فضاي نام خود دسترسي داشته باشيد.
فضاي نام هاي اساسي
همانطور که در بخش قبل نيز ياد آور شدم، دو فضاي نامي که به طور پيش فرض در اسناد XAML در برنامه هاي WPF وجد دارند، عبارتند از
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
که در زير به توضيح هر يک خواهم پرداخت.
فضاي نام xmlns=http://schemas.microsoft.com/winfx/2006/xaml/presentation :
اين فضاي نام، در برگيرنده تمامي کلاس هاي WPF و کنترل هاي و ... که جهت ايجاد واسط هاي کاربري، به کار گرفته مي شوند، مي باشد.
فضاي نام xmlns:x=http://schemas.microsoft.com/winfx/2006/xaml :
اين فضاي نام در واقع شامل انواع کاربردهاي XAML مي باشد که به شما اجازه نظارت بر توليد و شبيه سازي اسناد XAML را مي دهد. همانطور که مشاهده مي کنيد، اين فضاي نام داراي پيشوند x مي باشد. اين بدان معني است که در هر جايي از سند XAML که بخواهيد از عناصر درون اين فضاي نام استفاده نماييد، بايستي کدي مشابه کد زير بنويسيد:
<x:[ElementName]>
عناصري که از اين فضاي نام قابل دسترسي خواهند بود، بسته به عنصري که از اين فضاي نام استفاده مي کند، متفاوت مي باشد. به عنوان مثال يکي از کاربرد هاي آن قرار دادن شناسه هايي براي کنترل ها مي باشد که در localizable کردن، برنامه ها، نقش اساسي را بازي خواهند کرد.
خواص و رويداد ها در XAML
اگر به خاطر داشته باشيد، در زماني که ساختار ساده يک سند XAML را توضيح مي دادم، اشاره اي به سه خاصيت Title، Width و Height از کلاس Window کردم و اشاره شد که اين مقادير، خواصي را براي پنجره شما مشخص مي کنند که به ترتيب عبارت بودند از عنوان فرم، عرض و ارتفاع فرم.
به طور کلي در اسناد XAML ، به دو صورت مي توانيد خواص يک عنصرا را مشخص کنيد:
روش اول:
اضافه کردن خواص عناصر در تگ آغازين کنترل مربوطه مي باشد. معمولا زماني از اين روش استفاده مي کنيم که بتوان مقادير خو.اص را به راحتي تنظيم کرد. به عنوان مثال به کد زير توجه کنيد:
<TextBox Name="txtNum1" HorizontalAlignment="Center" VerticalAlignment= "Center" Background="Green"
Foreground="White">this is sample TextBox</TextBox>
کد فوق، يک نمونه از آبجکت TextBox تعريف مي کند و تعداي خواص آن را از جمله رنگي به عنوان پس زمينه و رنگ پيش زمينه و .. را مشخص مي کند.( نگران کد هاي نوشته شده نباشيد، به زودي معناي تمامي آن ها را متوجه خواهيد شد.)
پنجره اي که فقط شامل کنترل فوق باشد، ظاهري شبيه با ظاهر شکل زير خواهد داشت.
روش دوم:
اضافه کردن خواص کنترل به صورت تگ هاي داخلي، و بين تگ آغازين و پاياني کنترل مورد نظر مي باشد. به عنوام مثال مي توان قطعه کد فوق را به صورت زير نوشت:
<TextBox>
<TextBox.Name>txtNum1</TextBox.Name>
<TextBox.HorizontalAlignment>Center</TextBox.HorizontalAlignmen
<TextBox.VerticalAlignment>Center</TextBox.VerticalAlignment>
<TextBox.Background>Green</TextBox.Background>
<TextBox.Foreground>White</TextBox.Foreground>
<TextBox.Text>this is sample TextBox
</TextBox.Text>
</TextBox>
اجراي کد فوق، با کد قبل از آن يکسان مي باشد. حال ممکن است که اين سوال برايتان پيش آيد که حالت دوم نياز به کدنويسي بيشتري دارد. پس چه نياز است که کد اول را به اين شکل بنويسيم؟
در جواب اين سوال بايد بگويم که، بسياري از مواقع، تنظيم مقادير پيچيده و پيشترفته براي يک خاصيت، در تگ آغازين سخت و گاها غير ممکن است. به عنوان مثال فرض کنيد که بخواهيد ظاهر TextBox فوق را با تغيير خاصيت BackGround و ForeGround آن کمي تغيير بدهيد. به قطعه کد زير دقت کنيد:
<TextBox ... >
...
<TextBox.Background>
<RadialGradientBrush >
<RadialGradientBrush.GradientStops>
<GradientStop Color="#b1a4fb" Offset="0"/>
<GradientStop Color="Lime" Offset=".5"/>
<GradientStop Color="#a30c85" Offset="1"/>
</RadialGradientBrush.GradientStops>
</RadialGradientBrush>
</TextBox.Background>
...
</TextBox>
در اين کد، خاصيت BackGround تغيير پيدا کرده، و نيز افکتي به آن اضافه شده است. همانطور که مشاده مي کنيد، خاصيت BackGround در اين کد، مانند کد قبل تنها شامل يک رنگ نمي باشد، بلکه يک شي گراديان مي باشد که خود نيز شامل خواص بسيار زيادي مي باشد. پس در اين حالت نمي توان اين خاصيت را در تگ آغازين قرار داد.
(در بخش هاي آتي با کد هاي فوق و نحوه عملکرد آن ها بيشتر آشنا خواهيدشد)
شکل حاصل از اجراي اين کد، مشابه زير خواهد بود.
خواص پيوست شده (Attached Properties)
هر کنترلي علاوه بر خواصي که خودش دارا مي باشد، بر اساس نحوه قرار گيري آن بر روي کنترل نگهدارنده خودش (کنترلي که اين کنترل را در بر گرفته است که اصلاحا به آن کنترل Container گفته مي شود.) خواص جديدي به آن اضافه مي گردد که به اين خواص، خواص پيوست شده مي گويند. به اين دليل اين نام براي آن انتخاب شده است که اين خواص در حالت عادي براي کنترل مجود نيستند و بسته به کنترل نگهدارنده آن، اين خواص اضافه مي شوند.
به عنوان مثال، اگر TextBox فوق که کد ان را با هم ديديم، بر روي کنترل Grid که يکي از کنترل هاي Container (و در واقع مهمترين و پر کاربرد ترين) مي باشد، خواصي جهت تنظيم TextBox بر روي Grid به کنترل TextBox اضافه مي گردد. نحوه استفاده از اين خواص به صورت زير مي باشد:
DefiningName.PropertyName ="Value";
به عنوان مثال با اضافه کردن کد زير به کد هاي TextBox قبل، TextBox در سطر و
ستون دوم کنترل گريد، قرار خواهد گرفت.
<TextBox ... Grid.Row="1" Grid.Column="1">
...
...
</TextBox>
رويداد ها در XAML
خوشبختانه، XAML تمهيدات خوبي براي تعريف و استفاده از رويداد هاي مختلف کنترل ها فراهم کرده است. نحوه تعريف يک رويداد در اسناد XAML به صورت زير مي باشد:
EeventName="MethodName"
به عنوان مثال در قطعه کد زير رويداد کليک براي يک دکمه تعريف شده است:
<Button Name="testButton" Content="Click To Perform" Click="testButton_Click"></Button>
همانطور که قبلا نيز اشاره شد، يکي از بزرگترين قابليت هاي XAML، هوشمند بودن آن مي باشد. به عنوان مثال در هنگام تعريف رويداد، XAML به صورت اتوماتيک، ليست تمامي رويداد هاي تعريف شده براي کنترل هاي قبلي را که قابل بايند شدن، براي کنترل جديد، باشند را به صورت ليست شده در اختيار شما قرار مي دهد. در نتيجه به راحتي مي توانيد، چندين کنترل را به يک رويداد، بايند کنيد.
علاوه بر ليست رويداد هاي از قبل تعريف شده، گزينه ديگري نيز با عنوان <New Event Handler> موجود است، که با انتخاب آن مي توانيد، يک رويداد جديد براي کنترل مورد نظر ايجاد کنيد.
براي درک بهتر اين موضوع به شکل زير دقت کنيد:
همانطور که مشاهده مي کنيد، ليست کشويي در هنگام تعريف رويداد، براي دکمه قبل باز شده است. اما به دليل اينکه قبلا هيچ رويدادي تعريف نشده است، که قابل بايند شدن به کنترل Button باشد، تنها گزينه موجود، تعريف يک رويداد جديد مي باشد که با انتخاب گزينه <New Event handler> امکان پذير مي باشد. به محض فشردن کليد Enter بر روي اين گزينه، يک رويداد در کلاس مربوطه ساخته مي شود.
حال اگر بخواهيد، براي يک Button ، يک رويداد کليک تعريف کنيد، با ليستي که در شکل زير نشان داده شده است، مواجه خواهيد شد.
همانطور که مي بينيد، به ليست قبلي يک گزينه ديگر اضافه شده است، که در واقع رويداد تعزيف شده براي button فبل مي باشد. در اين حالت، شما دو انتخاب مي توانيد انجام دهيد:
انتخاب اول:
گزينه اول، يعني <New Event handler> را انتخاب کنيد، که در اين صورت، رويداد جديدي، صرف نظر از کليه رويداد هاي قبلي براي دکمه دوم ايجاد مي شود.
انتخاب دوم:
با انتخاب گزينه دوم، يعني textButton_Click ، دکمه دوم را نيز به رويداد کليک دکمه اول بايند کنيد. که در اين صورت رويداد جديدي براي دکمه دوم ايجاد نخواهد شد.
نکته:
براي رفتن به رويداد تعريف شده موجود، دو راه وجود دارد. يا اينکه به کلاس مربوطه که رويداد، در آن تعريف شده است برويد، و رويداد مورد نظر را جهت کد نويسي پيدا کنيد. راه دوم، راست کليک کردن بر روي نام متد مشخص شده براي رويداد، و انتخاب گزينه Navigate To Event handler مي باشد. اين موضوع در شکل زير نمايش داده شده است.
چنانچه مي خواهيد نمونه کد هايي را که از قسمت هاي بعدي ارائه ميشوند را بر روي کامپيوتر خود اجرا کنيد و نتيجه را مشاهده کنيد، ويژوال استوديو 2008 را چنانچه هنوز بر روي PC خودتان نصب نکرده ايد، نصب کنيد.
-----------------