مطالب
WF:Windows Workflow #۴
 Flowchart Workflow

در این قسمت به ساخت یک Workflow از طریق Flowchart می‌پردازیم. در Workflow هایی که از طریق Flowchart تعریف می‌شوند٬ فعالیت‌ها به صورت درختی تعریف شده و با هم در ارتباط بوده و ارتباط آنها از طریق درخت‌های تصمیم گیری می‌باشد.
برای استفاده از آن، از قسمت Toolbox ٬ قسمت Flowchart ٬ کنترل Flowchart را به داخل صفحه کشیده، حال می‌توانیم از دیگر کنترل‌ها در درون Flowchart استفاده کنیم.
نکته :  تفاوتی که در Sequence و Flowchart است، در نحوه اجرای فعالیت‌ها می‌باشد. در Sequence فعالیت‌ها همانطور که از بالا به پایین چیده شده است اجرا می‌شوند٬ ولی در Flowchart می‌توان در خواست‌هایی را که جهت اجرای فعالیت‌ها فرستاده می‌شوند، کنترل کرد.

FlowDecision
این کنترل برای مشخص کردن یک شرط می‌باشد و بر اساس این شرط٬ این کنترل می‌تواند دو خروجی داشته باشد. یکی در صورت درست بودن شرط و دیگری در صورت غلط بودن. این شرط  هم مانند دستور IF یک خصوصیت شرط دارد که در قسمت Properties آن مشخص می‌شود.


DateTime.Now.Hour==1
اگر به برچسب‌های True و False دقت کنید٬ خروجی‌های کنترل را نشان می‌دهند. این نوشته‌ها ثابت نیستند و می‌توانید با انتخاب کنترل، از قسمت Properties آنها را عوض کنید.
نکته : به عکس بالا دقت کنید. زمانیکه از کنترل خروجی گرفته شده است٬ سمت پیکان‌ها به سمت کنترل WriteLine می‌باشد و این به این معنا می‌باشد که این پیکان از کنترل Decision به سمت پاین کشیده شده است. اگر این کار را بر عکس انجام دهیم دیگر کنترل Decision کنترل WriteLine  را نمی‌شناسد و در صورت درست بودن شرط در خروجی مقداری چاپ نمی‌شود.
در کنترل Flowchart امکان استفاده از کنترل Sequence  وجود دارد و همینطور بالعکس. این امر بستگی به نوع فرآیند شما دارد که چه موقع باید از ساختار ترتیبی استفاده شود و کجا درختی و شاید این امکان وجود داشته باشد که فرآیند مورد نظر ترکیبی از دو باشد.
Flow Switch
زمانیکه از کنترل Decision استفاده می‌کنید٬ محدود می‌شوید به دو مقدار True و False. ولی زمانیکه از کنترل Flow Switch یا Switch استفاده می‌کنید٬ این محدودیت از بین می‌رود و شما می‌توانید n دستور عمل را اجرا کنید. این کنترل دقیقا شبیه دستور Switch Case در #C عمل می‌کند.
نحوه کار کردن آن به این صورت می‌باشد که ابتدا کنترل را انتخاب کرده٬ سپس از قسمت Properties ٬ در قسمت Expression آن، مقدار مورد نظر خود را وارد می‌کنیم. اینجا این سئوال پیش می‌آید این کنترل از کجا متوجه می‌شود که خروجی Expression  آن باید از چه نوعی باشد؟ اگر به شکل کنترل Flow Switch ٬ در قسمت Toolbox دقت کرده باشید می‌بینید که نحوه نوشتن آن مانند این است که یک Generic Class تعریف کرده باشیم و دقیقا به همین صورت می‌باشد. زمانیکه این کنترل به درون کنترل Flowchart کشیده می‌شود، شکل زیر نمایان خواهد شد.

همانطور که مشاهده می‌کنید نوع T، از نوع عددی صحیح تعیین شده و این نوع، مقدار پیش فرض است. البته می‌توان این نوع را عوض کرد. T می‌تواند از نوع Object، مثلا کلاس دانش آموزان باشد و یا از نوع یک Workflow دیگر٬ که در جلسات بعدی توضیح داده خواهد شد.

