PDA

توجه ! این یک نسخه آرشیو شده میباشد و در این حالت شما عکسی را مشاهده نمیکنید برای مشاهده کامل متن و عکسها بر روی لینک مقابل کلیک کنید : آموزشی معرفی کنترل ها و تکنیک های موجود در ASP.NET Ajax



moji5
18th December 2009, 03:54 AM
قصد دارم در سلسله مقالاتي به معرفي کنترل ها و تکنيک هاي موجود در MS Ajax بپردازم که قسمت اول و شروع بحث را در اين مقاله مشاهده خواهيد کرد.
MS Ajax يا به بيان کامل تر Microsoft Ajax کتابخانه اي از توابع مي باشد که توسط شرکت مايکروسافت به منظور بهره گيري از تکنولوژي آژاکس (Ajax) در برنامه هاي تحت وب در VS 2005 ايجاد شده است.
لازم به ذکر است که نام سابق آن Atlas بوده و هم اکنون به صورت منبع باز (Open Source) در دسترس مي باشد.
براي دريافت MS Ajax به سايت http://Ajax.Asp.net (http://ajax.asp.net/) مراجعه کنيد. روي دکمه Download ASP.NET Ajax کليک کنيد و فايل مربوطه که ASP.NET 2 Ajax Extensions مي باشد را دانلود کنيد. پس از دانلود فايل، آن را نصب کنيد. با نصب اين فايل ، در حقيقت بستري براي توسعه برنامه هاي کاربردي تحت وب با قابليت استفاده از امکانات آژاکس به وجود مي آيد.
اکنون برنامه VS 2005 را اجرا نموده و يک وب سايت جديد ايجاد کنيد. خواهيد ديد که علاوه بر گزينه هايي که قبلا و به طور پيش فرض در VS 2005 وجود دارد مانند ASP.NET Web Site و ASP.NET Web Service و ....... ، گزينه جديدي به نام ASP.NET Ajax-Enabled Web Site اضافه شده است.
گزينه ASP.NET Ajax-Enabled Web Site را انتخاب نموده و تاييد نماييد.
اکنون اگر به صفحه اول وب سايت دقت کنيد ، مي بينيد که بر خلاف وب سايت هايي که قبلا ايجاد نموده ايد، يک کنترل به نام Script Manager روي صفحه اول وب سايت وجود دارد. و اگر به Toolbox سمت چپ دقت کنيد مي بينيد که تب جديدي به نام Ajax Extensions اضافه شده است که حاوي کنترل هاي اصلي MS Ajax مي باشد.
به ياد داشته باشيد که براي استفاده از امکانات MS Ajax در يک صفحه وب سايت فقط نياز به يک Script Manager در صفحه داريد.
يک کنترل از نوع Update Panel از تب مربوطه انتخاب نموده و به صفحه اضافه کنيد.
Update Panel کنترلي است که براي به روزرساني جزئي (Partial Updating) در صفحه استفاده مي شود. يعني کنترل هايي که در داخل Update Panel قرار مي گيرند ، بدون نياز به اينکه کل صفحه به روز رساني شود ، مي توانند خود را به روز رساني نمايند.
مطابق شکل زير يک کنترل ليبل و يک دکمه به داخل Update Panel ، و يک کنترل ليبل نيز به خارج از Update Panel اضافه نماييد.
http://www.30sharp.com/Contents/39/In.gif اکنون در رويداد لود برنامه قطعه کد زير را بنويسيد.

Label1.Text = DateTime.Now.ToString();
Label2.Text = DateTime.Now.ToString();
و در رويداد کليک مربوط به دکمه ، قطعه کد زير را بنويسيد.

Label1.Text = DateTime.Now.ToString();
صفحه را اجرا کنيد. خواهيد ديد که هر دوي ليبل ها ، زمان اجراي صفحه را نشان مي دهند. روي دکمه کليک کنيد. اکنون مشاهده مي کنيد که با هربار کليک کردن دکمه ، زماني که ليبل اول يعني ليبلي که داخل Update Panel قرار دارد به روز رساني مي شود در حاليکه هنوز ليبل دوم زماني اجراي صفحه براي اولين بار را نشان مي دهد. در ضمن عمل Post Back نيز انجام نشده است.
شما مي توانيد براي تمرين بيشتر ساير کنترل ها را نيز به داخل Update Panel اضافه نموده و رفتار آن ها را مشاهده کنيد.
به علت اينکه همواره قرار دادن دکمه در محل Update Panel امکان پذير نمي باشد و ما نياز داريم که دکمه را در نقاط مختلف صفحه و محل مخصوص خود قرار دهيم . اين امکان وجود دارد که دکمه را خارج از Update Panel قرار دهيم . براي انجام اين کار ابتدا دکمه را از Update Panel خارج نماييد.
http://www.30sharp.com/Contents/39/Out.gif سپس به قسمت کدهاي HTML صفحه برويد و داخل تگ UpdatePanel ، يک تگ Triggers اضافه کنيد. و داخل تگ Triggers ، يک تگ AsyncPostBackTrigger اضافه کنيد.
تغييرات مربوطه را در زير مشاهده مي کنيد.

<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Label ID="Label1" runat="server" Text="Label"></asp:Label><br />
<br />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Button1" EventName="Click" />
</Triggers>
</asp:UpdatePanel>همانطور که مشاهده مي کنيد صفت ControlID نام دکمه و صفت EventName نام رويدادي از دکمه است که با به وجود آمدن آن ، محتواي Update Panel به روز رساني خواهد شد.
اکنون دوباره صفحه را اجرا کنيد. خواهيد ديد با اينکه ما دکمه را از داخل Update Panel خارج نموده ايم ولي باز هم عمل بروز رساني بدون انجام عمل PostBack انجام خواهد شد.
در مقالات بعدي کنترل ها و تکنيک هاي ديگر MS Ajax را معرفي خواهم کرد.

moji5
18th December 2009, 03:55 AM
در اين مقاله به معرفي کنترل ModalPopupExtender مي پردازم.
مقدمه :

همگي ما پيام هايي را که قبلا با استفاده از تابع window.confirm مربوط به زبان جاوااسکريپت به کاربر نشان مي داديم را به ياد مي آوريم.
با استفاده از کنترل ModalPopupExtender مربوط به Microsoft Ajax مي توان پنجره هايي با ظاهري بسيار زيبا به کاربر نشان داد. در اين مقاله ما دو مثال از کاربرد اين کنترل را انجام خواهيم داد.
مثال اول :

در مثال اول ما يک پنجره پيغام Popup به کاربر نشان خواهيم داد تا رنگ پس زمينه صفحه را انتخاب نموده و تاييد نمايد. سپس بدون اينکه صفحه PostBack نمايد، تغييرات به صفحه اعمال خواهد شد.
در شکل زير اين پنجره را مشاهده مي نماييد.
http://www.30sharp.com/Contents/40/Popup.gif لازم به ذکر مي باشد که براي اينکه بتوانيم از کنترل ModalPopupExtender استفاده نماييم، ابتدا بايد کتابخانه ASP.NET AJAX Control Toolkit را از اينجا (http://ajax.asp.net/downloads/default.aspx?tabid=47) دانلود نماييد. و سپس فايل دانلود شده ، که يک فايل زيپ مي باشد را استخراج نماييد.
همراه با ساير فايل هاي موجود در اين فايل زيپ، يک اسمبلي به نام AjaxControlToolkit.dll موجود مي باشد که در حقيقت تمام کنترل هاي موجود در ASP.NET AJAX Control Toolkit ، در اين اسمبلي مي باشند.
يک پروژه وب سايت از نوع ASP.NET Ajax-Enabled Web Site ايجاد نماييد. اسمبلي AjaxControlToolkit.dll را به Toolbox برنامه ويژوال استوديو اضافه نماييد.
اکنون کنترل هاي موجود در اين اسمبلي را در Toolbox مشاهده مي کنيد.
قبل از ايجاد اجزاي اصلي مثال، لطفا استايل هاي زير را به صفحه (در داخل تگ Head) اضافه نماييد.

<style type="text/css">
.ModalBackColor
{
background-color:Gray;
filter:alpha(opacity=70);
opacity:0.7;
}
.modalPopup {
background-color:#ffffdd;
border-width:3px;
border-style:solid;
border-color:Gray;
padding:3px;
width:250px;
}
</style>در اينجا دو عدد استايل تعريف شده است که در آينده از آن ها استفاده خواهيم کرد.
کدهاي جاوا اسکريپت زير را به صفحه اضافه کنيد.(در داخل تگ Head)

<script type="text/javascript">
var SelectedColorName;
function onOk()
{
document.bgColor=SelectedColorName;
}
</script>ملاحظه مي کنيد که در اين قسمت ما يک متغير عمومي جاوا اسکريپت به نام SelectedColorName تعريف کرده ايم که وظيفه آن نگهداري نام رنگي است که کاربر در پنجره Popup انتخاب مي کند. وظيفه تابع onOk، اعمال رنگي که در متغير SelectedColorName ذخيره شده است به پس زمينه صفحه مي باشد.
پنجره Popup که به کاربر نمايش داده مي شود درحقيقت يک کنترل Panel مي باشد که سفارشي سازي شده است.
اکنون نوبت به طراحي پنجره Popup يعني همان Panel مي باشد. يک Panel به صفحه اضافه کنيد و تغييرات زير را روي آن اعمال نماييد.

<asp:Panel ID="Panel1" runat="server" CssClass="modalPopup" Style="display: none"
Width="233px" Direction="RightToLeft">
<p>آيا مايل هستيد :</p>
<input id="RadioA" name="Radio" onclick="SelectedColorName = 'Yellow';" type="radio" />
<label for="RadioA" class="YellowColor" >رنگ پس زمينه زرد شود.</label><br />
<input id="RadioB" name="Radio" onclick="SelectedColorName = 'Red';" type="radio" />
<label class="RedColor" for="RadioB" > رنگ پس زمينه قرمز شود.</label><br />

<br />
<div align="center">
<asp:Button ID="btnOk" runat="server" Text="OK" />
<asp:Button ID="btnCancel" runat="server" Text="Cancel" />
</div>
</asp:Panel>در قطعه کد بالا دو دکمه راديويي داريم که کاربر رنگ مورد نظر خود را از آنها انتخاب مي کند و دو دکمه داريم که کاربر به وسيله آنها مي تواند انصراف يا تاييد را انتخاب کند.
هنگامي که کاربر دکمه هاي راديويي را انتخاب مي نمايد، متغير SelectedColorName مقدار دهي مي شود.
اکنون يک کنترل LinkButton به صفحه به شکل زير اضافه نماييد.

<asp:LinkButton ID="LinkButton1" runat="server">Click Here For Change Color</asp:LinkButton>خوب همه چيز آماده است و اکنون نوبت اضافه کردن کنترل ModalPopupExtender به صفحه مي باشد. با استفاده از Drag And Drop کنترل ModalPopupExtender را به صفحه اضافه کنيد. سپس به نماي Markup برويد و کدها را به صورت زير تغيير دهيد.

<cc1:ModalPopupExtender ID="ModalPopupExtender1" runat="server"
TargetControlID="LinkButton1"
PopupControlID="Panel1"
BackgroundCssClass="ModalBackColor"
DropShadow="true"
OkControlID="btnOk"
OnOkScript="onOk()"
CancelControlID="btnCancel"
/>کنترل ModalPopupExtender داراي صفات مختلفي مي باشد که در زير به معرفي تعدادي از آنها مي پردازم :


TargetControlID : اين صفت ID کنترلي را نگهداري مي کند که وظيفه آن فعال کردن پنجره Popup مي باشد. در اين مثال ما از کنترل LinkButton1 براي فعال کردن اين پنجره استفاده مي کنيم. يعني وقتي شما روي اين دکمه کليک مي کنيد، پنجره Popup نمايش داده مي شود.
PopupControlID : اين صفت ID کنترلي را نگهداري مي کند که قرار است به صورت Popup نمايش داده شود. در اين مثال ما از کنترل Panel1 براي انجام اين کار استفاده نموده ايم.
BackgroundCssClass : اين صفت نام يک استايل را نگهداري مي کند. هنگامي که پنجره Popup در حال نمايش است اين استايل به صفحه اعمال مي شود. و پس از بسته شده پنجره ، از بين مي رود.
DropShadow : در صورتي که مقدار اين صفت true باشد، هنگام نمايش پنجره Popup ، يک سايه اطراف آن رسم مي شود.
OkControlID : اين صفت ID کنترلي را نگهداري مي کند که توسط آن ما متوجه مي شويم کاربر پيام نمايش داده شده در پنجره Popup را تاييد نموده است. در اين مثال ما از دکمه btnOk داخل پنل استفاده نموده ايم.
OnOkScript : اين صفت نام يک تابع جاوا اسکريپت را نگهداري مي کند. در صورتي که کاربر پيام پنجره Popup را تاييد نمايد اين تابع فراخواني مي شود. در اينجا ما از تابع جاوا اسکريپتي که در ابتداي صفحه نوشتيم (onOk) استفاده کرديم.
CancelControlID : کاربرد اين صفت در حقيقت عکس صفت OkControlID مي باشد. اين صفت ID کنترلي را نگهداري مي کند که هنگام نمايش پنجره Popup ، توسط آن متوجه مي شويم کاربر گزينه انصراف را انتخاب نموده است که در اين مثال دکمه btnCancel مي باشد.
OnCancelScript : وظيفه اين صفت نيز عکس صفت OnOkScript مي باشد که ما در اين مثال از اين صفت استفاده نکرديم. در نتيجه وقتي کاربر دکمه btnCancel را کليک مي کند اتفاق خاصي نمي افتد و فقط پنجره Popup بسته مي شود.
X , Y : به طور پيشفرض پنجره Popup در وسط صفحه نمايش ديده مي شود. در صورتي که بخواهيم مکان آن را عوض کنيم بايد به اين دو صفت، مقدار مناسب را بدهيم . مقدار X ,Y مختصات گوشه بالا و سمت چپ پنجره Popup را نگهداري مي کنند.

اکنون صفحه آماده اجرا مي باشد. آن را اجرا نموده و تغييرات را مشاهده نماييد.
مثال دوم :

در مثال قبل تغييرات انتخاب شده توسط کاربر در پنجره Popup، بدون انجام عمل PostBack، به صفحه اعمال شدند.
گاهي اوقات ما احتياج داريم با توجه به انتخاب کاربر، صفحه را PostBack نماييم. در اين مثال اين کار را انجام خواهيم داد.
در اين مثال يک پنجره Popup به کاربر نشان مي دهيم که در صورت تاييد کاربر، صفحه را به سايت 30sharp.com انتقال مي دهيم.
يک صفحه جديد به برنامه اضافه نماييد و يک کنترل ScriptManager به آن اضافه کنيد.
کنترل هاي مثال قبل را به صفحه جديد اضافه کنيد و تغييرات زير را روي آنها اعمال نماييد.
ابتدا در رويدا Click مربوط به کنترل LinkButton قطعه کد زير را بنويسيد.

Response.Redirect("http://www.30sharp.com (http://www.30sharp.com/ShowArticle.aspx?nid=10&did=40&AuthorID=1)");محتواي کنترل Panel1 را به صورت زير تغيير دهيد.

<asp:Panel ID="Panel1" runat="server" CssClass="modalPopup" Direction="RightToLeft"
Style="display: none" Width="233px">
<p>
آيا مايل هستيد به سايت 30sharp.com انتقال يابيد؟</p>

<br />
<div align="center">
<asp:Button ID="btnOk" runat="server" Text="OK" />
<asp:Button ID="btnCancel" runat="server" Text="Cancel" />
</div>
</asp:Panel>تابع onOk را به صورت زير تغيير دهيد.

<script type="text/javascript">
var SelectedColorName;
function onOk() {
__doPostBack('LinkButton1','');
}
</script>
نکته اصلي در همين جا مي باشد. اگر به تابع onOk توجه کنيد متوجه مي شويد که ما از تابع PostBack__ جهت ارسال صفحه به سمت سرور استفاده کرده ايم. پس از اينکه صفحه PostBack نمود به طور خود کار رويداد Click مربوط به LinkButton اجرا مي شود و صفحه به سايت 30sharp.com انتقال مي يابد.

moji5
18th December 2009, 03:57 AM
کنترل DropShadowExtender يکي از کنترل هاي موجود در AjaxControlToolkit مي باشد. اين کنترل جهت به وجود آوردن سايه (Shadow) در اطراف کنترل هاي صفحه وب استفاده مي شود.
در اين مقاله مي خواهيم يک کنترل Panel به شکل زير، را به وجود آوريم.
http://www.30sharp.com/Contents/42/Drapshadow.gif شروع :

يک پروژه وب سايت از نوع ASP.NET Ajax-Enabled Web Site ايجاد نماييد.
يک کنترل Panel به صفحه اضافه کنيد. سپس يک کنترل DropShadowExtender که يکي از کنترل هاي مربوط به اسمبلي AjaxControlToolkit مي باشد را به صفحه اضافه کنيد.
ياد آوري :

براي اينکه کنترل هاي مربوط به AjaxControlToolkit را به برنامه اضافه کنيد کافي است اسمبلي AjaxControlToolkit را همانطور که در مقالات قبلي توضيح دادم به Toolbox برنامه اضافه کنيد تا کنترل هاي موجود در آن را مشاهده نماييد.
روي کنترل DropShadowExtender ، کليک راست تموده و گزينه Properties را انتخاب نماييد. صفت TargetControlID ، نام کنترلي را که قرار است براي آن سايه ايجاد کنيم را نگهداري مي کند. پس در اينجا نام Panel1 را به آن نسبت دهيد.
اکنون روي کنترل Panel کليک راست کنيد و گزينه Properties را انتخاب نماييد. اگر با دقت به صفات آن نگاه کنيد، متوجه مي شويد که يک گزينه جديد به نام DropShadowExtender1 به آن اضافه شده است.
روي علامت "+" در سمت چپ اين گزينه کليک کنيد و صفات آن را ملاحظه نماييد.
http://www.30sharp.com/Contents/42/prop.gif اکنون به معرفي اين صفات مي پردازم.


