نظرات مطالب
استفاده از pjax بجای ajax در ASP.NET MVC
با سلام
زمانی که از pjax استفاده می‌کنیم اگر قرار باشه ویویی رو که دارای یک فرم برای ارسال اطلاعات به سرور است را نمایش دهیم با خطای زیر رو به رو می‌شویم.

و بعد از نمایش خطا کل صفحه رفرش می‌شود و مثل اینه که اصلا pjax کار نداده.
همه‌ی مراحل را هم در مثال قبل که ارسال شد انجام داده ام ولی باز به اینصورت جواب میده.
مطالب
آشنایی با الگوی طراحی Prototype
فرض کنید در حال پختن یک کیک هستید. ابتدا کیک را می‌پذید و سپس آن را تزیین می‌کنید. عملیات پختن کیک، فرآیند ثابتی است و تزیین کردن آن متفاوت. گاهی کیک را با کاکائو تزیین می‌کنید و گاهی با میوه و غیره. 
پیش از اینکه سناریو را بیش از این جلو ببریم، وارد بحث کد می‌شویم. طبق سناریوی فوق، فرض کنید کلاسی بنام Prototype دارید که این کلاس هم از کلاس انتزاعی APrototype ارث برده است. در ادامه یک شیء از این کلاس می‌سازید و مقادیر مختلف آن را تنظیم کرده و کار را ادامه می‌دهید. 
public abstract class APrototype : ICloneable     {
        public string Name { get; set; }
        public string Health { get; set; }
    }

    public class Prototype : APrototype
    {
        public override string ToString() { return string.Format("Player name: {0}, Health statuse: {1}", Name, Health); }
    }
در ادامه از این کلاس نمونه‌گیری می‌کنیم:
Prototype p1 = new Prototype { Name = "Vahid", Health = "OK" };
Console.WriteLine(p1.ToString());
حالا فرض کنید به یک آبجکت دیگر نیاز دارید، ولی این آبجکت عینا مشابه p1 است؛ لذا نمونه‌گیری، از ابتدا کار مناسبی نیست. برای اینکار کافیست کدها را بصورت زیر تغییر دهیم:
 public abstract class APrototype : ICloneable
    {
        public string Name { get; set; }
        public string Health { get; set; }
        public abstract object Clone();
    }

    public class Prototype : APrototype
    {
        public override object Clone() { return this.MemberwiseClone() as APrototype; }
        public override string ToString() { return string.Format("Player name: {0}, Health statuse: {1}", Name, Health); }
    }
در متد Clone از MemberwiseClone استفاده کرده‌ایم. خود Clone هم در داخل واسط ICloneable تعریف شده‌است و هدف از آن کپی نمودن آبجکت‌ها است. سپس کد فوق را بصورت زیر مورد استفاده قرار می‌دهیم:
Prototype p1 = new Prototype { Name = "Vahid", Health = "OK" };
Prototype p2 = p1.Clone() as Prototype;
Console.WriteLine(p1.ToString());
Console.WriteLine(p2.ToString());
با اجرای کد فوق مشاهده میشود p1 و p2 دقیقا عین هم کار می‌کنند. کل این فرآیند بیانگر الگوی Prototype می‌باشد. ولی تا اینجای کار درست است که الگو پیاده سازی شده است، ولی همچنین به نظر نقصی نیز در کد دیده می‌شود:
برای واضح نمودن نقص، یک کلاس بنام AdditionalDetails تعریف می‌کنیم. در واقع کد را بصورت زیر تغییر میدهیم:
 public abstract class APrototype : ICloneable
    {
        public string Name { get; set; }
        public string Health { get; set; }
        public AdditionalDetails Detail { get; set; }
        public abstract object Clone();
    }
    public class AdditionalDetails { public string Height { get; set; } }

    public class Prototype : APrototype
    {
        public override object Clone() { return this.MemberwiseClone() as APrototype; }
        public override string ToString() { return string.Format("Player name: {0}, Health statuse: {1}, Height: {2}", Name, Health, Detail.Height); }
    }
و از آن بصورت زیر استفاده می‌کنیم:
Prototype p1 = new Prototype { Name = "Vahid", Health = "OK", Detail = new AdditionalDetails { Height = "100" } };
Prototype p2 = p1.Clone() as Prototype;
p2.Detail.Height = "200";
Console.WriteLine(p1.ToString());
Console.WriteLine(p2.ToString());
خروجی که نمایش داده می‌شود در بخش Height هم برای p1 و هم برای p2 عدد 200 را نمایش می‌دهد که می‌تواند اشتباه باشد. چراکه p1 دارای Height برابر با 100 است و p2  دارای Height برابر با 200. به این اتفاق ShallowCopy گفته میشود که ناشی از استفاده از MemberwiseClone است که در مورد ارجاعات با آدرس رخ می‌دهد.  در این حالت بجای کپی نمودن مقدار، از کپی نمودن آدرس استفاده میشود (Ref Type چیست؟)
برای حل این مشکل باید DeepCopy انجام داد. لذا کد را بصورت زیر تغییر می‌دهیم:(DeepCopy و ShallowCopy چیست؟)
 public abstract class APrototype : ICloneable
    {
        public string Name { get; set; }
        public string Health { get; set; }
        //This is a ref type
        public AdditionalDetails Detail { get; set; }
        public abstract APrototype ShallowClone();
        public abstract object Clone();
    }

    public class AdditionalDetails { public string Height { get; set; } }

    public class Prototype : APrototype
    {
        public override object Clone()
        {
            Prototype cloned = MemberwiseClone() as Prototype;
            //We need to deep copy each ref types in order to prevent shallow copy
            cloned.Detail = new AdditionalDetails { Height = this.Detail.Height };
            return cloned;
        }
        //Shallow copy will copy ref type's address instead of their value, so any changes in cloned object or source object will take effect on both objects
        public override APrototype ShallowClone() { return this.MemberwiseClone() as APrototype; }
        public override string ToString() { return string.Format("Player name: {0}, Health statuse: {1}, Height: {2}", Name, Health, Detail.Height); }
    }
و سپس بصورت زیر از آن استفاده نمود:
 Prototype p1 = new Prototype { Name = "Vahid", Health = "OK", Detail = new AdditionalDetails { Height = "100" } };
            Prototype p2 = p1.Clone() as Prototype;
            p2.Detail.Height = "200";
            Console.WriteLine("<This is Deep Copy>");
            Console.WriteLine(p1.ToString());
            Console.WriteLine(p2.ToString());

            Prototype p3 = new Prototype { Name = "Vahid", Health = "OK", Detail = new AdditionalDetails { Height = "100" } };
            Prototype p4 = p3.ShallowClone() as Prototype;
            p4.Detail.Height = "200";
            Console.WriteLine("\n<This is Shallow Copy>");
            Console.WriteLine(p3.ToString());
            Console.WriteLine(p4.ToString());