همانطور که در شکل بالا مشاهده می‌کنید از کنترل Decision دو خروجی گرفته شده است و هر دو به کنترل Switch ٬ اشاره دارند. این امر به این معنا می‌باشد که شرط در هر حالتی که باشد٬ چه درست چه غلط، پس از چاپ رشته مورد نظر، به کنترل Switch اشاره می‌کند.
Convert.ToInt32(((DateTime.Now.Month % 12) + 1) / 4) 
شرط کنترل Switch در بالا مشخص شده است و بر اساس عددی که بر می‌گرداند٬ رشته مورد نظر را چاپ می‌کند. همچنین یک مقدار Default وجود دارد که حتما باید مشخص شود.
Parallel
از این کنترل برای اجرای هم زمان چندین فعالیت استفاده می‌شود . 
به مثال زیر توجه کنید :

در کنترل‌های WriteLine کد زیر نوشته شده است :
"Time: " + DateTime.Now.TimeOfDay.ToString() 
"Date: " + DateTime.Now.Date.ToShortDateString() 
"Today is: " + DateTime.Now.ToString("dddd") 
کنترل Parallel باعث می‌شود ٬ که سه رشته هم زمان در خروجی چاپ شود .


اگر به عکس بالا دقت کنید٬ از بین حالت‌های مختلفی که کنترل Switch می‌تواند داشته باشد٬ یک اتصال به کنترل Parallel صورت گرفته و این به آن معنا است که در هر حالتی کنترل Parallel انجام می‌گیرد. البته شایان ذکر است که این روش را می‌توان محدود کرد.
مطالب
چگونه تشخیص دهیم UI Virtualization در WPF خاموش شده است؟
در مطلب «بهبود کارآیی کنترل‌های لیستی WPF در حین بارگذاری تعداد زیادی از رکوردها» عنوان شد که در حالت فعال بودن UI Virtualization، فقط به تعداد ردیف‌های نمایان، اشیاء متناظری به یک کنترل لیستی اضافه می‌شوند و حالت برعکس آن زمانی است که ابتدا کلیه اشیاء بصری یک لیست تولید شده و سپس لیست نهایی نمایش داده می‌شود.

سؤال: چگونه می‌توان تعداد اشیاء اضافه شده به Visual tree یک کنترل لیستی را شمارش کرد؟

شبیه به افزونه FireBug فایرفاکس، برنامه‌ای به نام Snoop نیز جهت WPF تهیه شده است که با تزریق خود به درون پروسه برنامه، امکان بررسی ساختار Visual tree کل یک صفحه را فراهم می‌کند. برای دریافت آن به آدرس ذیل مراجعه نمائید:

پس از دریافت، ابتدا مثال انتهای بحث «بهبود کارآیی کنترل‌های لیستی WPF در حین بارگذاری تعداد زیادی از رکوردها» را اجرا کرده و سپس برنامه Snoop را نیز جداگانه اجرا نمائید. اگر نام برنامه WPF مورد نظر، در لیست برنامه‌های تشخیص داده شده توسط Snoop ظاهر نشد، یکبار بر روی دکمه Refresh آن کلیک نمائید. پس از آن برنامه نمایش لیست‌ها را در Snoop انتخاب کرده و دکمه کنار آیکن minimize کردن Snoop را کشیده و بر روی پنجره برنامه رها کنید. شکل زیر ظاهر خواهد شد:


بله. همانطور که ملاحظه می‌کنید، در برگه Slow version به علت فعال نبودن مجازی سازی UI، تعداد اشیاء موجود در Visual tree کنترل لیستی، بالای 10 هزار مورد است. به همین جهت بارگذاری آن بسیار کند انجام می‌شود.
اکنون همین عملیات کشیدن و رها کردن دکمه بررسی Snoop را بر روی برگه دوم برنامه انجام دهید:


در اینجا چون مجازی سازی UI فعال شده است، فقط به تعداد ردیف‌های نمایان به کاربر، اشیاء لازم جهت نمایش لیست، تولید و اضافه شده‌اند که در اینجا فقط 188 مورد است و در مقایسه با 10 هزار مورد برگه اول، بسیار کمتر می‌باشد و بدیهی است در این حالت مصرف حافظه برنامه بسیار کمتر بوده و همچنین سرعت نمایش لیست نیز بسیار بالا خواهد بود.
مطالب
روش استفاده‌ی از jQuery در برنامه‌های AngularJS 2.0
استفاده‌ی گسترده‌ی از jQuery به همراه برنامه‌های AngularJS 2.0 ایده‌ی خوبی نیست؛ زیرا jQuery و کدهای آن، ارتباط تنگاتنگی را بین DOM و JavaScript برقرار می‌کنند که برخلاف رویه‌ی فریم‌ورک‌های MVC است. اما با این حال استفاده‌ی از افزونه‌های بی‌شمار jQuery در برنامه‌های AngularJS 2.0، جهت غنا بخشیدن به ظاهر و همچنین کاربردپذیری برنامه، یکی از استفاده‌های پذیرفته شده‌ی آن است.
روش استفاده‌ی از jQuery نیز در حالت کلی همانند مطلب «استفاده از کتابخانه‌های ثالث جاوا اسکریپتی در برنامه‌های AngularJS 2.0» است؛ اما به همراه چند نکته‌ی اضافه‌تر مانند محل فراخوانی و دسترسی به DOM، در کدهای یک کامپوننت.


هدف: استفاده از کتابخانه‌ی Chosen

می‌خواهیم جهت غنی‌تر کردن ظاهر یک دراپ داون در برنامه‌های AngularJS 2.0، از یک افزونه‌ی بسیار معروف jQuery به نام Chosen استفاده کنیم.


تامین پیشنیازهای اولیه

می‌توان فایل‌های این کتابخانه را مستقیما از GitHub دریافت و به پروژه اضافه کرد. اما بهتر است این‌کار را توسط bower مدیریت کنیم. این کتابخانه هنوز دارای بسته‌ی رسمی npm نیست (و بسته‌ی chosen-npm که در مخزن npm وجود دارد، توسط این تیم ایجاد نشده‌است). اما همانطور که در مستندات آن نیز آمده‌است، توسط دستور ذیل نصب می‌شود:
bower install chosen
برای مدیریت این مساله در ویژوال استودیو، به منوی project و گزینه‌ی add new item مراجعه کرده و bower را جستجو کنید:


در اینجا نام پیش فرض bower.json را پذیرفته و سپس محتوای فایل ایجاد شده را به نحو ذیل تغییر دهید:
{
    "name": "asp-net-mvc5x-angular2x",
    "version": "1.0.0",
    "authors": [
        "DNT"
    ],
    "license": "MIT",
    "ignore": [
        "node_modules",
        "bower_components"
    ],
    "dependencies": {
        "chosen": "1.4.2"
    },
    "devDependencies": {
    }
}
ساختار این فایل هم بسیار شبیه‌است به ساختار package.json مربوط به npm. در اینجا کتابخانه‌ی chosen در قسمت لیست وابستگی‌ها اضافه شده‌است. با ذخیره کردن این فایل، کار دریافت خودکار بسته‌های تعریف شده، آغاز می‌شود و یا کلیک راست بر روی فایل bower.json دارای گزینه‌ی restore packages نیز هست.
پس از دریافت خودکار chosen، بسته‌ی آن‌را در مسیر bower_components\chosen واقع در ریشه‌ی پروژه می‌توانید مشاهده کنید.


استفاده از jQuery و chosen به صورت untyped

ساده‌ترین و متداول‌ترین روش استفاده از jQuery و افزونه‌های آن شامل موارد زیر هستند:
الف) تعریف مداخل مرتبط با آن‌ها در فایل index.html
<script src="~/node_modules/jquery/dist/jquery.min.js"></script>
<script src="~/node_modules/bootstrap/dist/js/bootstrap.min.js"></script>

<script src="~/bower_components/chosen/chosen.jquery.min.js"></script>
<link href="~/bower_components/chosen/chosen.min.css" rel="stylesheet" type="text/css" />
که در اینجا jQuery و بوت استرپ و chosen به همراه فایل css آن اضافه شده‌اند.
ب) تعریف jQuery به صورت untyped
declare var jQuery: any;
همینقدر که این یک سطر را به ابتدای ماژول خود اضافه کنید، امکان دسترسی به تمام امکانات جی‌کوئری را خواهید یافت. البته بدون intellisense و بررسی نوع‌های پارامترها؛ چون نوع آن، any یا همان حالت پیش فرض جاوا اسکریپت تعریف شده‌است.