BehaviorID -- اين صفت شناسه DropShadowExtender مربوطه را نگهداري مي کند. در صورتي که اين گزينه را تغييري دهيد، يک صفت جديد به تگ DropShadowExtender اضافه مي شود که شناسه BehaviorID که شما تغيير داده ايد را نگهداري مي کند.
Opacity -- اين صفت ميزان شفافيت سايه دور Panel را نسبت به رنگ پس زمينه صفحه مشخص مي کند که ميزان آن به طور پيشفرض برابر 5 مي باشد. مقدار اين صفت مي تواند بين 0 (کاملا شفاف) و 10 (کاملا تيره) باشد.
Rounded -- به طور پيشفرض سايه اي که در اطراف کنترل نمايش داده مي شود به صورت چهارگوش مي باشد و مقدار اين صفت برابر false مي باشد. در صورتي که مقدار آن را true کنيم گوشه هاي سايه و کنترل به صورت منحني نمايش داده مي شود. (همانند شکل بالا)
Radius -- در صورتي که صفت Rounded برابر true باشد، اين صفت اندازه شعاع قسمت هاي انحنادار را مشخص مي کند.
Width -- اين صفت اندازه سايه اطراف کنترل (در اينجا Panel) را مشخص مي کند که به طور پيشفرض مقدار آن 5 مي باشد و مقياس آن پيکسل مي باشد.
TrackPosition -- در صورتي که استايل position مربوط به کنترل (در اينجا Panel) برابر absolute باشد و يا اينکه امکان اين را گذاشته باشيم که Panel بتواند روي صفحه حرکتي داشته باشد، بايد مقدار اين صفت که به طور پيشفرض false مي باشد را true نماييم.

نکته :

تغييراتي که ما اينجا انجام مي دهيم در حقيقت روي تگ <DropShadowExtender> اعمال مي شود و نه Panel .
در زير تغييرات اعمال شده را مي توانيد ببينيد.

<cc1:DropShadowExtender
ID="DropShadowExtender1"
runat="server"
TargetControlID="Panel1"
Radius="8"
Rounded="True"
TrackPosition="true"
Width="7" >
</cc1:DropShadowExtende>اکنون صفحه را اجرا کنيد و نتيجه کار را مشاهده نماييد.

moji5
18th December 2009, 04:05 AM
در اين مقاله به معرفي کنترل Accordion که يکي از کنترل هاي موجود در AjaxControlToolkit است، مي پردازم.
مقدمه :

عملکرد کنترل Accordion همانند چندين پنل مي باشد که در هر لحظه فقط محتواي يکي از پنل ها قابل مشاهده مي باشد. عملکرد اين کنترل را مي توانيد در اينجا (http://asp.net/AJAX/Control-Toolkit/Live/Accordion/Accordion.aspx)مشاهده نماييد.
در اين مقاله قصد داريم يک کنترل Accordion به شکل زير ايجاد کنيم که عملکرد آن شبيه 3 پنل مي باشد که در هر لحظه فقط محتواي يکي از آنها قابل مشاهده مي باشد.
http://www.30sharp.com/Contents/48/Accordion.gif شکل کلي قضيه به اين صورت است که کنترل Accordion يک نگاهدارنده (Container) مي باشد که شامل يک و يا چند Accordion Pane مي باشد و در هنگام اجراي صفحه، در هر لحظه فقط محتويات يکي از Accordion Pane نمايش داده مي شود.
شروع :

يک پروژه از نوع ASP.NET AJAX-Enabled WebSite ايجاد کنيد و سپس به نماي سورس (Source View) صفحه برويد. يک کنترل Accordion به صفحه اضافه نماييد و آن را به شکل زير تکميل نماييد.

<ajaxToolkit:Accordion ID="Accordion1" runat="server"
SuppressHeaderPostbacks=true
SelectedIndex="0"
FadeTransitions="true"
FramesPerSecond="40"
TransitionDuration="250"
RequireOpenedPane="false"
AutoSize="None" >
</ajaxToolkit:Accordion>
اکنون به معرفي تعدادي از صفات مربوط به Accordion مي پردازم.


SelectedIndex : با مقدار دهي به اين صفت مشخص مي کنيم که هنگام اجراي صفحه، محتواي کداميک از Accordion Pane ها به طور پيشفرض در حال نمايش باشد. در اين مثال من به آن مقدار صفر داده ام پس محتواي اولين Accordion Pane نمايش داده مي شود.
FadeTransitions : در صورتي که مقدار اين صفت true باشد هنگام باز و بسته شدن Accordion Pane ها يک جلوه گرافيکي Fade نمايش داده مي شود.
FramesPerSecond : با مقدار دهي به اين صفت تعداد فريم هايي را مشخص مي کنيم که حالت انيميشني کنترل Accordion در هر ثانيه اجرا مي کند.
TransitionDuration : مدت زمان به ميلي ثانيه، که مدت زمان جلوه انيميشني باز و بسته شدن يک Accordion Pane را مشخص مي کند.
HeaderCssClass : نام يک کلاس CSS را مي گيرد که مي تواند به Header تمام Accordion Pane ها و يا يک Accordion Pane مشخص اعمال شود.
ContentCssClass : نام يک کلاس CSS را مي گيرد که مي تواند به Content تمام Accordion Pane ها و يا يک Accordion Pane مشخص اعمال شود.
HeaderSelectedCssClass : نام يک کلاس CSS را مي گيرد و به Header مربوط به Accordion Pane ي که در هر لحظه انتخاب مي شود اعمال مي شود.
SuppressHeaderPostbacks : همانطور که در ادامه مقاله خواهيد ديد، ما در Header مربوط به هر کدام از Accordion Pane ها از يک هايپرلينک استفاده مي کنيم که با کليک شدن آن محتواي قسمت Content آن نمايش داده شود. با true شدن اين صفت، هنگام کليک شدن هايپرلينک ، صفحه Postback نمي کند و فقط محتواي Accordion Pane مربوطه نمايش داده مي شود.(اگر به اين صفت مقدار false بدهيد، هنگام کليک شدن هايپرلينک، صفحه Postback مي کند.)
DataSource : کنترل Accordion داراي قابليت Data Binding مي باشد و مي تواند به يک ديتاسورس بايند شود.
DataSourceID : اين صفت ID يک ديتاسورس را نگهداري مي کند.
DataMember : هنگامي که از DataSourceID استفاده مي کنيم، اين صفت نام عضو (Member) را نگهداري مي کند.
RequireOpenedPane : به طور پيشفرض مقدار اين صفت true مي باشد و هنگامي که روي لينک داخل Header هر Accordion Pane کليک مي کنيد محتواي آن Accordion Pane نمايش داده مي شود (Pane باز مي شود) و در زماني که محتواي آن Accordion Pane در حال نمايش باشد، وقتي روي هايپرلينک کليک مي کنيد اتفاقي نمي افتد. اگر مقدار اين صفت را به false تغيير دهيد آنگاه هنگام کليک مجدد بر روي هايپرلينک ، اگر محتواي Accordion Pane در حال نمايش باشد آن را مي بندد و در غير اينصورت آن را باز مي کند.
AutoSize : اين صفت مي تواند سه مقدار داشته باشد. اگر مقدار آن "None" باشد هنگام باز و بسته شدن Accordion Pane، سايرعناصر صفحه با توجه به اندازه محتويات Accordion Pane به اطراف جابجا مي شوند. اگر مقدار آن "Limit" باشد، سايز Accordion Pane هنگام باز شدن، بيشتر از سايزي که ما به Accordion Pane داده ايم نخواهد شد ولي اگر سايز محتويات آن کمتر از اندازه اي که ما داده ايم باشد، اندازه Accordion Pane به اندازه محتويات خواهد شد. اگر مقدار آن "Fill" باشد.سايز Accordion Pane دقيقا برابر سايزي مي شود که ما داده ايم و درنتيجه کمتر يا بيشتر نمي شود.

تذکر :

در اينترنت اکسپلورر 6 و 7 هنگامي که مقدار صفت AutoSize برابر Limit يا Fill باشد ، دقيقا يکسان رفتار مي کنند زيرا اين نسخه ها از صفت max-height مربوط به CSS حمايت نمي کنند.
اکنون به سراغ اضافه کردن Accordion Pane ها به کنترل Accordion مي رويم.
کنترل Accordion داراي تگ <Panes> مي باشد که Accordion Pane ها داخل اين تگ قرار مي گيرند. همانطور که در قطعه کد زير مشاهده مي کنيد، ما يک Accordion Pane را به کنترل Accordion اضافه کرده ايم .

<ajaxToolkit:Accordion ID="Accordion1" runat="server"
SuppressHeaderPostbacks=true
SelectedIndex="0"
HeaderCssClass="accordionHeader"
ContentCssClass="accordionContent"
FadeTransitions="true"
FramesPerSecond="40"
TransitionDuration="250"
RequireOpenedPane="false"
AutoSize="None" >

<Panes>
<ajaxToolkit:AccordionPane ID = "AccordionPane1" runat = "server" >
<Header>
<a href = "" class = "accordionLink"> Section 1</a>
</Header>
<Content>
<p>Persian C# Developers in <font color=red><b>30sharp.COM</b></font></p>
</Content>
</ajaxToolkit:AccordionPane>
</Panes>
</ajaxToolkit:Accordion>
هنگامي که با دقت به قطعه کد بالا نگاه کنيد متوجه مي شويد که Accordion Pane داراي دو تگ به نام هاي Header و Content مي باشد. در قسمت Header يک هايپرلينک قرار داده شده است که عملکرد آن را قبلا توضيح داده ام و در قسمت Content نيز محتواي Accordion Pane قرار مي گيرد.
اکنون کار تمام است و شما مي توانيد صفحه را اجرا کنيد و نتيجه را ببينيد.

moji5
18th December 2009, 04:05 AM
در اين مقاله به معرفي کنترل ConfirmButtonExtender که يکي از مجموعه کنترل هاي موجود در ASP.NET AjaxControlToolkit مي باشد، مي پردازم.
مقدمه :

اين مقاله را با طرح يک مثال شروع مي کنم. فرض کنيد که يک سيستم خبرنامه نوشته ايد که تعدادي از کاربران در آن عضو شده اند و براي سهولت کاربران، امکان لغو اشتراک را توسط دکمه اي قرار داده ايد. حال اگر کاربر به طور اتفاقي و ناخواسته اين دکمه را کليک کند چه اتفاقي مي افتد؟
نتيجه اين مي شود که اشتراک کاربر در خبرنامه لغو مي شود. مشابه اين حالت مي تواند در موقعيت هاي مختلف مانند حذف رکورد ها از ديتابيس و ارسال فرم هايي با اطلاعات مهم پيش آيد. پس ما احتياج داريم که به نحوي اطمينان پيدا کنيم که کاربر به طور تصادفي دکمه را کليک نکرده است.
کنترل ConfirmButtonExtender به همين منظور به وجود آمده است.
شروع :

يک پروژه وب سايت از نوع ASP.NET AJAX-Enabled WebSite ايجاد نماييد. يک کنترل Label و يک کنترل Button به صفحه اضافه کنيد و در رويداد کليک Button قطعه کد زير را بنويسيد.

protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = "Form Submited on : "+DateTime.Now.ToString("T");
}
همانطور که مشاهده مي کنيد، در صورتي که Button کليک شود، تاريخ کليک شدن آن را Label نشان مي دهد.
اکنون مي خواهيم هنگامي که کاربر روي دکمه کليک کرد، يک پنجره به شکل زير به کاربر نشان دهيم.
http://www.30sharp.com/Contents/55/confirm.gif در صورتي که کاربر دکمه OK را کليک نمايد، متوجه خواهيم شد که دکمه به طور اتفاقي و ناخواسته کليک نشده است و رويداد کليک Button اجرا مي شود و در صورتي که دکمه Cancel را کليک نمايد، متوجه مي شويم که دکمه به صورت ناخواسته کليک شده است و رويداد کليک Button اجرا نمي شود.
يک کنترل ConfirmButtonExtender به صفحه اضافه کنيد. به نماي Source View برويد و قطعه کد آن را به شکل زير تغيير دهيد.

<cc1:ConfirmButtonExtender ID="ConfirmButtonExtender1" runat="server"
TargetControlID="Button1"
ConfirmOnFormSubmit="True"
ConfirmText="آيا براي انجام اين کار مطمئن مي باشيد؟" >
</cc1:ConfirmButtonExtender>اکنون به شرح صفات کنترل ConfirmButtonExtender مي پردازم


TargetControlID : اين صفت نام Button يا LinkButton ي را نگهداري مي کند که قصد داريم هنگام کليک شدن آن توسط کاربر اعمالي که قبلا ذکر شد، انجام شود. در اين مثال، Button1 مي باشد.
ConfirmText : جمله اي را نگهداري مي کند که از کاربر، زماني که دکمه کليک مي شود، پرسيده مي شود.
OnClientCancel : نام يک تابع جاوا اسکريپت را نگهداري مي کند که زماني که کاربر دکمه Cancel را کليک مي کند، فراخواني مي شود. اين صفت اختياري مي باشد که بسته به نياز خود مي توانيد در زمان نياز، تابع جاوا اسکريپت آن را بنويسيد.
ConfirmOnFormSubmit: با true نمودن اين صفت، تنها زماني پنجره مورد نظر ما نمايش داده مي شود که فرم بدون هيچ مشکلي آماده براي ارسال به سمت سرور يعني Submit شدن مي باشد. مثلا اگر فرمي داشته باشيم که در آن از Validator ها استفاده کرده باشيم، تنها زماني پنجره مورد نظر ما نمايش داده مي شود که فرم کاملا توسط Validator ها اعتبارسنجي شده و آماده براي Submit باشد.

صفحه مورد نظر را اجرا کنيد و نتيجه را مشاهده نماييد.

moji5
18th December 2009, 04:06 AM
مقدمه :

در نرم افزارهاي تحت وب، مواقعي پيش مي آيد که قصد داريم موردي را در معرض امتيازدهي کاربران قرار دهيم. مثلا امکان اين را بدهيم که کاربر، يک امتياز از بين 1 تا 5 را انتخاب نموده و به يک مقاله يا محصول و يا غيره نسبت دهد.
با جمع آوري مجموعه امتيازات نسبت داده شده به محصول، توسط کاربران، مي توانيم ميزان محبوبيت محصول را مورد ارزيابي قرار دهيم.
کنترل Rating بدين منظور به وجود آمده است. در اين مقاله اين کنترل را معرفي نموده و سپس يک مثال کاربردي از آن را انجام خواهم داد.
کنترل Rating در حالت پيشفرض داراي شکل و يا رنگ خاصي نمي باشد و براي شکل دادن به آن بايد از CSS استفاده نماييد.
در اين مقاله ما قصد داريم Rating را به شکل زير در آوريم.
http://www.30sharp.com/Contents/56/Rating.gif همانطور که ملاحظه مي کنيد، براي به وجود آوردن شکل بالا ما نياز به دو قطعه عکس داريم. يکي براي ستاره هاي زرد رنگ و يکي براي ستاره هاي بدون رنگ.
ضمنا يک قطعه عکس ستاره قرمز رنگ نيز نياز داريم که در مدت زمان بين کليک شدن کنترل Rating توسط کاربر و به اتمام رسيدن پردازش سمت سرور، اين عکس نمايش داده مي شود.
به طور کلي ما از استايل هاي زير در اين مقاله استفاده مي کنيم.

.ratingStar {
font-size: 0pt;
width: 13px;
height: 12px;
margin: 0px;
padding: 0px;
cursor: pointer;
display: block;
background-repeat: no-repeat;
}
.filledRatingStar {
background-image: url(Images/FilledStar.png);
}
.emptyRatingStar {
background-image: url(Images/EmptyStar.png);
}
.savedRatingStar {
background-image: url(Images/SavedStar.png);
}
شروع :

يک پروژه از نوع ASP.NET Ajax-Enabled WebSite ايجاد کنيد و کنترل Rating را به صفحه اضافه نماييد. به نماي Source View رفته و قطعه کد موجود را به شکل زير تغيير دهيد.

<cc1:Rating ID="Rating1" runat="server"
CurrentRating="2"
MaxRating="5"
StarCssClass="ratingStar"
WaitingStarCssClass="savedRatingStar"
FilledStarCssClass="filledRatingStar"
EmptyStarCssClass="emptyRatingStar"
OnChanged="RatingChanged"
/>کنترل Rating داراي صفات نسبتا زيادي مي باشد که من در اينجا چند عدد از مهمترين ها را معرفي مي کنم.


CurrentRating: اين گزينه امتيازي را مشخص مي کند که ما به طور پيشفرض به کنترل Rating داده ايم. به طور مثال در قطعه کد بالا مشخص کرديم که دو عدد از ستاره ها روشن باشند يعني امتياز 2 از 5 را به آن داده ايم.
MaxRating : اين صفت بيشترين امتيازي را که کاربر مي تواند اعمال نمايد را مشخص مي کند. در قطعه کد بالا بيشترين امتياز، 5 در نظر گرفته شده است يعني 5 ستاره چهت امتياز دادن وجود دارد و کاربر مي تواند امتياز بين 1 تا 5 را انتخاب کند.
StarCssClass : اين صفت نام کلاس CSS ي را نگهداري مي کند که به کليه ستاره هايي که در حال نمايش هستند، اعمال مي شود.
WaitingStarCssClass : نام کلاس CSS ي را نگهداري مي کند که بين مدت زماني که کاربر بر روي امتياز مورد نظر خود کليک مي کند و زماني که پردازش سمت سرور به انتها مي رسد، اين استايل به کنترل اعمال مي شود.
FilledStarCssClass : نام کلاس CSS ي را نگهداري مي کند که به ستاره هايي که روشن هستند اعمال مي شود.
EmptyStarCssClass : نام کلاس CSS ي را نگهداري مي کند که به ستاره هايي که خاموش هستند اعمال مي شود.
AutoPostBack : اگر مقدار اين صفت true باشد، هنگامي که کاربر روي کنترل کليک مي کند عمل PostBack انجام مي شود.
ReadOnly : اگر مقدار اين صفت true باشد، اين کنترل غير قابل تغيير مي شود و کاربر فقط مي تواند امتياز را ببيند و نمي تواند آن را تغيير دهد.
RatingAlign : اين صفت مي تواند مقادير Vertical يا Horizontal را بگيرد و همانطور که از نامش پيداست، مشخص مي کند که کنترل به صورت عمودي يا افقي نمايش داده شود.
RatingDirection : مشخص مي کند که چينش ستاره ها از "راست به چپ" يا از "چپ به راست" يا از "بالا به پايين" يا از "پايين به بالا" باشد.
OnChanged : اين گزينه نام يک رويداد (Event) را نگهداري مي کند که هنگام کليک شدن کنترل Rating توسط کاربر، اتفاق مي افتد.
Tag : اين صفت مي تواند يک مقدار دلخواه را نگهداري نمايد. در ادامه اين مقاله کاربرد اين صفت را خواهيد ديد.


مثال دوم :

