الغرض من هذه المقالة هو إنشاء بقائمة تبدو سهلة وسهلة الاستخدام لموقع ASP.NET الممكّن. من أجل تحقيق ذلك ، سنستخدم الوظيفة القياسية للتحكم في الويب ASP.NET وتحسين المظهر بحت باستخدام أوراق الأنماط المتتالية (CSS).
بالنسبة لأولئك منكم على دراية بـ CSS ، فإن عنوان هذه المقالة سيقرن بالتأكيد جرسًا. يتم التخلص من CSS المستخدمة لتعزيز مظهر ومظهر التحكم في قائمة ASP.NET في مقالة معروفة على نطاق واسع في قائمة ، بعنوان "الأبواب المنزلق من CSS".
يتم شرح CSS المستخدمة لتحسين مظهر ومظهر القائمة بدقة في المقالة الموجودة في القائمة. الائتمان عندما يكون الائتمان مستحقًا. شكرا دوغلاس بومان على تزويدنا مع CSS. تأكد من قراءة مقالته أولاً إذا لم تكن على دراية به.
ينصب تركيز هذه المقالة على كيفية محاكاة مثل هذه القائمة في بيئة ASP.NET. لنبدأ ...
دعنا نطلق النار على Visual Studio 2008 وننشئ مشروعًا جديدًا باستخدام قالب مشروع تطبيق ASP.NET على الويب. سيقوم هذا القالب تلقائيًا بإضافة نموذج ويب افتراضي اسمه "default.aspx". افتحه في المحرر وأضف التحكم في القائمة من صندوق الأدوات الذي يمكنك العثور عليه ضمن علامة التبويب التنقل. إذا قمت بتشغيل موقع الويب الآن ، فسوف ينتهي بك الأمر إلى التحديق في صفحة فارغة. لكي تعرض القائمة أي شيء ، يجب أن يكون أولاً ملزمًا ببعض البيانات.
أسهل طريقة لتحديد البيانات لعنصر التحكم في القائمة لاستخدام وتمكين الزائرين من التنقل عبر موقع الويب هي ربطها بخريطة موقع. أضف عنصرًا جديدًا من خريطة الموقع إلى المشروع باستخدام الاسم المقترح لـ "Web.Sitemap". خريطة الموقع عبارة عن ملف XML ينظم صفحات الموقع بطريقة هرمية. ميزة إضافية تتمثل في أنه يتم الرجوع إليه تلقائيًا بواسطة التحكم في SitemapDataSource.
بعد ذلك ، أضف بعض الصفحات إلى sitemap كما هو معروض في القائمة أدناه.
قائمة 1 - web.sitemap
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< siteMap xmlns = " http://schemas.microsoft.com/AspNet/SiteMap-File-1.0 " >
< siteMapNode url = " " title = " " description = " " >
< siteMapNode url = " Default.aspx " title = " Home " description = " Take me back to the dasboard " />
< siteMapNode url = " Products.aspx " title = " Products " description = " Browse our catalog " />
< siteMapNode url = " Download.aspx " title = " Download " description = " Download neat stuff " />
< siteMapNode url = " Forum.aspx " title = " Forum " description = " Ask questions on our forum " />
< siteMapNode url = " Contact.aspx " title = " Contact " description = " Contact us " />
</ siteMapNode >
</ siteMap >أضف الآن عنصر تحكم SiteMapDataSource إلى الصفحة وقم بتعيين خاصية DataSourceId لعنصر التحكم في القائمة إلى معرف مصدر البيانات. قم أيضًا بتعيين خاصية الاتجاه لعنصر التحكم في القائمة إلى الأفقي كما تتخلف عن العمودي. أخيرًا وليس آخرًا ، قم بتعيين خاصية showStartingNode لـ SitemapDataSource على False. إذا لم تقم بذلك ، فسيتم عرض عقدة الجذر فقط ولا نريد تضمين هذه العقدة الأساسية في القائمة. يجب أن يشبه الرمز الخاص بك الآن الرمز المعروض في القائمة 2.
قائمة 2 - default.aspx
< asp:Menu
ID =" Menu1 "
runat =" server "
DataSourceID =" SitemapDataSource1 "
Orientation =" Horizontal "
> </ asp:Menu >
< asp:SiteMapDataSource
ID =" SiteMapDataSource1 "
runat =" server "
ShowStartingNode =" False "
/>إذا قمت بعرض الصفحة في متصفح الآن ، فيجب أن ترى قائمة وظيفية ومملة.
الشكل 1 - القائمة الأفقية العادية