لذا خروجی بصورت زیر را می‌توان مشاهده نمود:

البته در این سناریو ShallowCopy باعث اشتباه شدن نتایج می‌شود. شاید شما در دامنه‌ی نیازمندیهای خود، اتفاقا به ShallowCopy نیاز داشته باشید و DeepCopy مرتفع کننده‌ی نیاز شما نباشد. لذا کاربرد هر کدام از آنها وابستگی مستقیمی به دامنه‌ی نیازمندی‌های شما دارد.
نظرات مطالب
چک لیست ارتقاء به HTTPS مخصوص یک برنامه‌ی ASP.NET MVC 5x
روشی بهتر برای مدیریت محتوای مخلوط (لینک به HTTP و HTTPS در یک صفحه) در مرورگرهای جدید

در مورد محتوای مخلوط و «اصلاح تمام آدرس‌هایی که پیشتر توسط برنامه تولید شده‌اند» در مطلب فوق نکته‌ای عنوان شده‌است. روش دیگر مدیریت آن که نیازی به اصلاح محتوای صفحات سایت را ندارد، استفاده از هدر امنیتی «Content-Security-Policy: upgrade-insecure-requests» است:
<system.webServer>
    <httpProtocol>
      <customHeaders>
        <add name="Strict-Transport-Security" value="max-age=16070400; includeSubDomains" />
        <add name="Content-Security-Policy" value="upgrade-insecure-requests;" />
      </customHeaders>
</httpProtocol>
کار این هدر ویژه ، ارتقاء خودکار لینک‌های درج شده‌ی در صفحات به نگارش‌های HTTPS آن‌ها است. برای مثال این تصویری است که پیش از اعمال این هدر جهت درخواست آدرس gravatar یک کاربر ارسال شده‌است و اخطار محتوای مخلوط را می‌دهد:


و این تصویری است که پس از اعمال هدر upgrade-insecure-requests قابل مشاهده‌است که دیگر اخطار محتوای مخلوط را به همراه ندارد:
 

نظرات مطالب
AngularJS #1
سلام؛
کتابخانه‌ی jQuery عموما برای دو کار استفاده می‌شود: 
1- دستکاری یا پردازش DOM
2- ارتباط با سرور به صورت AJAX
انگولار سرویسی برای ارتباط AJAX دارد که شما را کاملا از jQuery بی نیاز می‌کند.
برای پردازش DOM و الصاق رویداد به عناصر صفحه، انگولار دارای API‌های خیلی خوبی است که می‌تواند تا حدی جایگزین jQuery باشد. اما فراموش نکنیم که jQuery علاوه بر پردازش DOM دارای کلی API متنوع است که انگولار به پای آن نمی‌رسد. دلیل هم مشخص است؛ چرا که هر دو کتابخانه برای کاری متفاوت نوشته شده اند و مقایسه آن‌ها اصلا کار درستی نیست. همچنین به این نکته هم توجه داشته باشید که برای jQuery هزاران افزونه‌ی مختلف نوشته اند که اجرای آن ها، وابسته به jQuery است. پس هیچ کتابخانه ای در این زمینه موازی کاری نمی‌کند، چون توانایی رقابت ندارد.(البته تعدادی را هم با کاملارا انگولار بازنویسی کرده اند.)
انگولار در مورد دستکاری DOM هم یک مورد را شما گوشزد می‌کند: اگر می‌خواهید  DOM را دستکاری کنید، این کار را باید از طریق Directive‌ها انجام دهید. منظور این است کدهای مورد نظرتان را با هر کتابخانه ای که می‌خواهید بنویسید، ولی آن‌ها را درون یک Directive سفارشی بنویسید و روی هوا کد ننویسید تا قابل تست کردن باشد.
در ادامه کاملا متوجه منظورم خواهید شد.
اشتراک‌ها
نکته های TypeScript در VS Code

اگر شما از TypeScript در محیط Visual Studio استفاده میکنید بصورت خودکار امکاناتی نظیر کامپایل کد‌ها بعد از save را در اختیار خواهید داشت (به فرض که این ویژگی رو غیر فعال نکرده باشید)، اما در محیط هایی مثل VS Code چطور ؟

نکته های TypeScript در VS Code
مطالب
نگاهی به اجزای تعاملی Twitter Bootstrap
پس از آشنایی با طرحبندی صفحات و امکانات متداول Twitter Bootstrap، در این قسمت به کامپوننت‌ها و اجزای تعاملی آن مانند منوها، برگه‌ها و امثال آن خواهیم پرداخت.

منوهای پایین افتادنی (Dropdown menus) در Twitter Bootstrap

برای کار با منوها، حداقل نیازهایی که باید به صفحه اضافه شوند، فایل css مرتبط با Twitter Bootstrap، فایل اسکریپت‌های جی‌کوئری و فایل bootstrap.min.js است.
در ادامه، ساختار متداول یک منوی نمونه ایجاد شده را ملاحظه می‌کنید:
    <div class="container-fluid">
        <div class="row-fluid">
            <div class="span12">
                <div class="dropdown">
                    <a class="dropdown-toggle" data-toggle="dropdown" href="#">منوی پایین افتادنی 
                    <span  class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a href="http://www.site1.com">site1</a></li>
                        <li><a href="http://www.site2.com">site2</a></li>
                        <li><a href="http://www.site3.com">site3</a></li>
                        <li class="divider"></li>
                        <li class="dropdown-submenu"><a href="#">سایر موارد</a>
                            <ul class="dropdown-menu">
                                <li><a href="http://www.site4.com">site4</a></li>
                                <li><a href="http://www.site5.com">site5</a></li>
                            </ul>
                        </li>
                    </ul>
                </div>
            </div>
        </div>
    </div>

در اینجا به یک div، کلاس dropdown نسبت داده شده است؛ از این جهت که می‌توان این منو را به انواع و اقسام المان‌های صفحه نیز نسبت داد. به این ترتیب، منو از محل قرارگیری این المان باز خواهد شد. در ادامه روال متداول تعریف منو را در Bootstrap، ملاحظه می‌کنید. کلاس dropdown-toggle سبب خواهد شد تا با کلیک ماوس بر روی لینک، منو ظاهر شود. کلاس caret نیز سبب نمایش مثلث رو به پایین، جهت مشخص سازی وجود منو در این محل خاص، تعریف شده است.
المان‌های منو، توسط لیست‌ها تعریف می‌شوند. این لیست باید با کلاس dropdown-menu شروع شود. سپس هر عضو این لیست، یک آیتم منو را تشکیل خوهد داد. اگر نیاز به خط جدا کننده‌ای در این میان باشد، باید از کلاس divider استفاده کرد.
در اینجا همچنین امکان تعریف منوهای تو در تو نیز وجود دارد. برای اینکار تنها کافی است یک لیست دیگر را در این میان اضافه کرد. کلاس dropdown-submenu به عضو لیست دربرگیرنده زیر منو، اضافه می‌شود. زیر منو نیز دارای کلاس dropdown-menu خواهد بود.