اکنون فرض کنيد تعدادي محصول داريد که آن ها را در يک GridView نشان داده ايد و قصد داريد براي آن ها از کنترل Rating استفاده کنيد و در حقيقت شکل زير را پديد آوريد.
http://www.30sharp.com/Contents/56/Products.gif يک کنترل Rating به صفحه اضافه کنيد و کدهاي آن را به شکل زير تغيير دهيد.

<cc1:Rating ID="Rating1" runat="server"
CurrentRating="2"
MaxRating="5"
StarCssClass="ratingStar"
WaitingStarCssClass="savedRatingStar"
FilledStarCssClass="filledRatingStar"
EmptyStarCssClass="emptyRatingStar"
OnChanged="RatingChanged"
Tag='<%# Eval("ProductID") %>'
/>قسمت جالب اين کد، صفت Tag مي باشد که ProductID مربوط به هر محصول را نگهداري مي کند. با کليک شدن کنترل Rating مربوط به هر محصول، ما در رويداد OnChanged به صورت زير به شناسه محصول و امتيازي که کاربر مي دهد، دسترسي داريم

protected void RatingChanged(object sender, RatingEventArgs e)
{
int ProductID =int.Parse(e.Tag);
string Rate = e.Value;
}

moji5
18th December 2009, 04:08 AM
مقدمه :