محل صحیح فراخوانی متدهای مرتبط با jQuery

در تصویر ذیل، چرخه‌ی حیات یک کامپوننت را مشاهده می‌کنید که با تعدادی از آن‌ها پیشتر آشنا شده‌‌ایم:

روش متداول استفاده از jQuery، فراخوانی آن پس از رخداد document ready است. در اینجا معادل این رخداد، hook ویژ‌ه‌ای به نام ngAfterViewInit است. بنابراین تمام فراخوانی‌های jQuery را باید در این متد انجام داد.
همچنین جی‌کوئری نیاز دارد تا بداند هم اکنون قرار است با چه المانی کار کنیم و کامپوننت بارگذاری شده کدام است. برای این منظور، یکی از سرویس‌های توکار AngularJS 2.0 را به نام ElementRef، به سازنده‌ی کلاس تزریق می‌کنیم. توسط خاصیت this._el.nativeElement آن می‌توان به المان ریشه‌ی کامپوننت جاری دسترسی یافت.
constructor(private _el: ElementRef) {
}


تهیه‌ی کامپوننت نمایش یک دراپ داون مزین شده با chosen

در ادامه قصد داریم نکاتی را که تاکنون مرور کردیم، به صورت یک مثال پیاده سازی کنیم. به همین جهت فایل جدید using-jquery-addons.component.ts را به پروژه اضافه کنید به همراه فایل قالب آن به نام using-jquery-addons.component.html؛ با این محتوا:
الف) کامپوننت using-jquery-addons.component.ts
import { Component, ElementRef, AfterViewInit } from "@angular/core";

declare var jQuery: any; // untyped

@Component({
    templateUrl: "app/using-jquery-addons/using-jquery-addons.component.html"
})
export class UsingJQueryAddonsComponent implements AfterViewInit {

    dropDownItems = ["First", "Second", "Third"];
    selectedValue = "Second";

    constructor(private _el: ElementRef) {
    }

    ngAfterViewInit() {
        jQuery(this._el.nativeElement)
            .find("select")
            .chosen()
            .on("change", (e, args) => {
                this.selectedValue = args.selected;
            });
    }
}

ب) قالب using-jquery-addons.component.html
<select>
    <option *ngFor="let item of dropDownItems"
            [value]="item"
            [selected]="item == selectedValue">
        {{item}} option
    </option>
</select>

<h4> {{selectedValue}}</h4>
با این خروجی


توضیحات

کلاس UsingJQueryAddonsComponent، اینترفیس AfterViewInit را پیاده سازی کرده‌است؛ تا توسط متد ngAfterViewInit بتوانیم با عناصر DOM کار کنیم. هرچند در کل اینکار باید صرفا محدود شود به مواردی مانند مثال جاری و در حد آغاز یک افزونه‌ی jQuery و اگر قرار است تغییراتی دیگری صورت گیرند بهتر است از همان روش binding توکار AngularJS 2.0 استفاده کرد.
در سازنده‌ی کلاس، سرویس ElementRef تزریق شده‌است تا توسط خاصیت this._el.nativeElement آن بتوان به المان ریشه‌ی کامپوننت جاری دسترسی یافت. به همین جهت است که پس از آن از متد find، برای یافتن دراپ داون استفاده شده‌است و سپس chosen به نحو متداولی به آن اعمال گردیده‌است.
در اینجا هر زمانیکه یکی از آیتم‌های دراپ داون انتخاب شوند، مقدار آن به خاصیت selectedValue انتساب داده شده و این انتساب سبب فعال سازی binding و نمایش مقدار آن در ذیل دراپ داون می‌گردد.
در قالب این کامپوننت هم با استفاده از ngFor، عناصر دراپ داون از آرایه‌ی dropDownItems تعریف شده در کلاس کامپوننت، تامین می‌شوند. متغیر محلی item تعریف شده‌ی در اینجا، در محدودی همین المان قابل دسترسی است. برای مثال از آن جهت تنظیم دومین آیتم لیست به صورت انتخاب شده، در حین اولین بار نمایش view استفاده شده‌است.


استفاده از jQuery و chosen به صورت typed