چند نکته تکمیلی در مورد منوها:
- همانطور که در قسمت بررسی دکمه‌های Bootstrap نیز عنوان شد، برای تبدیل یک المان به دکمه فقط کافی است کلاس btn را به آن انتساب دهیم. در اینجا نیز می‌توان کلاس لینک منوی پایین افتادنی را به صورت btn btn-primary dropdown-toggle تعریف کرد تا ظاهر آن تبدیل به یک دکمه Bootstrap شود.
- در اولین div مثال فوق، کلاس dropdown ذکر شده است. می‌توان این کلاس را به dropup تغییر داد تا نحوه باز شدن منوی تعریف شده رو به بالا باشد؛ بجای رو به پایین.
- برای ساخت split button که تشکیل شده است از دو دکمه اصلی و دکمه کوچکی در کنار آن که یک زیرمنو را نمایش می‌دهد، باید به نحو زیر عمل کرد:
    <div class="container-fluid">
        <div class="row-fluid">
            <div class="span12">
                <div class="btn-group">
                    <a class="btn btn-primary" href="#">Split button</a> <a class="btn btn-primary dropdown-toggle"
                        data-toggle="dropdown" href="#"><span class="caret"></span></a>
                    <ul class="dropdown-menu">
                        <li><a href="http://www.site1.com">site1</a></li>
                        <li><a href="http://www.site2.com">site2</a></li>
                    </ul>
                </div>
            </div>
        </div>
    </div>
تنها نکته‌ای که در اینجا نسبت به حالت قبل اضافه شده است، استفاده از کلاس btn-group است. این کلاس سبب می‌شود تا دکمه‌های تعریف شده در کنار هم به شکل یک toolbar مرتب شوند.



تعریف برگه‌ها در Twitter Bootstrap

برای تعریف منوهای راهبری سایت به شکل برگه، کار با استفاده از کلاس nav و تعریف یک لیست ساده شروع می‌شود:
    <div class="container">
        <div class="row">
            <h2>
                Navigational menus
            </h2>
            <div class="span3">
                <ul class="nav nav-tabs">
                    <li class="nav-header">nav nav-tabs</li>
                    <li class="active"><a href="#">Home</a></li>
                    <li><a href="#">Contact</a></li>
                    <li><a href="#">Login</a></li>
                </ul>
            </div>
            <div class="span3">
                <ul class="nav nav-tabs nav-stacked">
                    <li class="nav-header">nav nav-tabs nav-stacked</li>
                    <li class="active"><a href="#">Home</a></li>
                    <li><a href="#">Contact</a></li>
                    <li><a href="#">Login</a></li>
                </ul>
            </div>
            <div class="span3">
                <ul class="nav nav-pills">
                    <li class="nav-header">nav nav-pills</li>
                    <li class="active"><a href="#">Home</a></li>
                    <li><a href="#">Contact</a></li>
                    <li><a href="#">Login</a></li>
                </ul>
            </div>
            <div class="span3">
                <ul class="nav nav-list">
                    <li class="nav-header">nav nav-list</li>
                    <li class="active"><a href="#">Home</a></li>
                    <li><a href="#">Contact</a></li>
                    <li><a href="#">Login</a></li>
                    <li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Menu
                        ...<span class="caret"></span></a>
                        <ul class="dropdown-menu">
                            <li><a href="http://www.site1.com">site1</a></li>
                            <li><a href="http://www.site2.com">site2</a></li>
                        </ul>
                    </li>
                </ul>
            </div>
        </div>
    </div>


- اضافه شدن کلاس nav، بولت‌های لیست را حذف و ویژگی تغییر رنگ زمینه هر یک از عناصر لیست را با حرکت اشاره‌گر ماوس بر روی آن فعال می‌کند.
- برای اعمال اشکال مختلف به کلاس nav، می‌توان از سایر کلاس‌های مرتبط استفاده کرد. اگر از nav-tabs استفاده شود، این لیست عمودی تبدیل به یک لیست افقی خواهد شد. اگر کلاس active به یکی از آیتم‌های آن نسبت داده شود (بیانگر صفحه جاری)، این گزینه حالت انتخاب شده را پیدا می‌کند.
- در هر حالت، برای تبدیل چیدمان افقی به عمودی، از کلاس nav-stacked استفاده نمائید.
- کلاس nav-pills، برای نمایش عنصر فعال، از یک مستطیل با گوشه‌های گرد استفاده می‌کند.
- اگر می‌خواهید این گوشه‌ها گرد نباشند، از nav-list استفاده کنید.
- در هر کدام از حالت‌ها می‌توان از یک گزینه اختیاری با کلاس nav-header برای نمایش متنی خاکستری بالای منوی راهبری استفاده کرد.
- همانطور که در آخرین لیست اضافه شده در مثال فوق ملاحظه می‌کنید، امکان تعریف منوهای پایین افتادنی در اینجا نیز میسر است. در این حالت کلاس li تعریف شده باید dropdown تعریف شود. مابقی نکات آن مانند قبل است.


تعریف یک Tab به همراه محتوای برگه‌های آن در داخل یک صفحه

در حالت تعریف منوهای راهبری فوق، هر عنصر برگه‌های تعریف شده به یک صفحه جدید لینک شده بود. اگر نیاز باشد تا هر برگه، محتوایی داخل همان صفحه داشته باشد باید به نحو ذیل عمل کرد:
    <div class="container">
        <div class="row">
            <div class="span12">
                <div class="tabbable">
                    <ul class="nav nav-tabs">
                        <li class="active"><a data-toggle="tab" href="#tab1">Home</a></li>
                        <li><a data-toggle="tab" href="#tab2">About</a></li>
                    </ul>
                    <div class="tab-content">
                        <div class="tab-pane active" id="tab1">
                            data ... data ...
                        </div>
                        <div class="tab-pane" id="tab2">
                            data2 ... data2 ...
                        </div>
                    </div>
                </div>
            </div>
        </div>
    </div>

در اینجا کار با کلاس tabbable شروع می‌شود. سپس از یک لیست با کلاس nav nav-tabs برای تعریف سرتیترهای برگه‌ها استفاده می‌کنیم.
اگر به مثال فوق دقت کنید، اینبار hrefهای تعریف شده به tab1 و tab2 اشاره می‌کنند. ایندو در حقیقت id محتوای متناظر هستند که در قسمت div ایی با کلاس tab-content به div هایی با id مساوی tab1 و tab2 انتساب داده شده‌اند.