عملکرد کنترل DropDownExtender ، در حقيقت همانند يک Label مي ماند که وقتي اشاره گر ماوس را روي آن قرار مي دهيم شکل آن شبيه به يک DropDown مي شود و با کليک روي آن، گزينه هاي DropDown مشخص مي شود و ما مي توانيم يکي از گزينه ها را انتخاب نماييم.
عملکرد اين کنترل را در 3 حاالت زير مي بينيد.
1- شکل اين کنترل قبل از اينکه ماوس روي آن قرار بگيرد :
http://www.30sharp.com/Contents/70/DDE1.gif 2 - شکل اين کنترل زماني که ماوس روي آن قرار دارد :
http://www.30sharp.com/Contents/70/DDE2.gif 3 - شکل اين کنترل زماني که روي آن کليک مي شود :
http://www.30sharp.com/Contents/70/DDE3.gif در اين مقاله به پياده سازي يک DropDownExtender خواهم پرداخت که داراي 3 گزينه به نام هاي Option1 و Option2 و Option3 مي باشد.با کليک شدن هر گزينه ، متن گزينه کليک شده را نشان خواهيم داد. دقت داشته باشيد که تمام اعمال ذکر شده بدون انجام عمل PostBack، صورت خواهد گرفت.
دموي اين برنامه را ميتوانيد اينجا (http://www.30sharp.com/contents/70/demo.aspx) مشاهده کنيد.
براي پياده سازي مثال فوق احتياج به يک Label داريم که در حقيقت متن DropDownExtender را در حالت عادي نگهداري مي کند. سپس به يک کنترل Panel احتياج داريم که گزينه هاي DropDownExtender را نگهداري مي کند. هر يک از گزينه ها (Option ها) در حقيقت يک LinkButton هستند. و در نهايت زمان اضافه کردن کنترل DropDownExtender خواهد رسيد.
شروع :

در اين مثال من از استايل هاي زير براي شکل دهي به کنترل ها استفاده مي کنم.

.ContextMenuPanel
{
border: 1px solid #868686;
z-index: 1000;
background: url(menu-bg.gif) repeat-y 0 0 #FAFAFA;
cursor: default;
padding: 1px 1px 0px 1px;
font-size: 11px;
}
a.ContextMenuItem
{
margin: 1px 0 1px 0;
display: block;
color: #003399;
text-decoration: none;
cursor: pointer;
padding: 4px 19px 4px 33px;
white-space: nowrap;
}
a.ContextMenuItem-Selected
{
font-weight: bold;
}
a.ContextMenuItem:hover
{
background-color: #FFE6A0;
color: #003399;
border: 1px solid #D2B47A;
padding: 3px 18px 3px 32px;
}
يک وب سايت از نوع ASP.NET Ajax-Enabled WebSite ايجاد نموده و به نماي Source View برويد.
قطعه کد زير را اضافه نماييد.

<asp:Label ID="TextLabel" runat="server" Text="DropDownExtender Example in 30sharp.com" Width="259px" />
<asp:Panel ID="DropPanel" runat="server" CssClass="ContextMenuPanel" Style="display :none; visibility: hidden;" >
<asp:LinkButton runat="server" ID="Option1" Text="Option 1" CssClass="ContextMenuItem" OnClick="OnSelect" />
<asp:LinkButton runat="server" ID="Option2" Text="Option 2" CssClass="ContextMenuItem" OnClick="OnSelect" />
<asp:LinkButton runat="server" ID="Option3" Text="Option 3" CssClass="ContextMenuItem" OnClick="OnSelect" />
</asp:Panel>
<cc1:DropDownExtender runat="server" ID="DDE"
TargetControlID="TextLabel"
DropDownControlID="DropPanel" />
همانطور که مشاهده مي نماييد ما يک Label به نام TextLabel ايجاد نموده و متن آن را DropDownExtender Example in 30sharp.com قرار داده ايم. سپس يک Panel به نام DropPanel ايجاد نموده ايم که وظيفه آن نگهداري گزينه ها مي باشد.
همانطور که قبلا ذکر شد، هر يک از گزينه ها در حقيقت يک LinkButton مي باشند. در رويداد کليک هر LinkButton نام تابع OnSelect نوشته شده است. اين تابع را ما در Code Behind صفحه خواهيم نوشت که وظيفه آن مشخص کردن اين است که کدام گزينه انتخاب شده است. اين تابع را در ادامه مقاله مورد بررسي قرار خواهم داد.
سپس کنترل DropDownExtender را به صفحه اضافه نموده ايم. اين کنترل داراي صفات زيادي مي باشد که ما از دو تا از مهمترين آن ها استفاده نموده ايم که عبارتند از :


TargetControlID : اين صفت شناسه کنترلي را نگهداري مي کند که نقش کنترل DropDown را ايفا مي کند. که در اينجا ما TextLabel را به آن نسبت داده ايم.
DropDownControlID : اين صفت شناسه کنترلي که گزينه هاي DropDown را در خود نگهداري مي کند، را مشخص مي کند که در اين مثال DropPanel مي باشد.

خوب. اکنون زمان بررسي عملکرد اين کنترل مي باشد.
براي انجام اين کار نياز داريم که قطعه کد زير را به صفحه اضافه نماييم.

<asp:UpdatePanel id="Update" runat="server" >
<ContentTemplate>
<asp:Label id="lblSelection" runat="server" Style="padding: 5px; " />
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="Option1" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="Option2" EventName="Click" />
<asp:AsyncPostBackTrigger ControlID="Option3" EventName="Click" />
</Triggers>
</asp:UpdatePanel>در قطعه کد بالا يک Label به نام lblSelection در داخل يک UpdatePanel تعريف نموده ايم که ما متن گزينه انتخاب شده در DropDownExtender را در اين Label نشان خواهيم داد.
عملکرد تگ AsyncPostBackTrigger را قبلا در مقاله اي (http://www.30sharp.com/ShowArticle.aspx?nid=10&did=39&AuthorID=1) توضيح داده ام ولي جهت يادآوري بايد عرض کنم که با توجه به اينکه LinkButton هايي که ما به عنوان گزينه هاي DropDown استفاده نموده ايم در خارج از UpdatePanel قرار دارند و ما تمايل داريم که با کليک شدن آن ها ، بدون انجام PostBack، کنترل lblSelection به روز رساني شود، پس نياز داريم که با استفاده از تگ AsyncPostBackTrigger، اين LinkButton ها را به UpdatePanel معرفي نماييم.
حال نوبت به اين مي رسد که ببينيم کار تابع OnSelect که با کليک شدن هر يک از گزينه ها (LinkButton ها) فراخواني مي شود چيست.

protected void OnSelect(object sender, EventArgs e)
{
lblSelection.Text = "You selected <b>" + ((LinkButton)sender).Text + "</b>.";
}
عملکرد قطعه کد فوق کاملا مشخص مي باشد. با کليک شدن هر يک از گزينه ها، متن آن گزينه به کنترل lblSelection نسبت داده مي شود و در حقيقت ما در اين تابع به تمام خصوصيات گزينه کليک شده دسترسي داريم.
تمام اين اعمال بدون انجام شدن عمل PostBack ، صورت مي گيرد.

moji5
18th December 2009, 04:09 AM
مقدمه :

UpdatePanelAnimationExtender يکي از کنترل هاي پيشرفته موجود در AjaxControlToolkit مي باشد که براي به وجود آوردن جلوه هاي انيميشني در صفحه استفاده مي شود. مثلا شما مي توانيد کنترلي در صفحه داشته باشيد که هنگام آپديت شدن آن، يک جلوه انيميشني اطراف آن به وجود آيد تا کاربر متوجه تغييرات اعمال شده روي کنترل گردد.
دموي زنده اين مقاله را مي توانيد اينجا (http://www.30sharp.com/Contents/91/upae.aspx) مشاهده نماييد.
هشدار :
قبل از شروع مثال بايد عرض کنم در صورتي که شما در ASP.NET Ajax مبتدي مي باشيد، پيشنهاد مي کنم قبل از فراگيري اين مقاله،حتما مقالات قبلي اينجانب را در رابطه با ASP.NET AJAX مطالعه نماييد تا از اين مقاله بهره کافي را ببريد.
شروع :

قبل از اينکه به معرفي جزييات کنترل UpdatePanelAnimationExtender بپردازم، کمي در مورد کاري که قرار است انجام دهيم، توضيح مي دهم.
http://www.30sharp.com/Contents/91/upae1.gif در اين مثال ما يک کنترل Div به نام divContainer داريم که در داخل آن يک UpdatePanel به نام update قرار دارد و در داخل UpdatePanel يک کنترل Label به نام lblUpdate قرار دارد.
در خارج از کنترل divContainer ، يک کنترل Button به نام btnUpdate قرار دارد که هنگام کليک شدن آن، محتواي lblUpdate بروز رساني شده و تاريخ و زمان کليک شدن دکمه btnUpdate را نشان مي دهد.
قطعه کد زير، مطالب بيان شده در بالا را نشان مي دهد

<div id="divContainer" style="background-color: white; width: 300px;">
<asp:UpdatePanel ID="update" runat="server">
<ContentTemplate>
<asp:Label ID="lblUpdate" runat="server" Style="padding: 5px; font-size: 14px; font-weight: bold;color: Black;">
4/28/1906 12:00:00 AM
</asp:Label>
</ContentTemplate>
<Triggers>
<asp:AsyncPostBackTrigger ControlID="btnUpdate" EventName="Click" />
</Triggers>
</asp:UpdatePanel>
</div>
و قطعه کد زير هنگام کليک شدن btnUpdate اجرا مي شود.

protected void btnUpdate_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(2000);
lblUpdate.Text = DateTime.Now.ToString();
}
همانطور که مشاهده مي نماييد، ما در هنگام کليک شدن btnUpdate ، به مدت 2 ثانيه تاخير ايجاد نموده ايم زيرا در غير اين صورت محتواي lblUpdate خيلي سريع بروز رساني شده و نمي توانيم جلوه انيميشني را مشاهده نماييم.
در اين مقاله مي خواهيم 3 جلوه انيميشني مختلف يعني جلوه Fade و جلوه Collapse/Expand و جلوه تغيير رنگ پس زمينه را اعمال نماييم.
3 کنترل Checkbox در صفحه داريم که مشخص مي کنند چه جلوه هايي را مي خواهيم هنگام بروز رساني اعمال نماييم.
قطعه کد مربوط به Checkbox ها را مشاهده مي نماييد.

<input type="checkbox" id="effect_fade" checked="checked" />Fade<br />
<input type="checkbox" id="effect_collapse" checked="checked" />Collapse<br />
<input type="checkbox" id="effect_color" checked="checked" />Color Background<br />
با کليک شدن دکمه btnUpdate ، هر يک از Checkbox ها که انتخاب شده باشند، جلوه انيميشني آن اعمال مي شود.
جلوه هاي انيميشني که ما مي خواهيم در زمان بروز رساني ايجاد نماييم به 2 دوره زماني تقسيم مي شوند.


هنگامي که کنترل در حال بروز رساني مي باشد (OnUpdating)
پس از اينکه عمل بروز رساني به پايان رسيد(OnUpdated)

پس از انجام دادن اعمال فوق، اکنون زمان استفاده از کنترل UpdatePanelAnimationExtender مي باشد.
يک کنترل UpdatePanelAnimationExtender به صفحه اضافه نماييد و محتواي آن را به شکل زير تغيير دهيد.

<ajaxToolkit:UpdatePanelAnimationExtender ID="upae" BehaviorID="animation" runat="server"
TargetControlID="update">
<Animations>
<OnUpdating>
<Sequence>
<%-- Store the original height of the panel --%>
<ScriptAction Script="var b = $find('animation'); b._originalHeight = b._element.offsetHeight;" />

<%-- Disable all the controls --%>
<Parallel duration="0">
<EnableAction AnimationTarget="btnUpdate" Enabled="false" />
<EnableAction AnimationTarget="effect_color" Enabled="false" />
<EnableAction AnimationTarget="effect_collapse" Enabled="false" />
<EnableAction AnimationTarget="effect_fade" Enabled="false" />
</Parallel>
<StyleAction Attribute="overflow" Value="hidden" />

<%-- Do each of the selected effects --%>
<Parallel duration=".25" Fps="30">
<Condition ConditionScript="$get('effect_fade').checked">
<FadeOut AnimationTarget="divContainer" minimumOpacity=".2" />
</Condition>
<Condition ConditionScript="$get('effect_collapse').checked">
<Resize Height="0" />
</Condition>
<Condition ConditionScript="$get('effect_color').checked">
<Color AnimationTarget="divContainer" PropertyKey="backgroundColor"
EndValue="#FFFF00" StartValue="#FFFFFF" />
</Condition>
</Parallel>
</Sequence>
</OnUpdating>
</Animations>
</ajaxToolkit:UpdatePanelAnimationExtender>
هم اکنون به معرفي عناصر استفاده شده در قطعه کد فوق مي پردازم.
در قطه کد فوق UpdatePanelAnimationExtender داراي دو صفت جالب به نام هاي BehaviorID و TargetControlID مي باشد.
ما توسط صفت ID در سمت سرور مي توانيم به کنترل دسترسي داشته باشيم ولي در سمت کلاينت، توسط صفت BehaviorID و با استفاده از جاوا اسکريپت مي توانيم به کنترل دسترسي داشته باشيم.
صفت TargetControlID ، شناسه UpdatePanel را نگهداري مي کند که قرار است جلوه انيميشني به آن اعمال شود.
اعمالي را که مي خواهيم هنگام بروز رساني کنترل صورت گيرد، در داخل تگ <OnUpdating> قرار مي گيرد.
با توجه به اينکه هنگام بروز رساني قصد داريم divContainer را به شکل Collapse در آوريم، پس بايد اندازه اصلي آن را جايي ذخيره کنيم تا پس از انجام عمل بروز رساني (OnUpdated) بتوانيم آن را به اندازه اصلي خود Expand نماييم. اين عمل توسط تگ ScriptAction انجام مي گيرد.
همانطور که در قطعه کد زير مي بينيد، اندازه کنترل divContainer را در صفت originalHeight_ مربوط به UpdatePanelAnimationExtender ذخيره شده است.

<%-- Store the original height of the panel --%>
<ScriptAction Script="var b = $find('animation'); b._originalHeight = b._element.offsetHeight;" />
اعمالي را که مي خواهيم روي کنترل ها در هنگام بروز رساني اعمال شود را بايد داخل تگ Parallel قرار دهيم. اين تگ داراي دو صفت مهم مي باشد


duration : مدت زماني (بر حسب ثانيه) را که قصد داريم جلوه انميشني مورد نظر به کنترل اعمال شود. مقدار اين صفت به طور پيشفرض 1 ثانيه مي باشد.
Fps : سرعت انجام جلوه انيميشني بر حسب فريم بر ثانيه (Frames Per Seconds)

با توجه به اينکه قصد داريم در هنگام انجام عمل بروز رساني، کنترل هاي Checkbox و Button را غير فعال نماييم، از قطعه کد زير استفاده مي کنيم.

<%-- Disable all the controls --%>
<Parallel duration="0">
<EnableAction AnimationTarget="btnUpdate" Enabled="false" />
<EnableAction AnimationTarget="effect_color" Enabled="false" />
<EnableAction AnimationTarget="effect_collapse" Enabled="false" />
<EnableAction AnimationTarget="effect_fade" Enabled="false" />
</Parallel>
صفت AnimationTarget ، شناسه کنترلي را که قرار است آن را فعال يا غير فعال و غيره را انجام دهيم را نگهداري مي کند.
اکنون زمان اعمال جلوه هاي انيميشني به کنترل مورد نظرمان يعني UpdatePanel مي رسد.
به قطعه کد زير توجه نماييد.

<%-- Do each of the selected effects --%>
<Parallel duration=".25" Fps="30">
<Condition ConditionScript="$get('effect_fade').checked">
<FadeOut AnimationTarget="divContainer" minimumOpacity=".2" />
</Condition>
<Condition ConditionScript="$get('effect_collapse').checked">
<Resize Height="0" />
</Condition>
<Condition ConditionScript="$get('effect_color').checked">
<Color AnimationTarget="divContainer" PropertyKey="backgroundColor"
EndValue="#FFFF00" StartValue="#FFFFFF" />
</Condition>
</Parallel>
قطعه کد فوق داراي 3 تگ Condition مي باشد. با استفاده از تگ Condition مي توانيم شرايط مسئله را بررسي نماييم. مثلا ما اينجا مي خواهيم در صورتي جلوه انيميشني را اعمال نماييم که Checkbox مربوط به آن انتخاب شده باشد.
در اولين تگ Condition ما Checkbox مربوط به جلوه انيميشني FadeOut را بررسي کرده ايم که اگر انتخاب شده بود، جلوه انيميشني را اعمال مي نماييم. اين بررسي در صفت ConditionScript صورت گرفته است.

<Condition ConditionScript="$get('effect_fade').checked">
<FadeOut AnimationTarget="divContainer" minimumOpacity=".2" />
</Condition>
در دومين تگ Condition ما Checkbox مربوط به جلوه انيميشني Collapse را بررسي کرده ايم که اگر انتخاب شده بود، جلوه انيميشني را اعمال نماييم. همانطور که مي بينيد با استفاده از تگ Resize مقدار ارتفاع کنترل، را صفر اختصاص داده ايم.

<Condition ConditionScript="$get('effect_collapse').checked">
<Resize Height="0" />
</Condition>
در سومين تگ Condition ما Checkbox مربوط به جلوه انيميشني تغيير رنگ پس زمينه را بررسي کرده ايم که اگر انتخاب شده بود، جلوه انيميشني را اعمال نماييم.بدين منظور از تگ Color استفاده نموده ايم.
صفت PropertyKey ، نام صفتي را که قرار است براي آن رنگ تعيين شود را نگهداري مي کند. اگر کمي دقت کنيد، متوجه مي شويد که تغيير رنگي که ما علاقه مند هستيم انجام گيرد، بايد از محدوده يک رنگ خاص شروع و تا محدوده رنگ ديگر دامه يابد.
صفت StartValue نام رنگ آغازين را نگهداري مي کند و صفت EndValue نام رنگ نهايي را.
دقت داشته باشيد که نام رنگ ها بايد به صورت هگزا دسيمال باشد.

<Condition ConditionScript="$get('effect_color').checked">
<Color AnimationTarget="divContainer" PropertyKey="backgroundColor" EndValue="#FFFF00" StartValue="#FFFFFF" />
</Condition>
خوب، تا کنون اعمالي را که بايد هنگام بروز رساني (OnUpdating) انجام شود را مشخص کرده ايم و اکنون زمان آن رسيده است، اعمالي را که پس از انجام بروز رساني (OnUpdated) بايد انجام شود را مشخص نماييم که شامل برگشت به حالت اوليه کنترل ها و فعال شدن مجدد دکمه هاي غير فعال شده مي باشد.
به قطعه کد زير توجه نماييد.

<OnUpdated>
<Sequence>
<%-- Do each of the selected effects --%>
<Parallel duration=".25" Fps="30">
<Condition ConditionScript="$get('effect_fade').checked">
<FadeIn AnimationTarget="divContainer" minimumOpacity=".2" />
</Condition>
<Condition ConditionScript="$get('effect_collapse').checked">
<%-- Get the stored height --%>
<Resize HeightScript="$find('animation')._originalHeight" />
</Condition>
<Condition ConditionScript="$get('effect_color').checked">
<Color AnimationTarget="divContainer" PropertyKey="backgroundColor"
EndValue="#FFFFFF" StartValue="#FFFF00" />
</Condition>
</Parallel>

<%-- Enable all the controls --%>
<Parallel duration="0">
<EnableAction AnimationTarget="effect_fade" Enabled="true" />
<EnableAction AnimationTarget="effect_collapse" Enabled="true" />
<EnableAction AnimationTarget="effect_color" Enabled="true" />
<EnableAction AnimationTarget="btnUpdate" Enabled="true" />
</Parallel>
</Sequence>
</OnUpdated>
قطعه کد فوق کاملا گويا مي باشد.
نکته جالب در تگ Condition دوم مي باشد که به صورت Bold مشاهده مي نماييد. در اين تگ با استفاده از صفت HeightScript ، اندازه UpdatePanelAnimationExtender را به مقدار اول خود که در صفت originalHeight_ ذخيره کرده بوديم بر مي گردانيم.

moji5
18th December 2009, 04:10 AM
اين مقاله را با يک مثال آغاز مي کنم. يک کنترل UpdatePanel به صفحه اضافه کنيد وسپس داخل UpdatePanel ، يک Button و يک Label اضافه نماييد.
در نتيجه شکل زير را مشاهده مي نماييد. (البته من مقداري Style هم به صفحه اضافه کرده ام)
http://www.30sharp.com/Contents/102/UpdateProgress.gif در رويداد کليک مربوط به کنترل Button قطعه کد زير را بنويسيد.

protected void Button1_Click(object sender, EventArgs e)
{
System.Threading.Thread.Sleep(3000);
Label1.Text = DateTime.Now.ToString();
}
همانطور که ملاحظه مي کنيد، با کليک شدن Button، ابتدا 3 ثانيه تاخير به وجود آورده ايم و سپس تاريخ و زمان را در کنترل Label چاپ کرده ايم.
وقتي يک کاربر عادي ، روي Button کليک مي کند، مشاهده مي نمايد که به مدت 3 ثانيه هيچ اتفاق خاصي نمي افتد و سپس تاريخ نمايش داده مي شود.
در برنامه هاي کاربردي، بسيار پيش مي آيد که عمليات سمت سرور مقداري زمان بر، مي باشد. مثلا قرار است اطلاعات از ديتابيس خوانده شود و يا اعمال ديگر.
براي کاربراني که به Postback شدن صفحات عادت داشته اند، اين موضوع چندان خوش آيند نمي باشد و امکان دارد که پس از کليک کردن Button، هنگامي که مشاهده کردند پس از طي چند ثانيه اتفاق خاصي نيفتاده است، مجددا Button را کليک کنند (در حاليکه در حال حاضر اطلاعات در سمت سرور درحال پردازش مي باشد)
پس نياز است هنگامي که هنگامي که اطلاعات در سمت سرور در حال پردازش مي باشد، به نحوي اين موضوع را به کاربر نشان دهيم.
بدين منظور از کنترل UpdateProgress استفاده مي شود.
اکنون قصد داريم که در مدت زماني که اطلاعات در سمت سرور در حال پردازش مي باشند، يک تصوير Loading به شکل زير را به کاربر نمايش دهيم.
http://www.30sharp.com/Contents/102/Loading.gif کنترل UpdateProgress را به صفحه اضافه کنيد. به نماي Markup رفته و کد آن را به شکل زير تغيير دهيد.

<asp:UpdateProgress ID="UpdateProgress1" runat="server">
<ProgressTemplate>
<img src="25-1.gif" />
Updating Page ......
</ProgressTemplate>
</asp:UpdateProgress>
مشاهده مي نماييد که کنترل UpdateProgress داراي تگي به نام ProgressTemplate مي باشد که در داخل اين تگ، محتوايي که قرار است هنگام انجام پردازش اطلاعات سمت سرور به کاربر نمايش دهيم، قرار مي گيرد.
ما در اينجا يک تصوير Loading به همراه عبارت Updating page را قرار است به کاربر نمايش دهيم.
خوب، کار تمام است. صفحه را اجرا کنيد و نتيجه کار را مشاهده نماييد.
موفق باشيد.

moji5
18th December 2009, 04:12 AM
کنترل Timer جهت انجام يک سري اعمال در فواصل زماني مشخص، استفاده مي شود. در حقيقت با استفاده از اين کنترل مي توانيم يک تابع را در سمت سرور، در فواصل زماني مشخص، از سمت کلاينت فراخواني نماييم.
فرض کنيد که يک کنترل Label داريم که قرار است هر 3 ثانيه بروز رساني شود و تاريخ و زمان بروز رساني خود را نمايش دهد.
عملکرد اين کنترل را مي توانيد اينجا (http://www.30sharp.com/contents/107/TimerSample.aspx) مشاهده نماييد.
به قطعه کد زير توجه نماييد.
<asp:UpdatePanel ID="UpdatePanel1" runat="server">
<ContentTemplate>
<asp:Timer ID="Timer1" runat="server" Interval="3000" OnTick="Timer1_Tick" />
<asp:Label ID="Label1" runat="server" Font-Names="Tahoma" ForeColor="Red" ></asp:Label>
</ContentTemplate>
</asp:UpdatePanel>
همانطور که ملاحظه مي نماييد، داخل اين صفحه ما يک UpdatePanel داريم که کنترل Timer و Label در داخل آن قرار دارند.
صفت Interval، فاصله زماني را که پس ازآن، کنترل Timer عمل خواهد کرد را نگهداري مي کند. در اينجا ما مدت زمان 3000 ميلي ثانيه يا در حقيقت 3 ثانيه را به آن نسبت داده ايم.
پس از گذشت هر 3 ثانيه، رويداد OnTick اتفاق مي افتد و تابع Timer1_Tick فراخواني مي شود.
قطعه کد زير عملکرد تابع ، Timer1_Tick را نشان مي دهد.

protected void Timer1_Tick(object sender, EventArgs e)
{
Label1.Text = DateTime.Now.ToString();
}
در هنگام استفاده از کنترل Timer بايد دقت داشته باشيد که اگر به هر دليلي مانند قطع اينترنت يا ترافيک بالاي شبکه و غيره، فراخواني تابع Timer1_Tick با مشکل مواجه شود، در سمت کاربر يک خطاي استثنا (Exception) به وجود مي آيد و به طور متناوب به کاربر اين خطا به شکل صفحه ديالوگ، نمايش داده مي شود. لذا بايد براي کنترل خطاهاي به وجود آمده چاره اي بينديشيد که از حوزه بحث اين مقاله خارج مي باشد.
کنترل Timer داراي انعطاف پذيري زيادي نمي باشد و در نتيجه هنگام استفاده از اين کنترل در پروژه هاي کاربردي و حساس خود بايد کليه جوانب کار را بررسي نماييد.
کنترل عملکرد Timer در سمت کلاينت با استفاده از جاوااسکريپت :

عملکرد کنترل Timer را در سمت کلاينت مي توان با استفاده از جاوااسکريپت تغيير داد.
ابتدا بايد يک ارجاع به کنترل Timer در صفحه ايجاد کنيد. در قطعه کد زير اين مسئله را مشاهده مي نماييد.

var myTimer = $find('<%= Timer1.ClientID %>');اکنون به سادگي با استفاده از myTimer مي توانيد رفتار کنترل Timer را تغيير دهيد.

//returns the Timer’s interval in milliseconds:
var waitTime = myTimer.get_interval;
//sets the Timer’s interval to 5000 milliseconds (or 5 seconds):
myTimer.set_interval(5000);
//returns whether or not the Timer is enabled:
var isTimerEnabled = myTimer.get_enabled();
//disables the Timer:
myTimer.set_enabled(false);
//starts the Timer:
myTimer._startTimer();
//stops the Timer:
myTimer._stopTimer();

moji5
18th December 2009, 04:16 AM
مقدمه :

کنترل MutuallyExclusiveCheckBoxExtender يکي از ساده ترين کنترل هاي موجود در AjaxControlToolkit مي باشد.
همانطور که مي دانيد، يکي از راه هايي که مي توان به کاربر امکان انتخاب يک گزينه از ميان چندين گزينه را داد، استفاده ازدکمه هاي راديويي (Radio Buttons) مي باشد. دکمه هاي راديويي هنگامي که صفحه براي اولين بار بارگذاري مي شود، مي توانند انتخاب نشده باشند يعني هيچ گزينه اي از ميان گزينه ها انتخاب نشده باشد.
ولي پس از اينکه يکي از گزينه ها انتخاب شود ديگر امکان عدم انتخاب آن وجود ندارد و حتما بايد يکي از گزينه ها، انتخاب شده باقي بماند. اگر بتوان اين موضوع را يکي از محدوديت هاي مربوط به دکمه هاي راديويي دانست پس کنترل MutuallyExclusiveCheckBoxExtender براي رفع اين مشکل به وجود آمده است.
کنترل MutuallyExclusiveCheckBoxExtender همان طور که از نامش پيداست، يک Extender مي باشد و خود به تنهايي داراي شکل فيزيکي نمي باشد.
عملکرد اين کنترل از اينجا (http://30sharp.com/Contents/122/MECE.aspx) قابل مشاهده مي باشد.
شروع :

در اين مقاله قصد داريم صفحه اي ايجاد کنيم که چند عدد CheckBox در آن وجود داشته باشد و امکان انتخاب فقط يکي از آن ها در هر لحظه امکان پذير باشد.
http://www.30sharp.com/Contents/122/MECE.gif به قطعه کد زير توجه فرماييد.

<asp:CheckBox ID="CheckBox1" runat="server" Text="CheckBox1" />
<ajaxToolkit:MutuallyExclusiveCheckBoxExtender ID="Mutually1" runat="server"
TargetControlID="CheckBox1" Key="MyKey" />
<br />
<asp:CheckBox ID="CheckBox2" runat="server" Text="CheckBox2" />
<ajaxToolkit:MutuallyExclusiveCheckBoxExtender ID="Mutually2" runat="server"
TargetControlID="CheckBox2" Key="MyKey" />
<br />
<asp:CheckBox ID="CheckBox3" runat="server" Text="CheckBox3" />
<ajaxToolkit:MutuallyExclusiveCheckBoxExtender ID="Mutually3" runat="server"
TargetControlID="CheckBox3" Key="MyKey" />
<br />
<asp:CheckBox ID="CheckBox4" runat="server" Text="CheckBox4" />
<ajaxToolkit:MutuallyExclusiveCheckBoxExtender ID="Mutually4" runat="server"
TargetControlID="CheckBox4" Key="MyKey" />
همانطور که از قطعه کد بالا مشخص مي باشد، هر کنترل MutuallyExclusiveCheckBoxExtender به يک کنترل CheckBox اعمال مي شود و به ازاي هر يک CheckBox که قصد داريم در يک گروه قرار بگيرد(يعني يکي از گزينه هاي اين گروه را بتوان انتخاب نمود)، بايد يک کنترل MutuallyExclusiveCheckBoxExtender نيز به صفحه اضافه نمود.
در مثال بالا ما چهار عدد CheckBox داريم که قصد داريم به کاربر اين امکان را بدهيم تا فقط يکي از گزينه ها را انتخاب نمايد. ضمنا کاربر پس از انتخاب يکي از گزينه ها مي تواند از اين کار منصرف شده و گزينه انتخاب شده را از حالت انتخاب خارج سازد.
کنترل MutuallyExclusiveCheckBoxExtender داراي دو صفت مهم مي باشد که به معرفي آن ها مي پردازم.
TargetControlID : همانطور که از نام اين صفت مشخص مي باشد، اين صفت ID ي کنترل CheckBox ي را که قصد داريم اين کنترل به آن اعمال شود را نگهداري مي کند.
Key : براي اينکه بتوانيم چند عدد CheckBox را در يک گروه قرار دهيم، يعني فقط امکان انتخاب يکي از CheckBox هاي موجود در گروه را بدهيم، بايد يک نام به اين گروه نسبت دهيم. در اين صورت عملکرد MutuallyExclusiveCheckBoxExtender فقط به CheckBox هايي که داراي نام گروه مشابه هستند اعمال مي شود و به ساير CheckBox هاي موجود در صفحه اعمال نمي شود. صفت Key نام گروه را مشخص نگهداري مي کند. چهار کنترل MutuallyExclusiveCheckBoxExtender ي که در مثال بالا ما استفاده نموده ايم داراي صفت Key مي باشند که مقدار تمام آنها MyKey است. در حقيقت نام گروه MyKey مي باشد.

moji5
18th December 2009, 04:21 AM
مقدمه :

معرفی این کنترل را با یک مثال آغاز می کنم. فرض کنید شما از یک فروشگاه کامپیوتری، یک قطعه سخت افزاری مانند کیبورد خریداری کرده اید و اکنون قصد دارید به وب سایت شرکت سازنده کیبور مراجعه و محصول خود را ثبت نموده و درایور آن رو دانلود کنید.
فرض کنید که شرکت سازنده کیبورد، محصولات دیگری را نیز مانند مانیتور، اسپیکر، ماوس و غیره در مدل های مختلف تولید می کند.
در نتیجه در سایت شرکت سازنده، شما باید ابتدا نوع محصول (برای شما کیبورد) و سپس مدل آن و در نهایت رنگ محصول را انتخاب نمایید تا محصول مورد نظر خود را ثبت نموده یا درایور مربوط به آن را دانلود نمایید.
شرکت سازنده محصول نیز قصد دارد که بهترین و راحت ترین روش را برای ثبت کردن محصولات خود به کاربران ارایه دهد.
یکی از بهترین و موثرترین روش های موجود استفاده از کنترل CascadingDropDown (و یا روش های مشابه) می باشد.
اگر به وب سایت شرکت فراسو (http://www.farassoo.com/driver.htm) مراجعه نمایید، خواهید دید که این شرکت نیز از این تکنیک استفاده نموده است.
http://www.30sharp.com/Contents/128/06.gif در این مقاله من قصد داریم که این تکنیک را با استفاده از CascadingDropDown پیاده سازی کنیم.
همانطور که از نام کامل CascadingDropDownExtender مشخص می باشد، این کنترل یک Extender می باشد .
Extender ها در حقیقت یک کنترل مستقل نمی باشند ولی توانایی این را دارد که قابلیت هایی را به کنترل های موجود در ASP.NET بیفزایند.
CascadingDropDown نیز از این قاعده مستثنا نمی باشد و می تواند قابلیت هایی را به کنترل DropDown اضافه نماید.
در این مقاله قصد داریم مثالی را که ذکر شد، پیاده سازی کنیم.
در صفحه محصولات شرکت 3 عدد کنترل DropDown موجود می باشد که اولین کنترل لیست محصولات شرکت را نگهداری می کند. هنگامی که محصول مورد نظر انتخاب شد، کنترل DropDown پایینی از مدل های محصول انتخاب شده پر می شود.
و در نهایت هنگامی که مدل محصول نیز توسط کاربر انتخاب شد، DropDown پایینی آن، رنگ های مربوط به مدل انتخاب شده را نمایش می دهد. و بدین ترتیب کاربر می تواند در کمترین زمان و با بیشترین سهولت محصول مورد نظر خود را انتخاب نموده و سایر اعمال مورد نظر خود را انجام دهد.
شروع :

ابتدا بانک اطلاعاتی مربوط به محصولات را ایجاد خواهیم کرد. بانک اطلاعاتی ما شامل سه جدول می باشد.
جدول اول، نام و مشخصات انواع محصولات را نگهداری می کند (Products).
http://www.30sharp.com/Contents/128/Products.gif جدول دوم، مدل های مربوط به محصولات را نگهداری می کند (ProductModels).
http://www.30sharp.com/Contents/128/Models.gif جدول سوم، رنگ های مدل های محصولات را نگهداری می کند(ModelColors).
http://www.30sharp.com/Contents/128/Colors.gif قبل از اینکه به تشریح مثال بپردازم ، ابتدا یک نگاه سطح بالا به نحوه انجام کار خواهم داشت .
اگر بخواهیم بدون استفاده از تکنیک های AJAX به پیاده سازی تکنیک فوق بپردازیم، سناریوی انجام کار به شکل زیر می باشد.


ابتدا اولین DropDown هنگام لود صفحه پر می شود که شامل نام محصولات تولید شده توسط شرکت می باشد. (این عمل با استفاده از یک دستور Select روی جدول Products انجام می شود)
کاربر از اولین DropDown، محصول مورد نظر خود را انتخاب می کند. پس از اینکه نام محصول مورد نظر کاربر انتخاب شد، یک دستور Select روی جدول حاوی مدل ها (ProductModels) اجرا می شود و DropDown دوم از لیست مدل های مربوط به محصول انتخاب شده، پر می شود.
کاربر از دومین DropDown ، مدل مربوط به محصول خود را انتخاب می کند و سپس یک دستور Select روی جدول حاوی رنگ ها (ModelColors) با توجه به مدل انتخاب شده زده می شود و DropDown سوم از رنگ های موجود پر می شود.
کاربر از سومین DropDown ، رنگ محصول خریداری شده توسط خود را انتخاب می کند و کار تمام است.

در CascadingDropDown نیز این مراحل اتفاق می افتد و فقط نحوه انجام کار تفاوت دارد که در ادامه مقاله به بررسی آن می پردازم.
اکنون به پیاده سازی تکنیک فوق می پردازم.
سه عدد کنترل DropDown به صفحه اضافه نموده و شکل ظاهری آن ها را مرتب می کنیم.
http://www.30sharp.com/Contents/128/01.gif اولین کنترل DropDown ، مشخصات محصولات را نگهداری می کند. دومین کنترل مشخصات مدل های محصول انتخاب شده و سومین کنترل، مشخصات رنگ مدل انتخاب شده را نگهداری می کند.
قطعه کد مربوط به DropDown به شکل زیر می باشد.

<asp:DropDownList ID="ddlProducts" runat="server" Width="240px" />
<asp:DropDownList ID="ddlModels" runat="server" Width="240px" />
<asp:DropDownList ID="ddlColors" runat="server" Width="240px" />
خوب، اکنون نوبت به اضافه کرده کنترل های CascadingDropDown می باشد. با توجه به اینکه ما سه عدد DropDown در صفحه داریم که قرار است تکنیک را روی آن ها اجرا کنیم، باید سه عدد CascadingDropDown به صفحه اضافه کنیم.
اولین CascadingDropDown را به صفحه اضافه نموده و به شکل زیر تغییر می دهیم.

<ajaxToolkit:CascadingDropDown ID="cddProducts"
runat="server"
TargetControlID="ddlProducts"
Category="Product"
PromptText="Choose a Product ...."
LoadingText="Please wait ..."
ServicePath="ProductsService.asmx"
ServiceMethod="GetProducts">
</ajaxToolkit:CascadingDropDown>
این کنترل CascadingDropDown مربوط به ddlProducts می باشد.
اکنون به معرفی صفات مهم CascadingDropDown می پردازم.
TargetControlID : نام کنترل DropDown هدف را که قرار است قابلیت های این CascadingDropDown به آن اعمال شود را نگهداری می کند ( در اینجا ddlProducts) .
Category: کاربرد این صفت را در ادامه مقاله خواهیم دید. هنگام فراخوانی متدی که عملیات بازیابی اطلاعات از بانک اطلاعاتی را انجام می دهد، مقدار این صفت به عنوان یکی از پارامتر ها ارسال می شود.
PromptText : قبل از اینکه کنترل های DropDown با داده های مربوط به خود پر شوند، متن این صفت در آن ها نمایش داده می شود.
LoadingText : با توجه به اینکه بازیابی اطلاعات از بانک اطلاعاتی، عملی زمانبر می باشد، در این مدت زمان، متنی که در این صفت وارد نموده ایم در DropDown مربوطه نمایش داده می شود.
ServicePath : با توجه به اینکه ما قصد داریم از سمت کلاینت، متدهای مربوط به پر کردن DropDown ها را فراخوانی کنیم، یک وب سرویس به نام ProductsService ایجاد نموده ایم که در ادامه برنامه بیشتر مورد بررسی قرار خواهد گرفت. این صفت مسیر مربوط به وب سرویس را نگهداری می کند.
ServiceMethod : این صفت نام متدی را که قرار است از وب سرویس مذکور فراخوانی شود را نگهداری می کند.
اکنون CascadingDropDown های مربوط به DropDown های دوم و سوم را اضافه می کنیم.

<ajaxToolkit:CascadingDropDown ID="cddModels"
runat="server"
TargetControlID="ddlModels"
ParentControlID="ddlProducts"
Category="Model"
PromptText="Choose a Product Model...."
LoadingText="Please wait ..."
ServicePath="ProductsService.asmx"
ServiceMethod="GetModels">
</ajaxToolkit:CascadingDropDown>
<ajaxToolkit:CascadingDropDown ID="cddColors"
runat="server"
TargetControlID="ddlColors"
ParentControlID="ddlModels"
Category="Color"
PromptText="Choose a Color...."
LoadingText="Please wait ..."
ServicePath="ProductsService.asmx"
ServiceMethod="GetColors">
</ajaxToolkit:CascadingDropDown>
همانطور که ملاحظه می کنید، این CascadingDropDown ها دارای یک صفت جدید می باشند که در کنترل CascadingDropDown قبلی که به صفحه اضافه کردیم، وجود نداشت.
ParentControlID : همانطور که قبلا ذکر شد، DropDown پایینی، با توجه به مقداری که در DropDown بالایی انتخاب شده است پر می شود. در نتیجه DropDown بالایی والد DropDown پایینی محسوب می شود. در حقیقت شما با مقدار دادن به این صفت مشخص می کنید که مقادیر این DropDown باید وابسته به کدام DropDown باشند. به طور مثال مقادیر ddlModels وابسته به مقدار انتخاب شده از ddlProducts توسط کاربر می باشد.
خوب، حالا نوبت به ایجاد یک وب سرویس و پیاده سازی متدهای مربوطه می باشد.
یک وب سرویس به نام ProductsService به پروژه اضافه می کنیم.
نکته :

برای اینکه به وب سرویس این امکان را بدهیم تا از سمت کلاینت فراخوانی شود، باید یک Attribute به نام [System.Web.Script.Services.ScriptService] را مطابق شکل زیر به ابتدای کلاس اضافه کنیم.
http://www.30sharp.com/Contents/128/07.gif هنگامی که صفحه برای اولین بار لود می شود، اولین DropDown باید با لیست نام محصولات پر شود.

public CascadingDropDownNameValue[] GetProducts(string knownCategoryValues, string category)
{
string Query = "SELECT ProductId,ProductName FROM Products";
List<CascadingDropDownNameValue> values = new List<CascadingDropDownNameValue>();
using (SqlConnection con = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand(Query, con);
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
string productName = (string)dr["ProductName"];
int productId = (int)dr["ProductID"];
values.Add(new CascadingDropDownNameValue(productName, productId.ToString()));
}
}
return values.ToArray();
}
}
قبلا از اینکه به تشریح عملکرد قطعه کد بالا بپردازم، ذکر چند نکته را ضروری می دانم.


هر کدام از CascadingDropDown ها هنگام فراخوانی متد مربوط به خود، دو پارامتر را به متد ارسال می کنند. پارامتر اول را ما knownCategoryValues نام نهادیم که شامل اطلاعاتی در مورد گزینه انتخاب شده از DropDown مربوطه می باشد. همانطور که در ابتدای مقاله ذکر کردم، در اینجا نیز باید دستور Select مناسب روی بانک اطلاعاتی اجرا شود که مشخصات آن توسط این پارامتر ارسال می شود. پارامتر دوم همان Category می باشد که قبلا هم از آن یاد کردیم، و مشخص می کند که DropDown انتخاب شده، مربوط به کدام Category می باشد.
مقدار برگشتی این متد، شامل آرایه ای از اشیاء CascadingDropDownNameValue می باشد که کنترل DropDown مربوطه به آن بایند می شود.
چون CascadingDropDown مربوط به این DropDown دارای ParentControlID نمی باشد، این کنترل پس از لود صفحه پر می شود و اگر دارای این صفت بود، تنها پس از اینکه مقدار والد آن توسط کاربر انتخاب می شد، این DropDown پر می شد(یعنی متد GetProducts فراخوانی می شد).

قطعه کد بالا دارای نکته خاص دیگری نمی باشد، به جز اینکه ما یک لیست از نوع CascadingDropDownNameValue اینجا نموده ایم و آن را با اطلاعات جدول Products پر کرده ایم و در نهایت لیست پر شده را به شکل آرایه برگردانده ایم.
ما از پارامتر های ارسال شده به این متد استفاده نکرده ایم.
مقدار پارامتر knownCategoryValues خالی می باشد. زیرا این متد پس از لود صفحه فراخوانی می شود و مقداری از DropDown هنوز انتخاب نشده است و دارای والدی هم نیست که مشخصات گزینه انتخاب شده والد، در آن نگهداری شده باشد.
پارامتر category نیز حاوی نام طبقه بندی DropDown که در نمای Markup مشخص نمودیم یعنی "Product" می باشد.
اکنون به قطعه کد زیر توجه فرمایید. این متد هنگام انتخاب یک گزینه از گزینه های ddlProducts فراخوانی می شود.

[WebMethod]
public CascadingDropDownNameValue[] GetModels(string knownCategoryValues, string category)
{
StringDictionary kv = CascadingDropDown.ParseKnownCategoryValuesString(k nownCategoryValues);
int productId = int.Parse(kv["Product"]);
string Query = "SELECT ModelId, ProductId, ModelName FROM ProductModels WHERE ProductId = @ProductId";
List<CascadingDropDownNameValue> values = new List<CascadingDropDownNameValue>();
using (SqlConnection con = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand(Query, con);
cmd.Parameters.AddWithValue("@ProductId", productId);
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{

values.Add(new CascadingDropDownNameValue((string)dr["ModelName"], dr["ModelID"].ToString()));
}
}
return values.ToArray();
}
}
در قطعه کد بالا، پارامتر knownCategoryValues دارای مقدار می باشد و مشخصات گزینه انتخاب شده از ddlProducts را نگهداری می کند. اکنون باید با توجه به محصول انتخاب شده، مشخصات مدل های مربوط به آن را به ddlProductModels بایند کنیم و نیاز داریم که شناسه (ProductId) محصول انتخاب شده را جهت استفاده در دستور Select در دسترس داشته باشیم.
کلاس CascadingDropDown دارای متدی به نام ParseKnownCategoryValuesString می باشد که مشخصات ذخیره شده در پارامتر knownCategoryValues را برای استفاده راحت تر، به شکل StringDictionary بر می گرداند.
نکته بسیار مهم :

در طول مقاله بعضی از کاربردهای صفت Category را که در CascadingDropDown مقدار دهی کردیم، ذکر کردم. یکی از کاربردهای دیگر این صفت این است که با استفاده از آن در قطعه کد بالا شناسه محصول انتخاب شده (در حقیقت ddlProducts.SelectedValue) را با استفاده از نام طبقه بندی cddProducts یعنی عبارت "Product" بدست آورده ایم و در عبارت Select از آن استفاده نموده ایم.

int productId = int.Parse(kv["Product"]);
اکنون نوبت به متد آخر، یعنی GetColors می رسد.

[WebMethod]
public CascadingDropDownNameValue[] GetColors(string knownCategoryValues, string category)
{
StringDictionary kv = CascadingDropDown.ParseKnownCategoryValuesString(k nownCategoryValues);
int modelId = int.Parse(kv["Model"]);
string Query = "SELECT ColorId, ColorName FROM ModelColors WHERE (ModelId = @ModelId)";
List<CascadingDropDownNameValue> values = new List<CascadingDropDownNameValue>();
using (SqlConnection con = new SqlConnection(connectionString))
{
SqlCommand cmd = new SqlCommand(Query, con);
cmd.Parameters.AddWithValue("@ModelId", modelId);
con.Open();
SqlDataReader dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
values.Add(new CascadingDropDownNameValue((string)dr["ColorName"], dr["ColorID"].ToString()));
}
}
return values.ToArray();
}
}
عملکرد قطعه کد فوق نیز کاملا مشخص می باشد. این متد هنگامی فرخوانی می شود که مقداری از ddlProductModels انتخاب شود و در نتیجه متد یعنی لیست رنگ های مربوط به مدل انتخاب شده به کنترل ddlModelColors بایند می شود.
نکاتی مربوط به راندمان و امنیت :