قبل أن نتمكن من البدء في تطبيق CSS على القائمة ، هناك مشكلة أخرى يجب معالجتها أولاً. إذا ألقيت نظرة على رمز HTML الناتج الذي يتم إنشاؤه عند طلب صفحة Default.aspx ، فسوف تلاحظ أن التحكم في القائمة لا يولد رمز HTML الأكثر مرونة. بشكل افتراضي ، يلف كل عنصر قائمة في جدول. هذا لا يقرض نفسه لتطبيق CSS بسهولة. سيكون من الأفضل إذا قام التحكم في القائمة بإنشاء قائمة غير مرجحة تحتوي على جميع عناصر القائمة.
لحسن الحظ ، يمكن ضبط HTML المتولد باستخدام محولات التحكم. تتيح لك محولات التحكم تقديم HTML الذي تفضله. لحسن الحظ ، تتوفر محولات التحكم هذه بسهولة على CodePlex. توفر مجموعة محولات CSS Friendly Controlly Adapters محولات تحكم تم إنشاؤها مسبقًا ، بما في ذلك واحدة للتحكم في قائمة ASP.NET.
لاستخدام محولات التحكم الصديقة لـ CSS ، اتبع هذه الخطوات:
من الضروري استخدام الكود المصدري وتجميع مجموعة cssfriendly.dll لأنفسنا لأننا بحاجة إلى تعديل بعض CSS المستخدمة من قبل المحولات في وقت لاحق في هذه المقالة.
عند إضافة مشروع CSSFriendly إلى الحل الخاص بك ، سوف يظهر معالج Visual Studio Conversion. ما عليك سوى تنفيذ التحويل ، يجب أن يسير كل شيء بسلاسة. عندما يكمل التحويل ، فإن كل ما تبقى هو إضافة إشارة إلى مشروع CSSFriendly من مشروع موقع ASP.NET.
ما عليك سوى تشغيل الموقع وإلقاء نظرة على رمز HTML الذي تم إنشاؤه الآن.
قائمة 3 - رمز HTML الصديق CSS
< div class =" AspNet-Menu-Horizontal " id =" Menu1 " >
< ul class =" AspNet-Menu " >
< li class =" AspNet-Menu-Leaf AspNet-Menu-Selected " >
< a
href =" /Default.aspx "
class =" AspNet-Menu-Link AspNet-Menu-Selected "
title =" Take me back to the dasboard "
> Home </ a
>
</ li >
< li class =" AspNet-Menu-Leaf " >
< a
href =" /Products.aspx "
class =" AspNet-Menu-Link "
title =" Browse our catalog "
> Products </ a
>
</ li >
< li class =" AspNet-Menu-Leaf " >
< a
href =" /Download.aspx "
class =" AspNet-Menu-Link "
title =" Download neat stuff "
> Download </ a
>
</ li >
< li class =" AspNet-Menu-Leaf " >
< a
href =" /Forum.aspx "
class =" AspNet-Menu-Link "
title =" Ask questions on our forum "
> Forum </ a
>
</ li >
< li class =" AspNet-Menu-Leaf " >
< a href =" /Contact.aspx " class =" AspNet-Menu-Link " title =" Contact us "
> Contact </ a
>
</ li >
</ ul >
</ div >الأشياء تبحث الآن.
الملاحظة : يتيح لك ملف CSSfriendlyAdapters.Browser تحديد محولات التحكم الصديقة لـ CSS. أقوم بإجراء تعليق على جميع المحولات باستثناء تلك التي أريد استخدامها. وبهذه الطريقة ، لا يتم "تكييف" عناصر تحكم أخرى وسيواصلون توليد HTML الافتراضي.
كما ترون من الكود المعروض في القائمة أعلاه محول للتحكم في القائمة ، يقوم تلقائيًا بحقن فئات CSS اللازمة لعلامات <ul> و <li> و <a> . هذا يوفر لنا مشكلة من الاضطرار إلى تحديد هذه.
من الشائع أيضًا أن تحتوي صفحة واحدة على أكثر من عنصر تحكم محول واحد مثل القائمة. إذا كنت تريد مظهرًا ومظهرًا متميزًا لكل عنصر تحكم ، فقم بتعيين CSSseSeSeSelectorClass للتحكم المكيف. على سبيل المثال ، يمكنك تعيين قيمة خاصية CSSseSeSeSelectorClass على النحو التالي:
قائمة 4 - خاصية CSSseSelectorClass
< asp:Menu
ID =" Menu1 "
runat =" server "
DataSourceID =" SitemapDataSource1 "
Orientation =" Horizontal "
CssSelectorClass =" PrettyMenu "
> </ asp:Menu > والنتيجة هي أن رمز HTML الذي تم إنشاؤه بواسطة عنصر التحكم المكيف سيتم احتواءه داخل طبقة جديدة ( <div> ).
قائمة 5 - لف رمز HTML الذي تم إنشاؤه
< div class =" PrettyMenu " id =" Menu1 " >
<!-- Other HTML code -->
</ div >لاحظ أن هذه الخاصية خاصة بالمحولات الصديقة لـ CSS. إنها سمة مخصصة (تمدد) يمكنك تعيينها لعناصر التحكم التي تدعمها هذه المكتبة. تحتاج إلى مزيد من المعلومات حول الطريقة التي يعمل بها المحولات الودية ، ثم يرجى الرجوع إلى الروابط التالية:
مع إنشاء CSSSeSeSelectorClass طبقة منفصلة ( <div> ) حول القائمة وفئات CSS التي تم حقنها تلقائيًا في مكاننا ، نحن على استعداد أخيرًا لبدء تصميم القائمة.
CSS المستخدمة هو simular لتلك الموجودة في مقالة قائمة A. كما ذكرنا من قبل ، فإن تركيز هذه المقالة ليس على هيكل CSS ، بل على كيفية تطبيقه على التحكم في قائمة ASP.NET من أجل الحصول على قائمة جدولة رائعة. يمكن رؤية النتيجة النهائية في الشكل 2.
الشكل 2 - النتيجة النهائية