شیوه دوم تعریف منوی راهبری سایت به کمک Twitter Bootstrap

اگر علاقمند باشید که منوی راهبری بالای سایت دارای یک حاشیه به همراه مسایل طراحی واکنش‌گرا باشد، می‌توان از کامپوننت navbar مجموعه Bootstrap استفاده کرد:
    <div class="container">
        <div class="row">
            <div class="span12">
                <nav class="navbar navbar-inverse">
                    <div class="navbar-inner">
                        <a href="/" class="brand">نام سایت در اینجا</a> 
                        <a class="btn btn-navbar" data-toggle="collapse" data-target=".nav-collapse">
                            <span class="icon-bar"></span>
                            <span class="icon-bar"></span>
                            <span class="icon-bar"></span>
                        </a>
                        <div class="nav-collapse collapse">
                            <ul class="nav">
                                <li><a href="/about">درباره</a></li>
                                <li><a href="/contact">تماس</a></li>
                                <li class="dropdown"><a class="dropdown-toggle" data-toggle="dropdown" href="#">Menu
                                    ...<span class="caret"></span></a>
                                    <ul class="dropdown-menu">
                                        <li><a href="http://www.site1.com">site1</a></li>
                                        <li><a href="http://www.site2.com">site2</a></li>
                                    </ul>
                                </li>
                            </ul>
                            <form class="navbar-search pull-right input-append" action="/search">
                            <input class="span2" type="search" />
                            <button class="btn" type="button">
                                جستجو</button>
                            </form>
                        </div>
                    </div>
                </nav>
            </div>
        </div>
    </div>


navbar نیز همانند بسیاری از کامپوننت‌های Bootstrap، بر اساس ul و liها کار می‌کند. در ابتدای کار، کلاس nav را به تگ ul انتساب می‌دهیم. این مورد با مباحث قسمت قبلی در مورد تدارک برگه‌ها، تفاوتی نمی‌کند. به این ترتیب بولت‌های لیست حذف شده و همچنین تغییر رنگ پس زمینه، با حرکت اشاره‌گر ماوس بر روی آیتم‌ها را سبب می‌شود. سپس کل این ul و li ها، داخل تگ nav قرار می‌گیرند با کلاسی مساوی navbar. تا اینجا لیست عمودی تبدیل به یک لیست افقی می‌شود.
در ادامه برای اضافه کردن حاشیه‌ای به اطراف این منوی راهبری و تمایز آن از سایر قسمت‌های صفحه، یک div با کلاس navbar-inner را اضافه خواهیم کرد.
عموما مرسوم است که در منوی راهبری اصلی سایت، نام سایت یا متنی مشخص نیز در قسمتی از این منو ظاهر شود. برای انجام اینکار، کافی است یک لینک را با کلاس brand اضافه کنیم.
این موارد، اصول کلی تهیه یک منوی راهبری اصلی سایت را توسط Bootstrap بیان می‌کنند. در ادامه به چند نکته تکمیلی خواهیم پرداخت:
- اگر به تگ nav، کلاس navbar-static-top را اضافه کنیم، فاصله بین منو و اطراف صفحه را حذف می‌کند.
- اگر علاقمند هستیم که منوی بالای صفحه حتی با اسکرول به پایین محتوای نمایش داده شده، همواره نمایان باشد و بر روی محتوا قرار گیرد، می‌توان به تگ nav، کلاس navbar-fixed-top را اضافه کرد. یا اگر نیاز است این منو در پایین صفحه به صورت ثابت نمایش داده شود از navbar-fixed-bottom می‌شود استفاده کرد.
در این حالت خاص ممکن است منو، قسمتی از ابتدای محتوای صفحه را مخفی کند و این محتوا زیر منو واقع شود. برای بهبود آن باید margin-top مرتبط با body را مقدار دهی کنید (حدود 40px کافی است).
- استفاده از کلاس navbar-inverse (همانند مثال فوق)، سبب معکوس شدن رنگ زمینه منوی راهبری می‌شود.
- همچنین در اینجا نیز می‌توان یک dropdown-menu را به نحوی که ملاحظه می‌کنید، به منوی اصلی سایت افزود.
- امکان قرار دادن فرم‌های خاصی مانند فرم جستجو نیز در منوی راهبری وجود دارد. در این حالت از کلاس navbar-search مانند مثال فوق استفاده خواهد شد. کلاس pull-right این المان را به سمت راست صفحه (در اینجا به سمت چپ با توجه به RTL بودن قالب)، هدایت می‌کند و کلاس input-append سبب می‌شود تا دکمه و تکست باکس تعریف شده در یک سطر و کنار هم قرارگیرند تا ظاهر بهتری حاصل شود. در حالت کلی کلاس navbar-form نیز برای این نوع فرم‌ها درنظر گرفته شده است.
- اگر دقت کرده باشید، کل محتوای منو، به همراه فرم تعریف شده، در یک div با کلاس nav-collapse قرار گرفته است. هدف از اینکار ناپدید شدن خودکار قسمت‌های طولانی یا نچندان مهم، در حین مرور سایت با اندازه‌های مرورگر کوچکتر مانند مرورگرهای موبایل است. همچنین اگر بخواهیم در این حالت که قسمت‌هایی ناپدید شده‌اند، یک دکمه با سه سطر که بیانگر منویی مخفی است را نمایش دهیم می‌توان از کلاس btn-navbar استفاده کرد؛ که نمونه‌ای از آن‌را در مثال فوق ملاحظه می‌کنید. این دکمه بر اساس data-target مشخص شده، سبب مخفی یا ظاهر شدن قسمتی از صفحه می‌گردد.




تعیین موقعیت کاربر در صفحه به کمک breadcrumbs در Bootstrap

    <div class="container">
        <div class="row">
            <div class="span12">
                <ul class="breadcrumb">
                    <li><a href="/level1">سطح یک</a> <span class="divider">/</span></li>
                    <li><a href="/level2">سطح دو</a> <span class="divider">/</span></li>
                    <li class="active">سطح سه</li>
                </ul>
            </div>
        </div>
    </div>
عموما مرسوم است در یک سایت چند سطحی، موقعیت جاری کاربر، به نحوی به او اعلام شود. یکی از این روش‌ها استفاده از breadcrumbs است که نمونه‌ای از آن‌را در مثال فوق ملاحظه می‌کنید.
- در اینجا نیز برای تعریف breadcrumbs از ul و li استفاده شده است به همراه کلاس breadcrumb.
- برای ایجاد فاصله و نمایش یک خط جداکننده، از کلاس divider کمک گرفته شده است.
- صفحه جاری با کلاس active مشخص گردیده؛ بدون تعریف لینک.