همواره در مقالات خود سعی می کنم که آموزشی بودن و کاربردی بودن مقالات را در کنار هم در نظر بگیرم. ولی گاهی اوقات توجه زیاد به کاربردی بودن مقاله، ایجاد پیچیدگی هایی می کند که قسمت آموزشی بودن آن را تحت الشعاع قرار می دهد. لذا مخاطبین محترم هنگام استفاده از مطالب این مقاله و سایر مقالات در پروژه های کاربردی خود لطفا همه موارد مربوط به امنیت و راندمان و مدیریت خطا و غیره را نیز در نظر بگیرند.
برای سایت هایی با ترافیک بالا، بهتر است اطلاعات Cache شوند و بازیابی اطلاعات از Cache صورت گیرد. در غیر اینصورت، این ایده چندان جالب نمی باشد که با تغییر هر گزینه یک Query روی بانک اطلاعاتی اجرا شود.
بهتر است از StoredProcedure جهت بازیابی اطلاعات از بانک اطلاعاتی استفاده شود.
خوب، این مقاله نیز به پایان رسید و شما می توانید این تکنیک ارزشمند را در پروژه های خود پیاده سازی کنید.
http://www.30sharp.com/Contents/128/05.gif قطعه کد کامل این مقاله از لینک بالای صفحه قابل دریافت می باشد.
ولی یک سوپرایز هم برای علاقه مندان پر و پا قرص Pure Ajax دارم.
در قطعه کد پایین بدون استفاده از کنترل CascadingDropDownExtender ، این تکنیک شبیه سازی شده است.
ولی نیمی از راه رو باید خودتان طی کنید (نوشتن متدهای وب سرویس و غیره)
نکته :

مقداری برگشتی از متدهای وب سرویس در این حالت IEnumerable در نظر گرفته شده است. مانند الگوی زیر :

[WebMethod]
public IEnumerable<Product> GetProducts() {
// Implementation
}
[WebMethod]
public IEnumerable<Model> GetModels(int modeId)
{
// Implementation
}
قطعه کد مربوط به صفحه اصلی نیز به شکل زیر می باشد.

<%@ Page Language="C#" %>
<html xmlns="http://www.w3.org/1999/xhtml">
<head id="Head1" runat="server">
<title>www.30sharp.com</title>
<script type="text/javascript">
var ddlProducts;
var ddlModel;
function pageLoad()
{
ddlProducts = $get("ddlProducts");
ddlModel = $get("ddlModel");

$addHandler(ddlProducts, "change", changeModel);
ProductsService.GetProducts(makeSuccess);
}
function makeSuccess(data)
{
BindDropDown(ddlProducts, data);
changeModel();
}
function changeModel()
{
ProductsService.GetModels(ddlProducts.value, modelSuccess);
}
function modelSuccess(data)
{
BindDropDown(ddlModel, data);
}

function BindDropDown(ddl, data)
{
ddl.options.length = 0;
var newOption;
for (var k=0;k < data.length; k ++)
{
newOption = new Option( data[k].Name, data[k].Id );
ddl.options.add( newOption );
}
}

</script>
</head>
<body>
<form id="form1" runat="server">
<div>
<asp:ScriptManager ID="ScriptManager1" runat="server">
<Services>
<asp:ServiceReference Path="~/ProductsService.asmx" />
</Services>
</asp:ScriptManager>

<label for="ddlProducts">Product:</label>
<select id="ddlProducts"></select>

<br /><br />

<label for="ddlModel">Model:</label>
<select id="ddlModel"></select>


</div>
</form>
</body>
</html>

moji5
18th December 2009, 04:22 AM
مقدمه :

کنترل AlwaysVisibleControlExtender، یکی از کنترل های ساده و در عین حال جالب موجود در AjaxControlToolkit می باشد.
همانطور که از نام این کنترل مشخص است، این کنترل از نوع کنترل های توسعه دهنده (Extender) می باشد. یعنی خود دارای شکل فیزیکی نبوده ولی می تواند به کنترل های استاندارد موجود در ASP.NET خواصی را اضافه کند.
حتما تاکنون در برخی سایت ها و بخصوص تالارهای گفتمان(Forums) با این صحنه روبرو شده اید که تا قبل از اینکه در سایت ثبت نام کنید یا در حقیقت لاگین کرده باشید، پیغامی همواره به شما نمایش داده می شود، مبنی بر اینکه برای استفاده از تمامی امکانات سایت باید عضو سایت شده باشید. واین پیغام در صفحه در محل بخصوصی نمایش داده می شود و به هنگام اسکرول کردن در صفحه، همواره در محل خود باقی می ماند.
به طور مثال پیغامی شبیه به شکل زیر تا زمانی که در سایت لاگین نکرده باشید همواره در قسمت بالا و سمت چپ صفحه نمایش داده می شود و اگر در صفحه به سمت پایین یا بالا اسکرول کنید، می بینید که پیغام مربوطه موقعیت خود را حفظ می کند.
http://www.30sharp.com/Contents/147/avse1.gif کاربرد کنترل AlwaysVisibleControlExtender نیز در حقیقت ایجاد اینگونه پیام ها می باشد. بدیهی می باشد که این پیام ها می توانند دارای عکس و لینک و سایر عناصر HTML باشند.
پیش نمایش :