في صفحة التنزيل ، يمكنك العثور على الكود المصدري لهذه المقالة. أنه يحتوي على ورقة الأنماط والصور اللازمة. ما عليك سوى إجراء الخطوات التالية لإعادة إنشاء النتيجة النهائية:
<Pages> على الافتراضي. (انظر القائمة 6)قائمة 6 - Web.Config مقتطف
< system .web>
<!-- ... -->
< pages theme = " Default " >
<!-- ... -->
</ pages >
<!-- ... -->
</ system .web>إن CSS المستخدمة في حولي محسوبة في المقالة الموجودة في القائمة ، ولكن هناك بعض التغييرات. ترتبط التغييرات بشكل رئيسي ببنية CSS التي تطبقها محولات CSS الصديقة.
من أجل تطبيق CSS ، يجب استخدام الهيكل الصحيح. عند تصميم عنصر تحكم يتم تعديل HTML بواسطة محول ودود أجد أنه من المفيد استخدام الرسوم البيانية المذكورة في الورقة البيضاء. توضح لك هذه المخططات بوضوح كيف يتم تنظيم CSS.
يمكنك العثور على الرسم البياني للتحكم في القائمة هنا.
أحد الأسئلة التي جئت فيها مرارًا وتكرارًا في الكثير من المنتديات هو كيفية تنفيذ قائمة فرعية أفقية تتغير عندما يحدد المستخدم علامة تبويب مختلفة من قائمة المستوى الأعلى. لإنشاء هذا ، نحتاج أولاً إلى ضبط خريطة موقعنا.
يوضح القائمة 7 خريطة الموقع المعدلة.
قائمة 7 - web.sitemap مع "عناصر القائمة الفرعية"
<? xml version = " 1.0 " encoding = " utf-8 " ?>
< siteMap xmlns = " http://schemas.microsoft.com/AspNet/SiteMap-File-1.0 " >
< siteMapNode url = " " title = " " description = " " >
< siteMapNode url = " Default.aspx " title = " Home " description = " Take me back to the dasboard " >
< siteMapNode url = " About.aspx " title = " About us " description = " " />
< siteMapNode url = " Foo.aspx " title = " Foo " description = " " />
< siteMapNode url = " Bar.aspx " title = " Bar " description = " " />
</ siteMapNode >
<!-- ... -->
</ siteMap >من أجل الإيجاز ، يعرض قائمة 7 فقط عناصر القائمة الفرعية (العقد) للعقدة الرئيسية. تحقق من web.sitemap في الكود المصدري للإصدار الكامل. الآن عند تصفح موقع الويب باستخدام خريطة الموقع هذه ، سترى التأثير الموضح في الشكل 3.
الشكل 3 - عناصر القائمة الفرعية