تعریف قسمت صفحه بندی یک لیست یا گرید به کمک Bootstrap

<div class="container">
        <div class="row">
            <div class="span12">
                <div class="pagination pagination-centered pagination-large">
                    <ul>
                        <li class="disabled"><a href="#">Prev</a></li>
                        <li class="active"><a href="/page/1">1</a></li>
                        <li><a href="/page/2">2</a></li>
                        <li><a href="/page/3">3</a></li>
                        <li><a href="/page/4">4</a></li>
                        <li><a href="#">Next</a></li>
                    </ul>
                </div>
            </div>
        </div>
    </div>

برای نمایش زیباتر قسمت صفحه بندی یک لیست یا گرید می‌توان از یک سری ul و li مزین شده با کلاس pagination استفاده کرد. کلاس pagination-centered، آن‌را در وسط صفحه قرار خواهد داد (حالت‌های چپ و راست نیز وجود دارند). کلاس pagination-large، این قسمت را اندکی بزرگتر از معمول نمایش می‌دهد.
در اینجا کلاس disabled، سبب غیرفعال نمایش داده شدن لینک به یک صفحه و کلاس active، بیانگر نمایش صفحه جاری است.


نمایش برچسب‌ها و اعلانات با زمینه‌های مختلف به کمک Bootstrap

برای نمایش برچسب‌های کوتاه با زمینه‌ای متفاوت از کلاس label استفاده می‌شود. افزودن کلاس‌هایی مانند  label-success و امثال آن که در مثال ذیل ذکر شده‌اند، رنگ‌های متفاوتی را سبب خواهند شد. برای گرد کردن بیش از حد گوشه این برچسب‌ها از کلاس badge استفاده می‌شود.
    <div class="container">
        <div class="row">
            <div class="span12">
                <section>
                    <ul class="unstyled">
                        <li><span class="label">پیش فرض</span></li>
                        <li><span class="label label-success">موفقیت آمیز</span></li>
                        <li><span class="label label-warning">اخطار</span></li>
                        <li><span class="label label-importatnt">مهم است</span></li>
                        <li><span class="label label-info">اطلاعات</span></li>
                        <li><span class="label label-inverse">رنگ معکوس</span></li>
                    </ul>
                </section>
                <section>
                    <ul class="unstyled">
                        <li><span class="badge">پیش فرض</span></li>
                        <li><span class="badge badge-success">موفقیت آمیز</span></li>
                        <li><span class="badge badge-warning">اخطار</span></li>
                        <li><span class="badge badge-importatnt">مهم است</span></li>
                        <li><span class="badge badge-info">اطلاعات</span></li>
                        <li><span class="badge badge-inverse">رنگ معکوس</span></li>
                    </ul>
                </section>
                <div>
                    <div class="alert">
                        <button class="close" data-dismiss="alert">&times;</button>
                        نمایش اعلانات
                    </div>
                    <div class="alert alert-danger">
                        <button class="close" data-dismiss="alert">&times;</button>
                        نمایش اعلانات
                    </div>
                    <div class="alert alert-info">
                        <button class="close" data-dismiss="alert">&times;</button>
                        نمایش اعلانات
                    </div>
                    <div class="alert alert-success">
                        <button class="close" data-dismiss="alert">&times;</button>
                        نمایش اعلانات
                    </div>
                    <div class="alert alert-error">
                        <button class="close" data-dismiss="alert">&times;</button>
                        نمایش اعلانات
                    </div>
                </div>
            </div>
        </div>
    </div>

همانطور که ملاحظه می‌کنید برای نمایش اعلانی به کاربر می‌توان از کلاس alert استفاده کرد. افزودن کلاس‌هایی مانند alert-danger، رنگ‌های متفاوتی را ارائه خواهند داد و اگر علاقمندید که کاربر بتواند این اخطار را با کلیک بر روی دکمه ضربدر کنار آن حذف کند، از یک دکمه با کلاس close و data-dismiss مساوی alert استفاده کنید. این اطلاعات به صورت خودکار توسط اسکریپت‌های bootstrap پردازش می‌شوند.
مطالب
استخراج اطلاعات از صفحات وب با کمک HtmlAgilityPack
چند مدت پیش موقعی که تب المپیک بود و جدول http://www.london2012.com/medals/medal-count/  رو زیاد نگاه می‌کردم به نظرم رسید که کاشکی به اطلاعاتی مثل اینکه چند نفر از مدال آور‌ها خانم و یا آقا هستند و یا اینکه در روزهای مختلف تعداد مدال‌ها چطور توزیع می‌شند و بشه با یک jQuery UI  Slider روزهای مختلف رو انتخاب کرد و جدول رو دید.
برای این کار اولین چیزی که لازم بود دریافت و ذخیره اطلاعات بود که من برای این کار از Entity framework  4.1 Database-first و کتابخانه  htmlagilitypack - HAP استفاده کردم . طراحی دیتابیس نهایی به این صورت شد

خوب در تلاش اول و مبتدیانه و بدون استفاده از این کتابخانه مفید چون اکثر صفحات وب XHTML نیستند و بالاخره چند تگ درست بسته نشده دارند و شما اگر بخواهید در آبجکت  XmlDocument این html‌های به ظاهر سالم رو لود کنید فورا با استثنای زیر مواجه می‌شوید
XmlException Was unhandeled  
The 'img' start tag on line 1 position 1604 does not match the end tag of 'a'. Line 1, position 1766
راه حل ساده اینه که این کتابخونه رو با کمک NuGet نصب کنید
PM> Install-Package HtmlAgilityPack 
و از اینجا به بعد با کدی مثل این میتونید از کلاس HtmlDocument و مشابه XmlDocument ولی بدون ارور استفاده کنید.
 مثلا با  کد زیر میشه تاریخ تولد یک ورزشکار رو بدست آورد .توابع دیگه ای که خیلی جاها میتونه بدرد خورد GetAttributeValue و ChildNodes هست که یک نمونه نحوه استفادشو در ادامه میبینید