برای درک بهتر این موضوع می توانید به اینجا (http://www.30sharp.com/Contents/147/avce.aspx) مراجعه کنید و با اسکرول نمودن در صفحه، عملکرد کنترل را مشاهده نمایید.
شروع :

خوب، برای شروع فرض می کنیم که یک کنترل Panel در صفحه داریم و قصد داریم که محتویات این Panel همواره در قسمت بالا و سمت چپ صفحه نمایش داده شود و هنگامی که کاربر در حال اسکرول نمودن صفحه می باشد، محتویات این Panel نیز موقعیت خود را حفظ نموده و همواره به کاربر نمایش داده شوند.
قطعه کد مربوط به Panel به شکل زیر می باشد.

<asp:Panel ID="pnlAlwaysVisible" runat="server">
شما عضو نیستید، برای دسترسی کامل به سایت لطفا ثبت نام نمایید
</asp:Panel>
اکنون زمان اضافه کردن کنترل AlwaysVisibleControlExtender به صفحه فرا رسیده است. کنترل مربوطه را به صفحه اضافه نموده و به شکل زیر تغییر می دهیم.

<cc1:AlwaysVisibleControlExtender ID="AlwaysVisibleControlExtender1" runat="server"
TargetControlID="pnlAlwaysVisible"
VerticalSide="Top"
VerticalOffset="15"
HorizontalSide="Left"
ScrollEffectDuration=".2"
HorizontalOffset="25">
</cc1:AlwaysVisibleControlExtender>

اکنون به معرفی برخی خصوصیات مهم کنترل AlwaysVisibleControlExtender می پردازم.



TargetControlID : همانند سایر کنترل های توسعه دهنده (Extender) موجود در مجموعه AjaxControlToolkit، این خصوصیت شناسه کنترلی را که قرار است ویژگی های AlwaysVisibleControlExtender به آن اعمال شود را نگهداری می کند. در مثال ما این شناسه مربوط به کنترل Panel ی است که قبلا به صفحه اضافه نموده ایم (pnlAlwaysVisible)

VerticalSide : این صفت همانطور که از نام آن مشخص می باشد، مکان مورد نظر ما را در قسمت عمودی صفحه نگهداری می کند. مقادیر مجاز آن یکی از سه مورد Top ، Middle ، Bottom می باشد. با توجه به اینکه ما در این مثال می خواهیم محتویات Panel در قسمت بالا و سمت چپ صفحه نمایش داده شود، مقدار عمودی Top را به آن نسبت داده ایم. اگر می خواستیم که محتویات Panel در وسط صفحه نمایش داده شود باید مقدار Middle و برای نمایش در پایین صفحه باید مقدار Bottom را به آن نسبت می دادیم.

HorizontalSide : این صفت مشابه صفت VerticalSide می باشد. با این تفاوت که این صفت مکان مورد نظر نمایش محتویات Panel را نسبت به افق (Horizontal) نگهداری می کند. مقادیر مجاز آن Left، Center ، Right می باشند. با توجه به اینکه ما می خواهیم محتویات Panel در قسمت بالا و سمت چپ صفحه نمایش داده شود، مقدار Left را به آن نسبت داده ایم.

HorizontalOffset : در صورتی که بخواهیم کنترل پنل در هنگام نمایش به میزان معینی از لبه کناری (افقی) صفحه فاصله داشته باشد باید مقداری را بر حسب پیکسل به این صفت نسبت دهیم. در این مثال ما مقداد 25 را نسبت داده ایم پس این کنترل همواره به میزان 25 پیکسل از لبه سمت چپ صفحه فاصله خواهد داشت.

VerticalOffset : این صفت نیز مشابه صفت HorizontalOffset می باشد با این تفاوت که این صفت فاصله کنترل Panel را با لبه عمودی صفحه نگهداری می کند (بالا یا پایین). در این مثال ما مقدار 15 را به آن نسبت داده ایم پس به میزان 15 پیکسل از لبه بالایی صفحه فاصله خواهد داشت.

ScrollEffectDuration : هنگامی که کاربر در حال اسکرول در صفحه می باشد، مدت زمانی طول می کشد که پنل مورد نظر ما در موقعیت قبلی خود قرار بگیرد. این مدت زمان را برحسب ثانیه می توانید به صفت نسبت دهید. (برای امتحان می توانید به پیش نمایش صفحه در بالا مراجعه کنید و عملکرد آن را مشاهده نمایید)

تذکر :

هنگام استفاده از این کنترل دقت کافی را لحاظ کنید زیرا استفاده نادرست و نابجا از این کنترل می تواند باعث ایجاد دردسر و رنجش بازدید کننده سایت گردد.

moji5
18th December 2009, 04:27 AM
مقدمه :

اگر به تازگی در سایت گوگل کلمه رایجی را جستجو کرده باشید، باید با صحنه ای مشابه شکل زیر مواجه شده باشید.
http://www.30sharp.com/Contents/149/auto.gif در حقیقت سایت گوگل با توجه به کاراکتر هایی که شما برای جستجو وارد نموده اید، لیستی از پیشنهاد ها را ارائه می کند. این لیست شامل کلماتی می باشد که توسط تعداد زیادی از کاربران مورد جستجو واقع شده اند.
در صورتی که کلمه و یا جمله مورد نظر شما در لیست پیشنهادات باشد، شما می توانید آن را از لیست پیشنهادات انتخاب نمایید.
کنترل AutoCompleteExtender جهت به وجود آوردن نمونه ساده تری از تکنیک ذکر شده در بالا مورد استفاده قرار می گیرد. این کنترل نیز جزو ساده ترین کنترل های موجود در AjaxControlToolkit می باشد.
کنترل AutoCompleteExtender همانطور که از نام آن پیداست جزو کنترل های توسعه گر (Extender) می باشد و قابلیت های خود را می تواند به یک کنترل TextBox اضافه نماید.
دموی برنامه:

برای نمایش دموی برنامه به اینجا (http://30sharp.com/contents/149/auto.aspx) مراجعه نمایید.
شروع :

یک کنترل TextBox به صفحه اضافه کنید و مطابق قطعه کد زیر تغییر دهید.

<asp:TextBox ID="myTextBox" runat="server" Width="363px"></asp:TextBox>
یک کنترل AutoCompleteExtender به صفحه اضافه نموده و مطابق زیر آن را تغییر دهید.

<ajaxToolkit:AutoCompleteExtender runat="server"
ID="autoComplete1"
TargetControlID="myTextBox"
ServicePath="AutoCompleteService.asmx"
ServiceMethod="GetCompletionList"
MinimumPrefixLength="2"
EnableCaching="true"
CompletionSetCount="10" >
</ajaxToolkit:AutoCompleteExtender>

اکنون به معرفی برخی صفات مهم کنترل AutoCompleteExtender می پردازم.



TargetControlID : همانند سایر کنترل های موجود در مجموعه AjaxControlToolkit ، این صفت نام کنترلی را که قرار است خصوصیات آن توسعه پیدا کند (در اینجا myTextBox) نگهداری می کند.

ServicePath : با توجه به اینکه ما قصد داریم زمانی که کاربر کلمه ای را در کنترل myTextBox تایپ می کند یک متد را از طریق وب سرویس فراخوانی کنیم، این صفت مسیر وب سرویس مورد نظر را نگهداری می کند. (در ادامه مقاله، وب سرویس مورد نظر را مشاهده خواهید نمود)

ServiceMethod : این صفت نام متدی از وب سرویس را که قصد فراخوانی آن را داریم، نگهداری می کند.

MinimumPrefixLength : این صفت مشخص می کند که کاربر حداقل باید چه تعداد کاراکتر را تایپ کند تا لیست پیشنهاد را به او نمایش دهیم. همانطور که ملاحظه می نمایید، در قطعه کد بالا ما عدد 2 را به این صفت نسبت داده ایم. در نتیجه از زمانی که کاربر 2 کاراکتر را تایپ نماید، نمایش لیست پیشنهادها آغاز می شود.

EnableCaching : در صورتی که مقدار این صفت برابر true باشد، پس از نمایش لیست پیشنهادات به کاربر، این لیست در حافظه پنهان (cache) مرورگر کاربر ذخیره می شود و اگر کاربر کاراکترهای مورد نظر خود را مجددا تایپ نماید(تکراری)، لیست پیشنهادات از حافظه پنهان مرورگر استخراج می شود (به جای اینکه متد وب سرویس مجددا فراخوانی شود)

CompletionSetCount : این صفت حداکثر تعداد پیشنهاداتی را که می توان به کاربر نمایش داده را نگهداری می کند. به طور مثال اگر مقدار آن برابر 10 باشد، حداکثر تعداد گزینه هایی که به کاربر نمایش داده می شود 10 عدد می باشد.

تذکر:

با توجه به اینکه در حال حاضر بسیاری از توسعه گران ایرانی از VS 2005 استفاده می کنند، مقالات مربوط به AJAX را معمولا سازگار با VS 2005 یعنی توسط ASP.NET AJAX 1.0 انجام می دهم. ولی در صورتی که شما از ورژن VS 2008 استفاده می کنید، بهتر است بدانید که چند صفت جدید به این کنترل اضافه شده است که امکان استفاده از CSS جهت بهبود ظاهر این کنترل را اینجاد نموده است.
اکنون زمان این است به وب سرویس مورد نظر خود را ایجاد کنیم.
یک وب سرویس به نام AutoCompleteService ایجاد نمایید و متد GetCompletionList را به شکل زیر به آن اضافه نمایید.



[System.Web.Script.Services.ScriptService]
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
public class AutoCompleteService : System.Web.Services.WebService
{
[WebMethod]
public string[] GetCompletionList(string prefixText, int count)
{
Random random = new Random();
List<string> items = new List<string>(count);
for (int i = 0; i < count; i++)
{
char c1 = (char)random.Next(65, 90);
char c2 = (char)random.Next(97, 122);
char c3 = (char)random.Next(97, 122);
items.Add(prefixText + c1 + c2 + c3);
}
return items.ToArray();
}
}
متد GetCompletionList توسط کنترل AutoCompleteExtender فراخوانی می شود.
همانطور که ملاحظه می نمایید این متد دو پارامتر دارد. پارامتر اول کلمه ای است که کاربر در داخل کنترل TextBox تایپ نموده است و پارامتر دوم، حداکثر تعداد پیشنهاداتی است که می تواند به کاربر نمایش داده شود.
با توجه به اینکه ما در این مقاله قصد داریم به طور آزمایشی تعدادی پیشنهاد را نمایش دهیم، یک حلقه for ایجاد نموده ایم و داخل آن به اندازه حداکثر تعداد پیشنهاداتی که باید به کاربر نمایش داده شود، دیتای آزمایشی تولید نموده ایم و لیست پیشنهادات را به صورت آرایه ای از string ها برگردانده ایم.
ولی در پروژه های کاربردی شما باید با توجه به کاراکتر هایی که کاربر وارد نموده است، لیست پیشنهادات خود را نمایش دهید.
خوب کار تمام است و اکنون شما می توانید برنامه را اجرا نموده و عملکرد کنترل را مورد بررسی قرار دهید.

moji5
18th December 2009, 04:27 AM
مقدمه :

کنترل MutuallyExclusiveCheckBoxExtender يکي از ساده ترين کنترل هاي موجود در AjaxControlToolkit مي باشد.
همانطور که مي دانيد، يکي از راه هايي که مي توان به کاربر امکان انتخاب يک گزينه از ميان چندين گزينه را داد، استفاده ازدکمه هاي راديويي (Radio Buttons) مي باشد. دکمه هاي راديويي هنگامي که صفحه براي اولين بار بارگذاري مي شود، مي توانند انتخاب نشده باشند يعني هيچ گزينه اي از ميان گزينه ها انتخاب نشده باشد.
ولي پس از اينکه يکي از گزينه ها انتخاب شود ديگر امکان عدم انتخاب آن وجود ندارد و حتما بايد يکي از گزينه ها، انتخاب شده باقي بماند. اگر بتوان اين موضوع را يکي از محدوديت هاي مربوط به دکمه هاي راديويي دانست پس کنترل MutuallyExclusiveCheckBoxExtender براي رفع اين مشکل به وجود آمده است.
کنترل MutuallyExclusiveCheckBoxExtender همان طور که از نامش پيداست، يک Extender مي باشد و خود به تنهايي داراي شکل فيزيکي نمي باشد.
عملکرد اين کنترل از اينجا (http://30sharp.com/Contents/122/MECE.aspx) قابل مشاهده مي باشد.
شروع :

در اين مقاله قصد داريم صفحه اي ايجاد کنيم که چند عدد CheckBox در آن وجود داشته باشد و امکان انتخاب فقط يکي از آن ها در هر لحظه امکان پذير باشد.
http://www.30sharp.com/Contents/122/MECE.gif به قطعه کد زير توجه فرماييد.

<asp:CheckBox ID="CheckBox1" runat="server" Text="CheckBox1" />
<ajaxToolkit:MutuallyExclusiveCheckBoxExtender ID="Mutually1" runat="server"
TargetControlID="CheckBox1" Key="MyKey" />
<br />
<asp:CheckBox ID="CheckBox2" runat="server" Text="CheckBox2" />
<ajaxToolkit:MutuallyExclusiveCheckBoxExtender ID="Mutually2" runat="server"
TargetControlID="CheckBox2" Key="MyKey" />
<br />
<asp:CheckBox ID="CheckBox3" runat="server" Text="CheckBox3" />
<ajaxToolkit:MutuallyExclusiveCheckBoxExtender ID="Mutually3" runat="server"
TargetControlID="CheckBox3" Key="MyKey" />
<br />
<asp:CheckBox ID="CheckBox4" runat="server" Text="CheckBox4" />
<ajaxToolkit:MutuallyExclusiveCheckBoxExtender ID="Mutually4" runat="server"
TargetControlID="CheckBox4" Key="MyKey" />
همانطور که از قطعه کد بالا مشخص مي باشد، هر کنترل MutuallyExclusiveCheckBoxExtender به يک کنترل CheckBox اعمال مي شود و به ازاي هر يک CheckBox که قصد داريم در يک گروه قرار بگيرد(يعني يکي از گزينه هاي اين گروه را بتوان انتخاب نمود)، بايد يک کنترل MutuallyExclusiveCheckBoxExtender نيز به صفحه اضافه نمود.
در مثال بالا ما چهار عدد CheckBox داريم که قصد داريم به کاربر اين امکان را بدهيم تا فقط يکي از گزينه ها را انتخاب نمايد. ضمنا کاربر پس از انتخاب يکي از گزينه ها مي تواند از اين کار منصرف شده و گزينه انتخاب شده را از حالت انتخاب خارج سازد.
کنترل MutuallyExclusiveCheckBoxExtender داراي دو صفت مهم مي باشد که به معرفي آن ها مي پردازم.
TargetControlID : همانطور که از نام اين صفت مشخص مي باشد، اين صفت ID ي کنترل CheckBox ي را که قصد داريم اين کنترل به آن اعمال شود را نگهداري مي کند.
Key : براي اينکه بتوانيم چند عدد CheckBox را در يک گروه قرار دهيم، يعني فقط امکان انتخاب يکي از CheckBox هاي موجود در گروه را بدهيم، بايد يک نام به اين گروه نسبت دهيم. در اين صورت عملکرد MutuallyExclusiveCheckBoxExtender فقط به CheckBox هايي که داراي نام گروه مشابه هستند اعمال مي شود و به ساير CheckBox هاي موجود در صفحه اعمال نمي شود. صفت Key نام گروه را مشخص نگهداري مي کند. چهار کنترل MutuallyExclusiveCheckBoxExtender ي که در مثال بالا ما استفاده نموده ايم داراي صفت Key مي باشند که مقدار تمام آنها MyKey است. در حقيقت نام گروه MyKey مي باشد.

moji5
18th December 2009, 04:32 AM
مقدمه :


یکی از مواردی که در چند ماه اخیر توسط بازدید کنندگان سایت 30sharp به طور مکرر عنوان شده است، سنگین شدن صفحات و پایین آمدن سرعت لود و کارایی صفحات، هنگام استفاده از ASP.NET AJAX می باشد.
قبل از اینکه این مقاله را آغاز کنم، لازم می دانم که به یاد آوری چند مطلب بپردازم. همیشه وقتی قرار باشد که یک تکنولوژی پیچیده، مورد استفاده همگان قرار گیرد، باید یک سری پارامتر ها را فدای ایجاد سهولت و سادگی نمود.
اصولا برنامه نویسی AJAX با هر کتابخانه ای (.... & Anthem & ASP.NET AJAX & Ajax Pro) اگر قرار باشد به بهترین نحو خود انجام شود، کار ساده ای نیست و نیازمند در نظر گرفتن مسایل بسیار زیادی از جمله امنیت، کارایی، سرعت، سازگار بودن با مرورگرهای مشهور، زیبایی وغیره می باشد. که باید با توجه به شرایط موجود، استراتژی مشخصی را اتخاذ کرد.
این موضوع نیازمند آن است که برنامه نویس تسلط نسبی بر کتابخانه ای که در حال استفاده از آن است داشته باشد. پس نمی توان راه حل واحدی را جهت رفع تمام مشکلات ارایه داد.
ولی در این بین، راه حل هایی کلی نیز وجود دارند که رعایت آنها باعث می شود که کارایی صفحات به طور چشمگیری افزایش یابد و سرعت لود صفحات چندین برابر گردد. در این مقاله به معرفی این نکات می پردازم.
آغاز :

ScriptManager و UpdatePanel دو تا از کنترل های بسیار مهم ASP.NET AJAX می باشند.
ScriptManager :

ScriptManager در حقیقت مغز متفکر کتابخانه ASP.NET AJAX می باشد. در صفحاتی که قرار است از ASP.NET AJAX استفاده شود، حتما باید یک کنترل ScriptManager در صفحه وجود داشته باشد. این کنترل با توجه به امکاناتی که از ASP.NET AJAX در صفحه استفاده شده است، اسکریپت های مورد نیاز برای انجام درست کارها از اسمبلی System.Web.Extensions.dll استخراج نموده و به صفحه اضافه می نماید.
کنترل ScriptManager دارای دو صفت مهم می باشد که در کارایی صفحات وب نقش بسیار مهمی دارند.


ScriptMode
LoadScriptsBeforeUI

هسته اصلی کتاب خانه ASP.NET AJAX یک فایل جاوا اسکریپت می باشد به نام MicrosoftAjax.js که در اسمبلی System.Web.Extensions.dll تعبیه شده است.
این فایل دارای دو نسخه می باشد به نام های MicrosoftAjax.js وMicrosoftAJAX.debug.js.
نسخه MicrosoftAJAX.debug.js بسیار سنگین تر از MicrosoftAjax.js می باشد و دارای مقدار کدهای زیادی جهت اعتبارسنجی و کامنت ها و غیره می باشد و مخصوص استفاده در زمان برنامه نویسی می باشد و امکاناتی جهت دیباگ نمودن و رفع مشکلات برنامه نویسی را دارا می باشد.
مثلا در نسخه MicrosoftAJAX.debug.js داخل متدهای این کتابخانه قطعه کدهایی نوشته شده است که نوع (Type) پارامترهایی را که به متد ارسال شده است را بررسی می کند و در صورتی که نوع مناسبی نباشد، خطای مشخصی را ایجاد می نماید و برنامه نویس متوجه اشتباه خود می گردد. ولی پس این که برنامه نوشته و به اندازه کافی آزمایش شد و نوبت به فاز Deployment رسید، دیگر نیاز نیست از این فایل استفاده شود.
نسخه MicrosoftAjax.js شامل قطعه کدهای مورد نیاز جهت دیباگ برنامه نیست و در نتیجه بسیار سبک تر می باشد. هنگامی که قرار است وب سایت به طور رسمی مورد استفاده قرار گیرد باید از این نسخه استفاده شود.
وظیفه خصوصیت ScriptMode در کنترل ScriptManager دقیقا همین است و با استفاده از این خصوصیت می توانیم مشخص کنیم که از کدام نسخه استفاده شود.
مقدار پیشفرض این خصوصیت Auto می باشد. وقتی مقدار آن Auto باشد، کنترل ScriptManager با توجه به نوع Deployment تصمیم می گیرد که از کدام نسخه استفاده نماید.
اگر وب سایت به صورت Release مورد Deploy واقع شده باشد، کترل ScriptManager از نسخه MicrosoftAjax.js استفاده می کند و اگر به صورت Debug مورد Deploy واقع شده باشد از نسخه MicrosoftAJAX.debug.js.
خصوصیت ScriptMode می تواند دو مقدار دیگر را نیز بپذیرد که با استفاده از آنها می توانیم به طور صریح به ScriptManager اعلام کنیم که از کدام نسخه استفاده نماید. اگر مقدار Release را به این خصوصیت نسبت دهیم، صرف نظر از هر چیزی، کنترل ScriptManager از نسخه MicrosoftAjax.js استفاده می نماید و اگر مقدار Debug را به آن نسبت دهیم صرف نظر از هر چیزی، کنترل ScriptManager از نسخه MicrosoftAJAX.debug.js. استفاده می نماید.
پیشنهاد می کنم که اگر وب سایت شما از لحاظ اسکریپتی دچار مشکل نیست، حتما مقدار ScriptManager =Release را برای این کنترل انتخاب نمایید. این موضوع به میزان زیادی در کارایی صفحات نقش دارد.

<asp:ScriptManager ID="ScriptManager1" ScriptMode="Release" ></asp:ScriptManager>
ضمنا به یاد داشته باشید که پس از اولین باری که صفحه لود شود، اسکریپت های لود شده، در حافظه مرورگر Cache می شوند.
خصوصیت مهم دیگری که به بررسی آن می پردازم، LoadScriptsBeforeUI می باشد.
شاید بدترین مشکلی که در مورد استفاده از جاوا اسکریپت در صفحات وب وجود داشته باشد، زمان لود فایل های جاوا اسکریپت می باشد. هنگام لود فایل های جاوا اسکریپت در حقیقت لود سایر عناصر صفحه متوقف می شود و در صورتی که این اسکریپت ها در ابتدای صفحه قرار داشته باشند، بازدید کنندگان سایت با صفحه ای سفید روبرو می شوند و تا زمان لود کامل اسکریپت ها این قضیه ادامه دارد. و پس از لود اسکریپت ها ، سایر عناصر HTML از قبلی متن ها و عکس ها شروع به لود شدن می کنند.
این مشکل در ASP.NET AJAX به این علت به وجود می آید که به طور پیشفرض، اسکریپت ها و منابع مورد نیاز ASP.NET و ASP.NET AJAX و AjaxControlToolkit و سایر Extender ها دقیقا پس از شروع تگ form قرار می گیرند و درنتیجه ابتدا کلیه این اسکریپت ها و منابع باید لود شوند تا نوبت به سایر عناصر صفحه برسد.
شکل زیر بیانگر این مطلب می باشد.
http://www.30sharp.com/Contents/151/Scripts.png همانطور که در تصویر بالا ملاحظه می کنید، بسیار از اسکریپت ها دقیقا بعد از تگ form لود خواهند شد و همان مشکلی که در بالا ذکر شد، به وجود می آید.
راه حل این مشکل لود اسکریپت ها بعد از لود سایر عناصر صفحه می باشد و بهترین مکان برای اینکار، دقیقا قبل از بسته شده تگ body در انتهای صفحه می باشد.
البته با توجه به سیاست های سایت و بسیاری از عوامل دیگر، شاید شما نیاز داشته باشید که یک اسکریپت حتما در ابتدای صفحه لود شود (به همین دلیل در ابتدای مقاله ذکر کردم که با توجه به بسیاری از عوامل باید تصمیم گرفت!)
ولی در غالب موارد این موضوع مشکل خاصی به وجود نمی آورد و با انتقال اسکریپت ها به انتهای صفحه می توانید راندامان و سرعت لود صفحه را چندین برابر بالا ببریم.
تذکر :





برخی اسکریپت ها (بخصوص اسکریت های مربوط به کنترل های AjaxControlToolkit) جهت ارسال کنترل های صفحه به مکان های مناسب خود استفاده می شوند و به همین دلیل باید در ابتدای صفحه لود شوند. در غیر اینصورت تا زمانی که صفحه به طور کامل لود نشده است، کنترل مورد نظر در محل مناسب خود قرار نمی گیرد. به طور مثال کنترل AlwaysVisibleControlExtender (http://www.30sharp.com/ShowArticle.aspx?nid=10&did=147&AuthorID=1) از اینگونه کنترل ها می باشد. به این دلیل توصیه می شود که مکان (position) ابتدایی این کنترل ها را در صفحه به طور صریح به شکل Relative یا absolute مشخص کنید.

در مورد اسکریپت هایی که خود نیز قصد داریم به شکل یک فایل خارجی (مثلا Sample.js) به صفحه اضافه کنیم ، نیز بهتر است در انتهای صفحه قرار بگیرند.

کنترل ScriptManager دارای صفتی به نام LoadScriptsBeforeUI می باشد که مقدار پیشفرض آن true می باشد. همانطور که از نام این صفت پیداست ، هنگامی که مقدار آن true باشد، اغلب اسکریپت های مربوط به ASP.NET AJAX را در ابتدای صفحه لود می کند. برای اینکه این اسکرپت ها را به انتهای صفحه انتقال دهیم باید مقدار این صفت را false کنیم.

<asp:ScriptManager ID="ScriptManager1" ScriptMode="Release" LoadScriptsBeforeUI="false" />
با انجام این کار مقداری از اسکریپت ها به انتهای صفحه منتقل می شوند ولی متاسفانه بسیاری از اسکریپت ها همچنان در ابتدای صفحه باقی می مانند.
دلیل این امر این است که این اسکرپت ها توسط Page.ClientScript.RegisterClientScriptBlock رجیستر شده اند. کلاس Page داخل فضای نامی System.Web می باشد و دارای متدی به نام BeginFormRender می باشد. در داخل این متد، Client Script Block ها رندر می شوند. و این متد اسکریپت هایی را که رندر می کند، دقیقا بعد از تگ form در ابتدا صفحه قرار می دهد.
در شکل زیر شمای کلی این متد را ملاحظه می نمایید.

internal void BeginFormRender(HtmlTextWriter writer, string formUniqueID)

{

...

this.ClientScript.RenderHiddenFields(writer);

this.RenderViewStateFields(writer);

...

if (this.ClientSupportsJavaScript)

{

...

if (this._fRequirePostBackScript)

{

this.RenderPostBackScript(writer, formUniqueID);

}

if (this._fRequireWebFormsScript)

{

this.RenderWebFormsScript(writer);

}

}

this.ClientScript.RenderClientScriptBlocks(writer) ;

}


همانطور که ملاحظه می کنید این متد به شکل internal تعریف شده و قابل override شدن نیز نمی باشد. پس چگونه می توان این مشکل را حل نمود؟
راه حل این موضوع خارج از محدوده این مقاله می باشد ولی در صورتی که علاقه مند می باشید، می توانید یک مقاله عالی در این زمینه از آقای Omar Al Zabir (http://www.codeproject.com/KB/aspnet/fastload.aspx) را مطالعه کنید.
UpdatePanel:

صحبتی که در ابتدای مقاله در مورد آسان نمودن تکنولوژی های پیچیده نمودم، در مورد کنترل UpdatePanel کاملا صادق می باشد. عملکرد پشت صحنه این کنترل بسیار پیچیده می باشد ولی نحوه استفاده از آن بسیار آسان.
قبل از اینکه به بررسی نکات موجود در مورد UpdatePanel بپردازم، مختصری در مورد نحوه عملکرد آن صحبت می کنم.
هنگامی که یکی از کنترل های موجود در UpdatePanel درخواست Postback می کند یا به عبارت بهتری UpdatePanel را تریگر (Trigger) می کند، UpdatePanel محتوای خود را آپدیت می کند. بدین شکل که ابتدا محتوای کل ViewState صفحه را به سمت سرور ارسال می کند و پس از اینکه عملیات در سمت سرور به پایان رسید، مقدار ViewState جدید کل صفحه را به همراه محتویات جدید خود دریافت می کند.
با توجه به اینکه معمولا در صفحات وب، حجم عظیمی از ViewState تولید می شود، پس ارسال و دریافت این مقدار اطلاعات می تواند چیزی شبیه فاجعه به بار بیاورد.
به این دلیل پیشنهاد می شود که به UpdatePanel به عنوان آخرین راه حل نگاه کنید و نه اولین!
برای اطلاع بیشتر پیشنهاد می کنم این (http://www.30sharp.com/ShowArticle.aspx?nid=10&did=93&AuthorID=1) مقاله کوتاه و با ارزش را نیز مطالعه نمایید.
ولی سهولت بالای استفاده از این کنترل، عدم استفاده از آن را غیر ممکن نموده است و بنده در اینجا به معرفی برخی روش ها جهت بالا بردن راندمان آن می پردازم.
اولین موردی که باید بررسی شود، خصوصیت UpdateMode می باشد.
اگر چند UpdatePanel در صفحه داشته باشیم، هنگامی که محتوای یکی از آنها آپدیت می شود، به طور پیشفرض سایر UpdatePanel ها نیز محتوای خود را بروزرسانی می کنند. دلیل این امر همین خصوصیت UpdateMode است که مقدار پیشفرض آن Always می باشد.
به یاد داشته باشید که اولین کاری که در مورد UpdatePanel انجام می دهید این باشد که مقدار این خصوصیت را برای Conditional قرار دهید.

<asp:UpdatePanel ID="UpdatePanel1" runat="server" UpdateMode="Conditional" >
<ContentTemplate>
<ContentTemplate>
</asp:UpdatePanel>
با توجه به اینکه هنگامی که UpdatePanel تریگر می شود، تمام محتویات جدید خود را از سرور دریافت نموده و بروز رسانی می نماید، لذا سعی کنید که تعداد کنترل هایی که داخل UpdatePanel قرار می گیرند، حد اقل باشند. برای انجام این کار، کنترل هایی را که قرار است بروز رسانی شوند را داخل UpdatePanel قرار داده و کنترل هایی که دستور بروزرسانی را می دهند ،توسط
AsyncPostBackTrigger (http://www.30sharp.com/ShowArticle.aspx?nid=10&did=39&AuthorID=1) در داخل UpdatePanel رجیستر شوند.
تا جایی که می توانید و به کار شما خدشه ای وارد نمی کند، سعی کنید خصوصیت EnableViewState کنترل های صفحه را برابر false قرار دهید.
یکی از معمول ترین استفاده هایی که از UpdatePanel می شود، قرار دادن کنترل GridView داخل آن می باشد. پس از انجام این کار، می توانیم عمل Paging را بدون انجام Postback کل صفحه، انجام دهیم.
کنترل GridView یکی از کنترل هایی است به مقدار بسیار زیادی ViewState تولید می کند. برای رفع این مشکل پیشنهاد می شود که حتما مقدار خصوصیت EnableViewState مربوط به این کنترل را برابر false قرار دهید. تنها مشکلی که این موضوع می تواند به وجود آورد این است که اگر صفحه Postback شود این کنترل مقادیر خود را از دست می دهد. برای رفع این مشکل پیشنهاد می شود که هنگامی که محتوای این کنترل را از دیتابیس برای اولین بار بازیابی نمودید، باید اطلاعات را Cache کنید تا در هنگام عمل Postback یا انجام عمل Paging، اطلاعات از حافظه Cache خوانده شوند و نه از دیتابیس.
امیدوارم نکات ذکر شده در این مقاله مورد استفاده شما قرار گرفته باشد.

moji5
18th December 2009, 04:34 AM
مقدمه :

همانطور که احتمالا می دانید، یکی از کنترل هایی که استفاده از آن در داخل UpdatePanel امکان پذیر نمی باشد، کنترل FileUpload می باشد. کنترل FileUpload جهت آپلود نمودن فایل ها استفاده می شود. ازجمله مشکلاتی که این کنترل دارد، این است که هنگام انجام عمل آپلود باید کل صفحه مجددا بارگذاری گردد.
در ضمن، نمایش یک تصویر متحرک هنگام انجام عمل آپلود به سادگی امکان پذیر نمی باشد. این مشکل زمانی خود را نشان می دهد که عمل آپلود مقداری زمانبر باشد.
در نسخه ی منتشر شده از AJAX Control Toolkit در تاریخ 30 سپتامبر، دو کنترل جدید به این مجموعه اضافه شده اند که یکی از آن ها کنترل AsyncFileUpload می باشد. این کنترل جهت رفع مشکلاتی که قبلا به آن ها اشاره نمودم، ایجاد شده است.
در این مقاله به معرفی خصوصیات این کنترل می پردازم.
آغاز:

قبل از اینکه به معرفی این کنترل بپردازم، باید ذکر کنم که این کنترل هم در داخل و هم خارج از UpdatePanel قابل استفاده می باشد و به عبارت دیگر، نیازی به کنترل UpdatePanel ندارد.
کنترل AsyncFileUpload امکانات زیر را ارائه می کند:


امکان انجام عمل آپلود، بدون نیاز به بارگذاری مجدد کامل صفحه وب
امکان نمایش یک تصویر متحرک به کاربر ، هنگام انجام عمل آپلود
ارائه رویدادهای (Events) مورد نیاز در سمت کلاینت و سرور، جهت اطلاع از وضعیت عملیات آپلود
امکان انجام عملیات آپلود، بدون نیاز به کنترل UpdatePanel

اکنون به معرفی صفات و رویدادهای مهم کنترل AsyncFileUpload می پردازم:
صفات:



CompleteBackColor: این صفت نام یک رنگ را می گیرد. اگر عملیات آپلود با موفقیت به پایان برسد، رنگ پس زمینه این کنترل برابر رنگی می شود که توسط این صفت مشخص شده است.
ErrorBackColor: عملکرد این صفت شبیه صفت قبلی می باشد. با این تفاوت که اگر هنگام عملیات آپلود با شکست روبرو شود، رنگ پس زمینه کنترل، توسط این صفت مشخص می شود.
UploadingBackColor : عملکرد این صفت شبیه نیز مشابه دو صفت قبلی می باشد. با این تفاوت که این رنگ در حین انجام عمل آپلود در پس زمینه کنترل نمایش داده می شود.
ThrobberID: این صفت نام کنترلی را نگهداری می کند که هنگام انجام عمل آپلود نمایش داده شده و پس از آن ناپدید می گردد. معمولا این کنترل، یک تصویر متحرک می باشد.
UploaderStyle: شکل ظاهری این کنترل توسط این صفت مشخص می شود. مقدار های مجاز برای این صفت Traditional و Modern می باشد. مقدار پیشفرض آن Traditional می باشد که ظاهر کنترل شبیه کنترل معمولی FileUpload می باشد. اگر مقدار این صفت Modern باشد، ظاهر زیباتری پیدا می کند. (ما در ادامه این مقاله از این صفت استفاده خواهیم نمود)

رویداد های سمت کلاینت:



OnClientUploadComplete: این رویداد در سمت کلاینت و در صورتی که عمل آپلود با موفقیت انجام شود، اتفاق می افتد.
OnClientUploadError: این رویداد در سمت کلاینت و در صورتی که هنگام عمل آپلود خطایی به وجود آید اتفاق می افتد.
OnClientUploadStarted: این رویداد در سمت کلاینت و قبل از اینکه انجام عمل آپلود آغاز گردد، اتفاق می افتد.

رویداد های سمت سرور:



UploadedComplete: این رویداد در سمت سرور و زمانی اتفاق می افتد که عمل آپلود با موفقیت انجام شده باشد.
UploadedFileError: این رویداد در سمت سرور و زمانی اتفاق می افتد که عملیات آپلود با خطا روبرو شده باشد.

اکنون زمان استفاده از این کنترل فرا رسیده است.
یک صفحه جدید ایجاد نموده و کنترل AsyncFileUpload را به آن اضافه می نماییم. سپس قطعه کد آن را به شکل زیر تغییر می دهیم.
<asp:ScriptManager ID="ScriptManager1" runat="server"></asp:ScriptManager>
<cc1:AsyncFileUpload ID="AsyncFileUpload1" runat="server"
OnClientUploadError="uploadError"
OnClientUploadComplete="uploadComplete"
OnClientUploadStarted="uplaodStarted"
UploaderStyle="Traditional"
CompleteBackColor ="GreenYellow"
ErrorBackColor="Red"
UploadingBackColor="#CCFFFF"
ThrobberID="imgLoader"
OnUploadedComplete="AsyncFileUpload1_UploadedComplete"

/>

عملکرد قطعه کد بالا را قبلا توضیح داده ام.
در قسمت زیر رویدادهای سمت کلاینت را ملاحظه می نمایید.
<script type = "text/javascript">
function uplaodStarted(sender) {
$get("<%=lblMessage.ClientID%>").style.color = "green";
$get("<%=lblMessage.ClientID%>").innerHTML = "File uploading started.";
}
function uploadComplete(sender) {
$get("<%=lblMessage.ClientID%>").style.color = "#33CCFF";
$get("<%=lblMessage.ClientID%>").innerHTML = "File Uploaded Successfully";
}
function uploadError(sender) {
$get("<%=lblMessage.ClientID%>").style.color = "red";
$get("<%=lblMessage.ClientID%>").innerHTML = "File upload failed.";
}
</script>

عملکرد توابع جاوا اسکریپت بالا کاملا مشخص می باشد.
و در قسمت زیر نیز رویداد سمت سرور AsyncFileUpload1_UploadedComplete را ملاحظه می نمایید.
protected void AsyncFileUpload1_UploadedComplete(object sender, AjaxControlToolkit.AsyncFileUploadEventArgs e)
{
//Delay time just for test!
System.Threading.Thread.Sleep(5000);

string filename = System.IO.Path.GetFileName(AsyncFileUpload1.FileNa me);
AsyncFileUpload1.SaveAs(Server.MapPath("Uploads/") + filename);
}


در قطعه کد بالا، ما فایل مورد نظر را در پوشه ای به نام Uploads ذخیره نموده ایم. ضمنا برای نمایش عملکرد این کنترل، به اندازه 5 ثانیه تاخیر ایجاد نموده ایم.
خوب، کار تمام است. با اجرای برنامه بالا و انجام عمل آپلود با شکل هایی مشابه زیر مواجه خواهید شد.
شکل ظاهری کنترل:

http://www.30sharp.com/Contents/187/AsyncFileUpload_www_30sharp_com.jpg
شکل ظاهری کنترل هنگام شروع عمل آپلود:

http://www.30sharp.com/Contents/187/AsyncFileUpload_Started_www_30sharp_com.jpg
شکل ظاهری کنترل هنگام اتمام موفقیت آمیز عمل آپلود:

http://www.30sharp.com/Contents/187/AsyncFileUpload_Complete_www_30sharp_com.jpg
شکل ظاهری کنترل هنگام ایجاد خطا هنگام انجام عمل آپلود:

http://www.30sharp.com/Contents/187/AsyncFileUpload_Failed_www_30sharp_com.jpg

moji5
18th December 2009, 04:36 AM
در ادامه ی دو مقاله قبلی خود، در مورد بالا بردن راندمان و کارایی صفحات وب ASP.NET AJAX، در این مقاله یکی دیگر از تکنیک های جالب را مطرح می کنم.
قبل از شروع این مقاله، پیشنهاد می کنم که دومقاله قبلی را حتما مطالعه نمایید.


نکات مهم جهت بهبود کارایی و سرعت لود صفحات در ASP.NET AJAX (http://www.30sharp.com/ShowArticle.aspx?nid=10&did=151&AuthorID=1)
استفاده از خصوصیت جالب CompositeScript در ASP.NET Ajax 3.5 SP1 (http://www.30sharp.com/ShowArticle.aspx?nid=10&did=152&AuthorID=1)

برای یادگیری این ترفند، ابتدا نیاز است که با رویدادهایی که هنگام استفاده از کنترل UpdatePanel مورد استفاده قرار می گیرد، آشنا شوید.
PageRequestManager :

PageRequestManager یک آبجک جاوا اسکریپت موجود در ASP.NET AJAX می باشد. وظیفه این آبجک مدیریت وظایف مربوط به UpdatePanel می باشد. به عنوان مثال، وقتی کنترلی در داخل یک UpdatePanel درخواست عمل Postback می کند، آبجک PageRequestManager وظیفه انجام این عمل را به عهده می گیرد و اطلاعاتی را در مورد وضعیت Postback انجام شده در اختیار برنامه نویس قرار می دهد که در ادامه این مقاله این اعمال را بررسی خواهیم نمود.
هنگامی که یک کنترل در داخل UpdatePanel درخواست عمل Postback می کند و یا به عبارت دیگر، کنترل UpdatePanel تریگر می شود، آبجکت PageRequestManager چند رویداد مهم سمت کلاینت (Client Side Event) را در اختیار برنامه نویس قرار می دهد که با استفاده از این رویداد ها می توان عمل Postback درخواست شده را مدیریت نمود.
به این دلیل این رویداد ها را سمت کلاینت می نامیم که در سمت کلاینت اتفاق می افتند و باید توسط کدهای جاوا اسکریپت به آن ها دسترسی پیدا نمود. در صورتی که با این اعمال آشنا نیستید، نگران نباشید و ادامه مقاله را پیگیری کنید.
فرض کنید که یک کنترل Button داخل UpdatePanel دارید که با کلیک شدن آن، زمان کلیک شدن در یک Label نمایش داده می شود.
هنگامی که کنترل Button کلیک شد، رویدادهای زیر قابل دسترس می باشند.


initializeRequest
beginRequest
pageLoading
pageLoaded
endRequest

قبل از اینکه به معرفی هر کدام از رویداد ها بپردازم، نظر شما را به شکل زیر که ترتیب رویدادهای اتفاق افتاده را نشان می دهد، جلب می کنم.
http://www.30sharp.com/Contents/154/UpdatePanelEvents.png اگر با دقت به شکل بالا نگاه کنید، متوجه خواهید شده که بعد از رویداد pageLoaded ، رویدادی به نام load نیز وجود دارد که من در بالا اسمی از آن نبردم.
رویداد load توسط کلاس Sys.Application ، صرف نظر از این که صفحه در حال لود اولیه یا Refresh یا Asynchronous Postback و یا حتی Postback معمولی باشد اتفاق می افتد.
یعنی اگر صفحه برای اولین بار در حال لود شدن باشد و یا اینکه در حال Refresh شدن باشد و یا اگر یک UpdatePanel درخواست Postback نموده باشد، و یا حتی یک Postback معمولی درحال انجام باشد، این رویداد اتفاق می افتد.
با توجه به اینکه بررسی این رویداد در این مقاله مورد نظر بنده نمی باشد، بیش از این در مورد آن صحبت نمی کنم.
اکنون به بررسی رویداد های ذکر شده در بالا و نحوه کاربرد آنها می پردازم. (در ادامه این مقاله، استفاده از این رویداد ها را در کاربرد ملاحظه می کنید، پس نگران نباشید و مطالب را به دقت دنبال کنید.)
initializeRequest :

هنگامی که کنترلی در داخل UpdatePanel درخواست عمل Postback می کند (مثلا یک Button کلیک شود) ، ابتدا این رویداد رخ می دهد. در این رویداد هنوز درخواست عمل Postback به سرور ارسال نشده است و حتی آماده ارسال هم نشده است.
این رویداد بهترین مکان برای اعمالی همچون Cancel نمودن این درخواست می باشد. مثلا ممکن است که صفحه در حال حاضر در حال انجام عمل Asynchronous Postback می باشد(مثلا این Button قبلا کلیک شده و نتیجه آن هنوز برنگشته ولی کاربر مجددا Button را کلیک نموده است!)
عکس این عمل هم قابل انجام است و شما می توانید در خواست قبلی را Cancel کنید (در حقیقت Abort کنید) و به این درخواست جدید اجازه ارسال به سرور و پردازش بدهید.
در ادامه مقاله، نحوه استفاده از این رویداد و نحوده انجام اعمال فوق را خواهید دید.
beginRequest :

اگر در رویداد initializeRequest ، درخواست عمل Postback را Cancel نکرده باشیم. این رویداد اتفاق می افتد. در این رویداد درخواست عمل Postback، آماده برای ارسال به سمت سرور می باشد و دقیقا بعد از این رویداد است که درخواست به سرور ارسال می شود.
نکته:

اگر با عملکرد کنترل UpdateProgress (http://www.30sharp.com/ShowArticle.aspx?nid=10&did=102&AuthorID=1) آشنا باشید، باید بدانید که در این رویداد است که این کنترل نمایش داده می شود. اگر با عملکرد این کنترل آشنا نیستید، پیشنهاد می کنم که این مقاله را مطالعه نمایید.
pageLoading :

اگر عمل Postback با موفقیت انجام شده باشد(یعنی خطایی به وجود نیامده باشد) ، این رویداد رخ می دهد. این رویداد قبل از بروز رسانی محتویات UpdatePanel رخ می دهد. یعنی انجام عمل Postback با موفقیت انجام شده و محتویات جدید UpdatePanel به سمت کلاینت ارسال شده است ولی هنوز محتوای UpdatePanel بروز رسانی نشده است.
در این مقاله از این رویداد استفاده جالبی می کنیم.
pageLoaded :

این رویداد مشابه رویداد pageLoading می باشد با این تفاوت که این رویداد پس از بروزرسانی محتویات جدید UpdatePanel اتفاق می افتد.
endRequest :

صرف نظر از اینکه خطایی در انجام عمل Postback صورت گرفته باشد یا خیر، این رویداد همواره اتفاق می افتد.
نکات :




به این دلیل است که Error Handling را همواره در این رویداد انجام می دهند.

کنترل UpdateProgress در این رویداد مخفی می شود.

در قطعه کد زیر، نحوه استفاده از رویدادهای فوق را مشاهده می نمایید.

<script language="javascript" type="text/javascript">
var prm=Sys.WebForms.PageRequestManager.getInstance();
prm.add_initializeRequest(onInitializeRequest);
prm.add_beginRequest(onBeginRequest);
prm.add_pageLoading(onPageLoading);
prm.add_pageLoaded(onPageLoaded);
prm.add_endRequest(onEndRequest);
function onInitializeRequest(sender,args)
{
// if you want to abort the previous postback and continue new request
//use the following code
//if(prm.get_isInAsyncPostBack())
//{
// prm.abortPostBack();
//}

// if you want to cancel the new request and continue previous postback
//use the following code
//if(prm.get_isInAsyncPostBack())
//{
// args.set_cancel(true);
//}

alert('initializeRequest');
}

function onBeginRequest(sender,args)
{
alert('beginRequest');
}

function onPageLoading(sender,args)
{
alert('pageLoading');
}

function onPageLoaded(sender,args)
{
alert('pageLoaded');
}

function onEndRequest(sender,args)
{
alert('endRequest');
}


</script>
همانطور که ملاحظه می کنید در ابتدا با استفاده از Sys.WebForms.PageRequestManager.getInstance به آبجک PageRequestManager دسترسی پیدا کرده ایم و سپس رویدادهای مورد نظر خود را رجیستر نموده ایم.
قبل از ادامه مقاله، لطفا قطعه کد فوق را اجرا نمایید و عملکرد آن را مشاهده کنید. (قطعه کد کامل این مقاله از لینک بالای صفحه قابل دریافت می باشد.)
خوب، اکنون می رویم به سراغ هدف اصلی این مقاله یعنی بالا بردن راندمان UpdatePanel هایی که دارای کنترل GridView هستند.
هنگامی که UpdatePanel در حال بروز رسانی است، ASP.NET AJAX تمام اشیاء DOM موجود در UpdatePanel را Dispose نموده و سپس این کنترل را بروز رسانی می نماید.
دلیل این عمل این است که حافظه اختصاص یافته به این اشیاء آزاد شود. درست متوجه شدید! عمل مدیریت حافظه در جاوا اسکریپت هم وجود دارد و حتما باید مورد توجه قرار گیرد.
اکنون فرض کنید که یک کنترل GridView (یا کنترل های مشابه) داخل UpdatePanel وجود دارد و دارای عناصر زیادی می باشد. هنگام انجام عمل Paging و یا هر گونه بروز رسانی دیگر UpdatePanel ، ابتدا تمام اشیاء DOM موجود در GridView باید Dispose شوند و سپس عمل بروزرسانی UpdatePanel انجام شود که این عمل طبیعتا مدتی زمان می برد.
یکی از راه های بالا بردن سرعت بروز رسانی UpdatePanel ، در حقیقت دور زدن (Bypass) این عمل می باشد.
برای دور زدن این عمل ما باید در رویداد pageLoading یعنی دقیقا قبل از اینکه عمل بروز رسانی UpdatePanel انجام شود، محتویات داخل GridView را خالی کنیم.
این عمل به شکل زیر انجام می شود.

<script language="javascript" type="text/javascript">
var prm=Sys.WebForms.PageRequestManager.getInstance();
prm.add_pageLoading(onPageLoading);
function onPageLoading(sender,args)
{
var gv=$get('<%= GridView1.ClientID %>');
gv.parentNode.removeChild(gv);
}
</script>
با استفاده قطعه کد بالا در حقیقت عمل Dispose شدن اشیاء را دور زده ایم و این کار انجام نمی شود و در نتیجه مدت زمانی قابل توجهی را صرفه جویی نموده ایم.
نکته:

اگر داخل UpdatePanel از کنترل هایی استفاده نموده اید که توسط کامپوننت های ASP.NET AJAX و یا behaviorها (شامل Extender ها) مورد استفاده قرار گرفته اند، تکنیک ذکر شده قابل استفاده نمی باشد. مثلا اگر داخل GridView از modalpopupextender استفاده نموده اید، این تکنیک برای شما کارایی نخواهد داشت.
همانطور که قبلا اشاره کردم، سعی کنید حتما خصوصیت EnableViewState کنترل GridView را برابر false قرار دهید.

moji5
18th December 2009, 04:38 AM
تذکر :

مخاطبین اصلی این مقاله، افراد متوسط و پیشرفته در زمینه Javascript و Ajax در نظر گرفته شده اند.
مقدمه :

یکی از مهمترین و جالبترین ویژگی های موجود در زبان های شی گرا، ویژگی وراثت (Inheritance) می باشد.
در زبان های شی گرا از قبیل #C و JAVA و VB.NET خاصیت وراثت مبتنی بر کلاس ها (Class Based) می باشد. یعنی شما می توانید کلاس هایی بسازید که تمامی اعضایی که به صورت Public یا Protected در کلاس والد (Parent) می باشند را به ارث برده و مورد استفاده قرار دهند. به این کلاس ها، کلاس های فرزند(Child) گویند.
ولی در زبان جاوا اسکریپت سناریو به شکل متفاوتی است زیرا در این زبان در حقیقت کلاس وجود ندارد و کلاس به صورت شبیه سازی شده وجود دارد و وراثت به شکل مبتنی بر prototype یعنی prototype-based می باشد. و تمامی خصوصیات و متدها از آبجکت prototype به ارث می روند.
شروع :

ادامه مقاله را با طرح یک مثال ادامه می دهم.
فرض کنید کلاسی به نام حیوان خانگی (Pet) داریم و قصد داریم کلاسی به نام گربه (Cat) بنویسیم که از کلاس حیوان خانگی وراثت بگیرد و اعمال متداول را انجام دهد.
در این مقاله، خاصیت وراثت را ابتدا با استفاده از جاوا اسکریپ محض انجام خواهیم داد و سپس با استفاده از ASP.NET AJAX.
کلاس حیوان خانگی را به شکل زیر در نظر می گیریم.

Pet = function() {
this._name="";
this._age=0;
}
Pet.prototype = function() {
speak: function() {
throw Error("This method should be overridden by derived classes.");
}
}

در قطعه کد بالا ما کلاسی به نام Pet تعریف کرده ایم که دارای دو خصوصیت برای نگهداری نام و سن حیوان، می باشد و دارای یک متد به نام speak می باشد که پیاده سازی نشده است. و اگر این متد فراخوانی شود، خطایی تولید می شود و بیانگر این می باشد که این متد باید توسط کلاس فرزند override شود.
اکنون قصد داریم کلاسی به نام گربه بنویسیم که از کلاس بالا وراثت گرفته و متد speak را override نموده و صدای گربه را بر می گرداند.

Cat = function() {
//Call base class’s constructor
Pet.call(this);
}

//Inherit properties defined in prototype
Cat.prototype = new Pet();
//Override speak method
Cat.prototype.speak = function() {
return 'Meeeooow'
}

در قطعه کد بالا آبجکت Cat از Pet وراثت گرفته است و سه عمل دیگر صورت گرفته است .


به ارث بردن خصوصیات تعریف شده در سازنده (Constructor) کلاس والد، به وسیله فراخوانی نمودن سازنده کلاس Pet در سازنده کلاس Cat
به ارث بردن خصوصیات تعریف شده در قسمت prototype کلاس والد. این عمل توسط ایجاد یک نمونه جدید از کلاس Pet و نسبت دادن آن به prototype کلاس Cat به وجود آمده است.
override نمودن متد speak

قطعه کد بالا به شکل زیر قابل استفاده می باشد.

var cat = new Cat();
cat.speak();

پیاده سازی وراثت توسط ASP.NET AJAX :

اکنون اعمالی را که توسط جاوا اسکریپت محض انجام دادیم را با استفاده از ASP.NET AJAX به شکل حرفه ای تری انجام خواهیم داد.
ابتدا کلاس Pet را می نویسیم

Type.registerNamespace('Samples')
Samples.Pet = function() {
this._name = '';
this._age = 0;
}
Samples.Pet.prototype = {
speak: function() {
throw Error("This method should be overridden by derived classes.");
}
}
Type.registerClass('Samples.Pet');

نکته قابل توجه در قطعه کد بالا این است که ما این کلاس را در یک فضای نامی به نام Samples قرار داده ایم.
اکنون کلاسی به نام Cat در یک فضای نامی به نام Samples ایجاد خواهیم نمود و از کلاس Pet وراثت خواهیم گرفت.

Type.registerNamespace('Samples');
Samples.Cat = function() {
Samples.Cat.initializeBase(this);
}
Sapmples.Cat.prototype = {
speak: function() {
return 'Meeeooow';
}
}
Type.registerClass('Samples.Cat', Samples.Pet);

در قطع کد بالا ما در سازنده کلاس Cat با استفاده از متد initializeBase و ارسال this به عنوان پارامتر برای آن، کلیه خواص موجود در سازند کلاس والد یعنی Pet را به ارث برده ایم.
سپس متد speak را override نموده ایم. در انتهای قطعه کد، کلاس را رجیستر نموده ایم.
تذکر :

دقت داشته باشید که باید کلاس والد را به عنوان پارامتر دوم به متد registerClass ارسال کنیم.
خوب، فرض کنید که سازنده کلاس والد تعدادی پارامتر را به عنوان آرگومان دریافت می نماید. پس سازنده کلاس والد، یعنی Pet را به شکل زیر تغییر می دهیم.

Samples.Pet = function(name, age) {
this._name = name;
this._age = age;
}
در قطعه کد زیر در سازنده کلاس Cat ، ما پارامترها را دریافت نموده و به سازند کلاس والد یعنی Pet می فرستیم.

Samples.Cat = function(name, age) {
Samples.Cat.initializeBase(this, [name, age]);
}

همانطور که ملاحظه می نمایید، پارامترهای لازم را به شکل یک آرایه (Array) در پارامتر دوم تابع initializeBase ارسال نموده ایم.
قطعه کد فوق به شکل زیر قابل استفاده است.

var cat=new Cat('CatName',1)

اکنون فرض کنید که در متدی که override نموده ایم، قصد داریم متد مربوطه در کلاس والد را فرخوانی نماییم.
این عمل به شکل زیر قابل انجام است.

Samples.Cat.prototype = function() {
Samples.Cat.callBaseMethod(this, 'speak');
}

در قطعه کد بالا با استفاده از متد callBaseMethod این عمل انجام شده است. پارامتر اول this و پارامتر دوم نام متد مربوطه می باشد.
در صورتی که متد کلاس والد دارای پارامتر باشد، باید پارامتر ها را به شکل یک آرایه و به عنوان پارامتر سوم به متد callBaseMethod ارسال نماییم.

Samples.Cat.callBaseMethod(this, 'speak',[param1,param2,....] );
موفق باشید.

mhkcoder
5th September 2010, 03:43 AM
سلام مطلب خوبی بود ولی کاش قبل از این که در خلال سورس نام منبع اصلی فاش بشه خودتون تو پست اول میگفتید .

MAHDIAR
25th March 2014, 03:21 AM
سلام دوست عزیز شما استاد ajax هستید من یک در خواست دارم لطف میکنید یک اسلایدر فول پیج را ajax بسازید ویه فروم ورود مثل این سایت blur-sky-group.ir
اگه مقدور برام ایمیل کنید تو پرفایلم هستش

استفاده از تمامی مطالب سایت تنها با ذکر منبع آن به نام سایت علمی نخبگان جوان و ذکر آدرس سایت مجاز است

استفاده از نام و برند نخبگان جوان به هر نحو توسط سایر سایت ها ممنوع بوده و پیگرد قانونی دارد