لتعطيل هذا التأثير ، قم بتعيين خاصية MaximumDynamicDisplayLevels من التحكم في القائمة إلى الصفر كما هو موضح في القائمة 8.
قائمة 8 - خاصية MaximumDynamicDisplayLevels
< asp:Menu
ID =" Menu1 "
runat =" server "
DataSourceID =" SitemapDataSource1 "
Orientation =" Horizontal "
CssSelectorClass =" PrettyMenu "
MaximumDynamicDisplayLevels =" 0 "
> </ asp:Menu >بعد ذلك ، أضف القائمة الثانية والتحكم في SitemapDataSource وتعيين خصائصها كما هو موضح في القائمة 9.
قائمة 9 - التحكم في القائمة الفرعية
< asp:Menu
ID =" Menu1 "
runat =" server "
DataSourceID =" SitemapDataSource1 "
Orientation =" Horizontal "
CssSelectorClass =" PrettyMenu "
MaximumDynamicDisplayLevels =" 0 "
>
</ asp:Menu >
< asp:Menu
ID =" Menu2 "
runat =" server "
DataSourceID =" SitemapDataSource2 "
Orientation =" Horizontal "
CssSelectorClass =" PrettySubMenu "
>
</ asp:Menu >
< asp:SiteMapDataSource
ID =" SiteMapDataSource1 "
runat =" server "
ShowStartingNode =" False "
/>
< asp:SiteMapDataSource
ID =" SiteMapDataSource2 "
runat =" server "
StartingNodeOffset =" 1 "
ShowStartingNode =" False "
/>نخبر القائمة الثانية بشكل أساسي أنه يجب أن يعرض المستوى الثاني من العقد الموجودة في خريطة الموقع وأنه يجب ألا يعرض عقدة البداية التي تتوافق مع علامة التبويب المحددة في القائمة الأولى.
أيضا تم تعيين CSSseSeSelectorClass للقائمة الثانية على Prettysubmenu. CSS لهذه القائمة محاكاة للقائمة الأولى. قم بتنزيل رمز المصدر إذا كنت تريد التحقق من ذلك. سيعطيك تشغيل موقع الويب الآن هذه النتيجة الانقسام.
الشكل 4 - عناصر القائمة الفرعية المصممة

يجب حل العدد الأخير. من أجل توضيح هذه المسألة ، يجب إعادة تنظيم المشروع.
أولاً ، دعنا نضيف صفحة رئيسية إلى المشروع المسمى site.master. انقل الرمز ، والقوائم ومصادر البيانات ، من صفحة Default.aspx إلى الصفحة الرئيسية ووضعها قبل حامل مكان المحتوى الأول في الجسم. بعد ذلك ، يمكنك حذف صفحة Default.aspx بأمان.
الآن دعنا نضيف بعض عناصر نموذج محتوى الويب إلى المشروع. أضف نماذج محتوى الويب التي تتوافق مع عناصر العقدة الأولى لخريطة الموقع وعقدها الفرعية ، وهي:
تأكد من اختيار site.master كصفحة رئيسية لكل من نماذج محتوى الويب هذه. الصفحات الأخرى المذكورة في الويب.
قم بتشغيل الموقع مرة أخرى ، وانتقل إلى صفحة FOO. هذا سوف يكشف عن القضية.
الشكل 5 - قضية الاختيار

نظرًا لأننا انتقلنا إلى المستوى السفلي في خريطة الموقع ، فإن قائمة المستوى الأعلى لا تعرف عنصر القائمة الذي يجب وضع علامة عليه كما هو محدد. سنحتاج إلى القيام ببعض الترميز في رمز الصفحة الرئيسية وراء حل هذا.
يوضح لك قائمة 10 لقمة الرمز اللازمة.
سرد 10 - تحديد عنصر قائمة قائمة المستوى الصحيح
namespace MenuWebApplication
{
public partial class Site : System . Web . UI . MasterPage
{
private static string ExtractBaseUrl ( string url )
{
return url . Contains ( "?" ) ? url . Remove ( url . IndexOf ( '?' ) ) : url ;
}
protected void Page_Load ( object sender , EventArgs e )
{
Menu1 . DataBind ( ) ;
// Which node in the site map is currently selected?
SiteMapNode currentNode = SiteMap . CurrentNode ;
if ( currentNode != null )
{
// Obtain the Url of the currently selected node's parent node.
string parentUrl = String . Empty ;
SiteMapNode parentNode = currentNode . ParentNode ;
if ( parentNode != null )
{
parentUrl = ExtractBaseUrl ( parentNode . Url ) ;
}
// Obtain the Url of the currently selected node.
string currentUrl = ExtractBaseUrl ( currentNode . Url ) ;
// Iterate the top level menu tier.
foreach ( MenuItem menuItem in Menu1 . Items )
{
// Compare the menu item's Url against the currently
// selected node's Url or the Url of its parent.
string menuItemUrl = ExtractBaseUrl ( menuItem . NavigateUrl ) ;
if ( ( currentUrl == menuItemUrl ) || ( parentUrl == menuItemUrl ) )
{
// If either matches then mark the top level menu item as selected.
Menu1 . Items [ Menu1 . Items . IndexOf ( menuItem ) ] . Selected = true ;
break ;
}
}
}
}
}
}أنت الآن حر في تحديد أي من عناصر القائمة الفرعية. سيبقى عنصر قائمة المستوى الأعلى المقابل في اختياره لمنح الزائر فكرة بصرية حول المكان الذي يقع فيه حاليًا داخل الموقع.
الشكل 6 - قضية الاختيار ثابتة

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