HtmlDocument xhtml = Crawler.GetXHtmlFromUri("http://www.london2012.com/athlete/hadadi-ehsan-1077408/");
HtmlNode tempNode = xhtml.DocumentNode.SelectSingleNode("//table[@class='athleteBio']/tbody/tr[4]");
string temp = tempNode.FirstChild.FirstChild.InnerText.Replace("&nbsp;", "").Trim(); athlete.Birthday = DateTime.Parse(temp.Substring(0, 10), new CultureInfo("en-GB"));
tempNode = xhtml.DocumentNode.SelectSingleNode("//div[@class='athletePhotoMedals']/div/div/img"); athlete.LargePhotoUri = tempNode.GetAttributeValue("src", ""); 
البته تابع GetXHtmlFromUri رو جدا باید با کمک HttpWebRequest بنویسید و توی خوده HAP متاسفانه چنین تابعی توکار نشده
نکته اصلی هم پیدا کردن محل دقیق اطلاعاته که با ابزاری مثل Firebug خیلی راحت‌تر میشه این کارو انجام داد. کافیه روی تاریخ تولد راست کلیک و  inspect element by Firebug رو بزنید و حالا اگر تویه  dom روی هر المنت html نگه دارید بهتون XPath کامل رو میده که میتونید تویه تابع DocumentNode.SelectSingleNode  ازش استفاده کنید.



برای درک بهتر XPath  هم این 2 تا صفحه  xpath_syntax و xpath_examples خیلی میتونه کمکتون بکنه.
نظرات مطالب
خودکار کردن تعاریف DbSetها در EF Code first
الف)
- تمام مدل‌های شما باید از کلاس مشخصی مثلا BaseEntity مشتق شوند.
- یا در تنظیمات برنامه مشخص کنید در حین Reflection چه فضای نامی باید جستجو شود.
- و یا مثلا مانند ASP.NET MVC اگر کلاسی نامش به عبارت خاصی ختم شد و همچنین از کلاس پایه خاصی نیز مشتق شده بود آنگاه بررسی شود.
ب)
- مرحله بعد اندکی ویرایش متد loadEntities است جهت خواندن مدل‌های واقع شده مثلا در یک فضای نام خاص یا مشتق شده از یک کلاس پایه خاص و سپس افزودن خودکار آن‌ها به modelBuilder همانند چیزی که در مثال فوق پیاده سازی شده.
در مثال بالا فقط یک اسمبلی جستجو می‌شود؛ اگر نیاز است تمام اسمبلی‌های بارگذاری شده در برنامه جستجو شوند، روش کار مراجعه به AppDomain است:
foreach (Assembly currentassembly in AppDomain.CurrentDomain.GetAssemblies()) 
{
   Type t = currentassembly.GetType("typeName", false, true);
    if (t != null) {return currentassembly.FullName;}
}
مطالب
بررسی نحوه‌ی راه اندازی پروژه‌ی Decision
پروژه‌ی Decision را می‌توان چکیده‌ی تمام مطالب سایت دانست که در آن جمع آوری نکات ASP.NET MVC 5.x، EF Code First 6.x، مباحث تزریق وابستگی‌ها، کار با AutoMapper، بوت استرپ 3 و غیره لحاظ شده‌اند. به همین جهت درک آن بدون مطالعه‌ی « تمام » مطالب سایت میسر نیست و همچنین راه اندازی آن.
در این مطلب با توجه به سؤالات زیادی که در مورد صرفا نحوه‌ی اجرای بدون خطای آن وجود داشت، ریز مراحل آن‌را بررسی می‌کنیم.


پیشنیازهای توسعه‌ی برنامه
- با توجه به استفاده از ویژگی‌های C# 6 در این پروژه، حتما نیاز است برای کار و اجرای آن از VS 2015 استفاده کنید.
- همچنین این پروژه از قابلیت «فایل استریم» SQL Server استفاده می‌کند. بنابراین نیاز است نگارش متناسبی از SQL Server را پیشتر نصب کرده باشید (هر نگارشی بالاتر از SQL Server 2005).
- اگر از ReSharper استفاده می‌کنید، به صورت موقت آن‌را به حالت تعلیق درآورید (منوی tools، گرینه‌ی options و انتخاب resharper و سپس suspend کردن آن). این مورد سرعت بازیابی بسته‌های نیوگت را به شدت افزایش می‌دهد.


بازیابی وابستگی‌های نیوگت پروژه

مرسوم نیست چند 10 مگابایت وابستگی‌های پروژه را به صورت فایل‌های باینری، به مخزن کدها ارسال کرد. از این جهت که نیوگت بر اساس مداخل فایل‌های packages.config، قابلیت بازیابی و نصب خودکار آن‌ها را دارد. بنابراین ابتدا package manger console را باز کنید؛ از طریق منوی Tools -> NuGet Package Manager -> Package Manager Console


همانطور که در تصویر مشاهده می‌کنید، نیوگت تشخیص داده‌است که بسته‌هایی برای نصب وجود دارند. بنابراین بر روی دکمه‌ی restore کلیک کنید تا کار دریافت و نصب خودکار این بسته‌ها از اینترنت شروع شود. البته اگر پیشتر این بسته‌ها را در پروژه‌های دیگری نصب کرده باشید، نیوگت از کش موجود در سیستم استفاده خواهد کرد و برای دریافت آن‌ها به اینترنت مراجعه نمی‌کند. ولی در هر حال اتصال به اینترنت ضروری است.

پس از پایان کار بازیابی بسته‌ها، یکبار کل Solution را Build کنید تا مطمئن شوید که تمام بسته‌های مورد نیاز به درستی بازیابی و نصب شده‌اند (Ctrl+Shift+B و یا همان منوی Build و انتخاب گزینه‌ی Build Solution).



تنظیمات رشته اتصالی بانک اطلاعاتی برنامه

پس از Build موفق کل Solution در مرحله‌ی قبل، اکنون نوبت به برپایی تنظیمات بانک اطلاعاتی برنامه است. برای این منظور فایل web.config ذیل را باز کنید:
Decision\src\Decision.Web\Web.config
یک چنین تنظیمی را مشاهده می‌کنید:
  <connectionStrings>
    <clear />
    <add name="DefaultConnection" connectionString="Data Source=.\sqlexpress;Initial Catalog=DecisionDb;Integrated Security = true;MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />
  </connectionStrings>
از آنجائیکه بر روی سیستم من SQL Server نگارش Developer نصب است و از SQL Server Express استفاده نمی‌کنم، تنظیمات فوق را به نحو ذیل تغییر خواهم داد:
  <connectionStrings>
    <clear />
    <add name="DefaultConnection" connectionString="Data Source=(local);Initial Catalog=DecisionDb;Integrated Security = true;MultipleActiveResultSets=True;" providerName="System.Data.SqlClient" />
  </connectionStrings>
تنها تغییر صورت گرفته، تنظیم data source است. مابقی موارد یکی است و تفاوتی نمی‌کند.

در این حالت نیاز است بانک اطلاعاتی خالی DecisionDb را خودتان ایجاد کنید. علت آن به AutomaticMigrationsEnabled = false بر می‌گردد؛ که در ادامه توضیح داده شده‌است و همچنین وجود تنظیم ذیل در فایل Decision\src\Decision.Web\App_Start\ApplicationStart.cs
 Database.SetInitializer<ApplicationDbContext>(null);