کتابخانه‌ی jQuery در مخزن کد https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/jquery دارای فایل d.ts. خاص خود است. برای نصب آن می‌توان از روش ذیل استفاده کرد:
npm install -g typings
typings install jquery --save --ambient
پس از افزودن فایل typings این کتابخانه، در ابتدای فایل main.ts یک سطر ذیل را اضافه کنید:
 /// <reference path="../typings/browser/ambient/jquery/index.d.ts" />
اینکار سبب خواهد شد تا intellisense درون ویژوال استودیو بتواند مداخل متناظر را یافته و راهنمای مناسبی را ارائه دهد.

در ادامه به فایل using-jquery-addons.component.ts مراجعه کرده و تغییر ذیل را اعمال کنید:
// declare var jQuery: any; // untyped
declare var jQuery: JQueryStatic; // typed
فایل d.ts. اضافه شده، امکان استفاده‌ی از نوع جدید JQueryStatic را مهیا می‌کند. پس از آن در کدهای تعریف شده، chosen به رنگ قرمز در می‌آید، چون در تعاریف نوع دار jQuery، این افزونه وجود خارجی ندارد. برای رفع این مشکل، فایل typings/browser/ambient/jquery/index.d.ts را گشوده و سپس به انتهای آن، تعریف chosen را به صورت دستی اضافه کنید:
interface JQuery {
   //...
   chosen(options?:any):JQuery;
}
declare module "jquery" {
   export = $;
}
به این ترتیب این متد به عنوان جزئی از متدهای زنجیروار jQuery، شناسایی شده و قابل استفاده خواهد شد.


کدهای کامل این پروژه را از اینجا می‌توانید دریافت کنید.
نظرات مطالب
EF Code First #11
اون پیاده سازی هم اشتباه است! چون متد Save داخل خود Repository است.
ضمنا اون مطالب رو بر اساس اطلاعات آن روز نوشتم. الان هم پیاده سازی UOW و Repository کاملی رو از NH‌ دارم ولی ... هیچ وقت NH رو در پروژه‌ای که از آن استفاده کردم، تغییر ندادم یا از آن repository برای Unit testing استفاده نکردم.
وابستگی به ORM در عمل زیاد خواهد بود. بنابراین تعویض آن غیرممکن می‌شود.
استفاده از بانک اطلاعاتی واقعی بهتر است و به همین جهت دو کاربردی که برای آن در اکثر سایت‌ها ذکر شده، در عمل استفاده نمی‌شود.
بنابراین استفاده از Repository صرفا پیچیدگی بی‌موردی را به سیستم تحمیل می‌کند.
نظرات مطالب
ذخیره TreeView ساخته شده توسط KendoUI در Asp.net MVC
با سلام و تشکر از شما
اگر tree دارای چک باکس باشد و بخواهیم نود هایی که چک خورده است را ذخیره کنیم چگونه عمل کنیم؟
قابلیت drag هم نداشت مهم نیست . یک tree ثابت از دیتا بیس پر می‌شود و بعد گزینه هایی که تیک دارد را در جدولی دیگر ذخیره می‌کنیم
بازخوردهای دوره
آشنایی با AOP Interceptors
- سؤال شما این بود که در کلاس اصلی من، در متدی داخل آن، با چند صدهزار رکورد کار انجام می‌شود. پاسخ این است که اصلا این پروکسی ایجاد شده ربطی به داخل متد شما ندارد. کاری به وهله سازی‌های انجام شده داخل آن نیز ندارد. invocation.Proceed یعنی این متد رو اجرا کن؛ نه اینکه هر وهله‌ای که داخل آن متد قرار می‌گیرد را نیز با پروکسی مزین کن.
- تمام ORMها برای پیاده سازی مباحث Lazy loading یک شیء پروکسی را از شیء اصلی شما ایجاد می‌کنند. نمونه‌اش را شاید با EF Code first با نام‌های خودکاری مانند ClassName_00394CF1F92740F13E3 دیده باشید؛ NHibernate هم یک زمانی از همین Castle.Core برای تدارک پروکسی‌های اشیاء استفاده می‌کرد. سربار آن در حین ایجاد چندین هزار وهله از یک شیء، در حد همان کار با ORMهایی است که هر روزه از آن‌ها استفاده می‌کنید (اگر می‌خواهید یک حسی از این قضیه داشته باشید).