این تنظیم و نال بودن پارامتر ورودی آن به این معنا است که اولا برنامه یک بانک اطلاعاتی جدید را به صورت خودکار ایجاد نمی‌کند و همچنین کار Migrations خودکار نیست.


ایجاد بانک اطلاعاتی برنامه و تنظیمات آن

پس از آن، نوبت به ایجاد بانک اطلاعاتی برنامه است. چون این برنامه از EF Code first استفاده می‌کند، قادر است بانک اطلاعاتی ذکر شده‌ی در Initial Catalog فوق را به صورت خودکار ایجاد کند (با تمام جداول، روابط و تنظیمات آن‌ها). این اطلاعات هم از پروژه‌ی Decision.DataLayer و پوشه‌ی Migrations آن تامین می‌شوند.
اگر به فایل Decision\src\Decision.DataLayer\Migrations\201602072159421_Initial.cs مراجعه کنید، یکسری تنظیمات دستی را هم علاوه بر کدهای خودکار EF، مشاهده خواهید کرد:
 //. . .
Sql("EXEC sp_configure filestream_access_level, 2");
Sql("RECONFIGURE", true);

Sql("alter database DecisionDb Add FileGroup FileGroupApplicant contains FileStream", true);
Sql("alter database DecisionDb add file ( name = 'ApplicantDocuements'  ,  filename = 'C:\\FileStream\\ApplicantDocuements') to filegroup FileGroupApplicant", true);
//. . .
این‌ها مواردی هستند که کار تنظیمات فایل استریم را به صورت خودکار انجام می‌دهند.
بنابراین نیاز است در درایور C، پوشه‌ی خالی FileStream از پیش تهیه شده باشد (نیازی به ایجاد پوشه‌ی ApplicantDocuements نیست و این پوشه به صورت خودکار ایجاد می‌شود).

و در فایل Decision\src\Decision.DataLayer\Migrations\Configuration.cs مشخص شده‌است که AutomaticMigrationsEnabled = false. به این معنا که تنظیمات فوق به صورت خودکار به بانک اطلاعاتی اعمال نشده و باید چند دستور ذیل را به صورت دستی صادر کنیم:
الف) ابتدا package manager console را مجددا باز کنید و در اینجا default project را بر روی Decision.DataLayer قرار دهید. از این جهت که قرار است اطلاعات migration را از این پروژه دریافت کنیم:


در غیراینصورت پیام خطای No migrations configuration type was found in the assembly را دریافت خواهید کرد.

ب) سپس دستور ذیل را صادر کنید (با این فرض که بانک اطلاعاتی خالی DecisionDb ذکر شده‌ی در قسمت قبل را پیشتر ایجاد کرده‌اید):
 PM> Update-Database -Verbose -ConnectionStringName "DefaultConnection" -StartUpProjectName "Decision.Web"
این تنظیمات به این معنا است که Update-Database را بر اساس اطلاعات پروژه‌ی Decision.DataLayer انجام بده (همان انتخاب default project)؛ اما رشته‌ی اتصالی را از پروژه‌ی Decision.Web و تنظیمات DefaultConnection آن دریافت کن.

من در این حالت پیام خطای Update-Database : The term 'Update-Database' is not recognized as the name of a cmdlet را دریافت کردم.
راه حل: یکبار ویژوال استودیو را بسته و مجددا باز کنید تا کار نصب بسته‌ها و بارگذاری تمام وابستگی‌های آن‌ها به درستی صورت گیرد. این خطا به این معنا است که هرچند NuGet کار نصب EF را انجام داده‌است، اما هنوز اسکریپت‌های پاورشل آن که دستوراتی مانند Update-Database را اجرا می‌کنند، بارگذاری نشده‌اند. راه حل آن بستن و اجرای مجدد ویژوال استودیو است.
پس از اجرای مجدد ویژوال استودیو و انتخاب default project صحیح (مطابق تصویر فوق)، مجددا دستور Update-Database  فوق را صادر کنید (با پارامترهای ویژه‌ی آن).
با صدور این دستور، پیام خطای ذیل را دریافت کردم:
 The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework'
registered in the application config file for the ADO.NET provider with invariant name 'System.Data.SqlClient' could not be loaded.
برای رفع آن نیاز است EF را یکبار دیگر نصب کنید:
 PM> Update-Package -Reinstall "EntityFramework" -ProjectName "Decision.DataLayer"
در ادامه مجددا کل Solution را Build کنید؛ چون Migrations بر اساس اطلاعات اسمبلی‌های کامپایل شده‌ی پروژه کار می‌کند.
اینبار دستور update-database فوق (با پارامترهای ویژه‌ی آن) بدون مشکل اجرا شد و بانک اطلاعاتی مربوطه تشکیل گردید.




اکنون برنامه قابل اجرا است و در این حالت است که می‌توان دکمه‌ی F5 را جهت اجرای برنامه فشرد. البته در این حالت بر روی پروژه‌ی Decision.Web کلیک راست کرده و گزینه‌ی set as startup project را نیز انتخاب کنید و سپس F5:



لطفا سؤالاتی را که مرتبط با «راه اندازی» این پروژه نیستند، در قسمت بازخوردهای اختصاصی آن مطرح کنید.
مطالب
بهبود کارآیی کنترل‌های لیستی WPF در حین بارگذاری تعداد زیادی از رکوردها
کنترل‌های WPF در حالت پیش فرض و بدون اعمال قالب خاصی به آن‌ها عموما خوب عمل می‌کنند. مشکل از جایی شروع می‌شود که قصد داشته باشیم حالت پیش فرض را اندکی تغییر دهیم و یا Visual tree این کنترل‌ها اندکی پیچیده شوند. برای نمونه مدل زیر را در نظر بگیرید:
using System;

namespace WpfLargeLists.Models
{
    public class User
    {
        public int Id { set; get; }
        public string FirstName { set; get; }
        public string LastName { set; get; }
        public string Address { set; get; }
        public DateTime DateOfBirth { set; get; }
    }
}
قصد داریم فقط 1000 رکورد ساده از این مدل را به یک ListView اعمال کنیم.
                    <ListView ItemsSource="{Binding UsersTab1}" Grid.Row="1" Margin="3">
                        <ListView.View>
                            <GridView>
                                <GridViewColumn Header="Id" Width="50" DisplayMemberBinding="{Binding Id, Mode=OneTime}" />
                                <GridViewColumn Header="FirstName" Width="100" DisplayMemberBinding="{Binding FirstName, Mode=OneTime}" />
                                <GridViewColumn Header="LastName" Width="100" DisplayMemberBinding="{Binding LastName, Mode=OneTime}" />
                                <GridViewColumn Header="Address" Width="100" DisplayMemberBinding="{Binding Address, Mode=OneTime}" />
                                <GridViewColumn Header="DateOfBirth" Width="150" DisplayMemberBinding="{Binding DateOfBirth, Mode=OneTime}" />
                            </GridView>
                        </ListView.View>
                    </ListView>
در اینجا UsersTab1، لیستی حاوی فقط 1000 رکورد از شیء User است. در حالت معمولی این لیست بدون مشکل بارگذاری می‌شود. اما با اعمال مثلا قالب MahApp.Metro، بارگذاری همین لیست، حدود 5 ثانیه با CPU usage صد در صد طول می‌کشد. علت اینجا است که در این حالت WPF سعی می‌کند تا ابتدا در VisualTree، کل 1000 ردیف را کاملا ایجاد کرده و سپس نمایش دهد.


راه حل توصیه شده برای بارگذاری تعداد بالایی رکورد در WPF  : استفاده از UI Virtualization

UI Virtualization روشی است که در آن تنها المان‌هایی که توسط کاربر در حال مشاهده هستند، تولید و مدیریت خواهند شد. در این حالت اگر 1000 رکورد را به یک ListBox یا ListView ارسال کنید و کاربر بر اساس اندازه صفحه جاری خود تنها 10 رکورد را مشاهده می‌کند، WPF فقط 10 عنصر را در VisualTree مدیریت خواهد کرد. با اسکرول به سمت پایین، مواردی که دیگر نمایان نیستند dispose شده و مجموعه نمایان دیگری خلق خواهند شد. به این ترتیب می‌توان حجم بالایی از اطلاعات را در WPF با میزان مصرف پایین حافظه و همچنین مصرف CPU بسیار کم مدیریت کرد. این مجازی سازی در WPF به وسیله VirtualizingStackPanel در دسترس است.

برای اینکه WPF virtualization به درستی کار کند، نیاز است یک سری شرایط مقدماتی فراهم شوند:
- از کنترلی استفاده شود که از virtualization پشتیبانی می‌کند؛ مانند ListBox و ListView.
- ارتفاع کنترل لیستی باید دقیقا مشخص باشد؛ یا درون یک ردیف از Grid ایی باشد که ارتفاع آن مشخص است. برای نمونه اگر ارتفاع ردیف Grid ایی که ListView را دربرگرفته است به * تنظیم شده، مشکلی نیست؛ اما اگر ارتفاع این ردیف به Auto تنظیم شده، کنترل لیستی برای محاسبه vertical scroll bar خود دچار مشکل خواهد شد.
- کنترل مورد استفاده نباید در یک کنترل  ScrollViewer محصور شود؛ در غیر اینصورت virtualization رخ نخواهد داد. علاوه بر آن در خود کنترل باید خاصیت ScrollViewer.HorizontalScrollBarVisibility نیز به Disabled تنظیم گردد.
- در کنترل در حال استفاده، ScrollViewer.CanContentScroll باید به true تنظیم شود.

مورد مشخص بودن ارتفاع بسیار مهم است. برای نمونه در برنامه‌ای پس از فعال سازی مجازی سازی، کنترل لیستی کلا از کار افتاد و حرکت scroll bar آن سبب بروز CPU Usage بالایی می‌شد. این مشکل با تنظیم ارتفاع آن به شکل زیر برطرف شد:
 Height="{Binding Path=RowDefinitions[1].ActualHeight, RelativeSource={RelativeSource AncestorType=Grid}}"
در این تنظیم، ارتفاع کنترل، به ارتفاع سطر دوم گرید دربرگیرنده ListView متصل شده است.

- پس از اعمال موارد یاد شده، باید VirtualizingStackPanel کنترل را فعال کرد. ابتدا دو خاصیت زیر باید مقدار دهی شوند:
   VirtualizingStackPanel.IsVirtualizing="True"
  VirtualizingStackPanel.VirtualizationMode="Recycling"
سپس ItemsPanelTemplate کنترل باید به صورت یک VirtualizingStackPanel مقدار دهی شود. برای مثال اگر از ListBox استفاده می‌کنید، تنظیمات آن به نحو زیر است:
 <ListBox.ItemsPanel>
    <ItemsPanelTemplate>
          <VirtualizingStackPanel IsVirtualizing="True" VirtualizationMode="Recycling" />
    </ItemsPanelTemplate>
</ListBox.ItemsPanel>
و اگر از ListView استفاده می‌شود، تنظیمات آن مشابه ListBox است:
 <ListView.ItemsPanel>
    <ItemsPanelTemplate>
          <VirtualizingStackPanel
               IsVirtualizing="True"
               VirtualizationMode="Recycling" />
    </ItemsPanelTemplate>
</ListView.ItemsPanel>
با این توضیحات ListView ابتدای بحث به شکل زیر تغییر خواهد یافت تا مجازی سازی آن فعال گردد:
                    <ListView ItemsSource="{Binding UsersTab2}" Grid.Row="1" Margin="3"
                              ScrollViewer.HorizontalScrollBarVisibility="Disabled"
                              ScrollViewer.CanContentScroll="True"
                              VirtualizingStackPanel.IsVirtualizing="True"
                              VirtualizingStackPanel.VirtualizationMode="Recycling">
                        <ListView.ItemsPanel>
                            <ItemsPanelTemplate>
                                <VirtualizingStackPanel 
                                        IsVirtualizing="True" 
                                        VirtualizationMode="Recycling" />
                            </ItemsPanelTemplate>
                        </ListView.ItemsPanel>
                        <ListView.View>
                            <GridView>
                                <GridViewColumn Header="Id" Width="50" DisplayMemberBinding="{Binding Id, Mode=OneTime}" />
                                <GridViewColumn Header="FirstName" Width="100" DisplayMemberBinding="{Binding FirstName, Mode=OneTime}" />
                                <GridViewColumn Header="LastName" Width="100" DisplayMemberBinding="{Binding LastName, Mode=OneTime}" />
                                <GridViewColumn Header="Address" Width="100" DisplayMemberBinding="{Binding Address, Mode=OneTime}" />
                                <GridViewColumn Header="DateOfBirth" Width="150" DisplayMemberBinding="{Binding DateOfBirth, Mode=OneTime}" />
                            </GridView>
                        </ListView.View>
                    </ListView>
کدهای کامل مثال فوق را از اینجا می‌توانید دریافت کنید: WpfLargeLists.zip
در این مثال دو برگه را ملاحظه می‌کنید. برگه اول حالت normal ابتدای بحث است و برگه دوم پیاده سازی UI Virtualization را انجام داده است.