نظرات مطالب
مقایسه بین حلقه های تکرار (Lambda ForEach و for و foreach)
یک روش ساده : 
Stopwatch sw = Stopwatch.StartNew();
var ListOfNumber = new List<int>() { 100, 200, 300 , 400 , 500  };
for ( int i = 0 ; i < ListOfNumber.Count ; i++ )
{
       Console.WriteLine( ListOfNumber[i] );
}
sw.Stop();
Console.WriteLine("Total time (ms): {0}", (long) sw.ElapsedMilliseconds);

نظرات مطالب
NHibernate و مدیریت خودکار تغییرات ساختار بانک اطلاعاتی
در بیشتر شرکت هایی که به طریقی میخوان از بانک هم ورژن داشته باشند معمولا کنار هر پروژه یک پروژه از نوع بانک ساخته میشه (فقط MS SQL) ولی با این امکان NHibernate دیگه احتیاجی به نگهداری یک پروژه موازی نیست، همه تسک ها بصورت مجتمع و مدیریت شده در کلاسهای سطح سلوشن نگهداری میشه.
واقعا پست هاتون برای توسعه دهنده ها یه نوع واکسیناسیون میمونه ;)
نظرات مطالب
هزینه استفاده از دات نت فریم ورک چقدر است؟
علاوه بر مطالبی که دوستان در مورد اشتراک MSDN و فواید آن گفتند ... برنامه‌ی دیگری به نام bizspark از طرف مایکروسافت برای شرکت‌های تازه تاسیس و کمک به آن‌ها وجود دارد. به این ترتیب به مدت سه سال مشترک MSDN خواهید شد و تنها 100 دلار در پایان سه سال باید پرداخت کنید. در طی این مدت دسترسی قانونی به تمام محصولات مهم مایکروسافت را دارید (VS2010, Office2010, MS Axapta, SQL SERVER, SERVER 2008, Windows 7-8 و ...)
http://www.microsoft.com/bizspark/
نظرات مطالب
هزینه استفاده از دات نت فریم ورک چقدر است؟
علاوه بر مطالبی که دوستان در مورد اشتراک MSDN و فواید آن گفتند ... برنامه‌ی دیگری به نام bizspark از طرف مایکروسافت برای شرکت‌های تازه تاسیس و کمک به آن‌ها وجود دارد. به این ترتیب به مدت سه سال مشترک MSDN خواهید شد و تنها 100 دلار در پایان سه سال باید پرداخت کنید. در طی این مدت دسترسی قانونی به تمام محصولات مهم مایکروسافت را دارید (VS2010, Office2010, MS Axapta, SQL SERVER, SERVER 2008, Windows 7-8 و ...)
http://www.microsoft.com/bizspark/
نظرات مطالب
بررسی واژه کلیدی static
با سلام خدمت استاد نصیری
جناب نصیری طبق نکت آخر پس اینکه ما میام برای استفاده از jQuery Ajax از متدهای استاتیک استفاده میکنیم کار خوبی نمیکنیم؟آخه این تنها راه هست.
یه سوال دیگه هم داشتم که MS Ajax چطور میتونه متدهای غیر استاتیک صفحه رو هم صدا بزنه در حالی که ما در jQuery فقط قادر به صدا زدن متدهای استاتیک هستیم؟
سپاسگزارم
مطالب
OpenCVSharp #5
استفاده از پنجره‌ی native خود OpenCV، روش مرسومی است در زبان‌های مختلف برنامه نویسی که از OpenCV استفاده می‌کنند و این پنجره مستقل است از سکوی کاری مورد استفاده. اما شاید در دات نت علاقمند باشید که نتیجه‌ی عملیات را در یک picture box استاندارد نمایش دهید. در ادامه، تبدیل تصاویر OpenCV را به فرمت دات نت، در دو قالب برنامه‌های WinForms و همچنین WPF، بررسی خواهیم کرد.


استفاده از OpenCVSharp در برنامه‌های WinForms به کمک PictureBoxIpl

یکی از اسمبلی‌های کتابخانه‌ی OpenCVSharp را که در پوشه‌ی bin برنامه می‌توان مشاهده کرد، OpenCvSharp.UserInterface.dll نام دارد. این اسمبلی حاوی یک picture box جدید به نام PictureBoxIpl است که می‌تواند تصاویری را با فرمت IplImage، دریافت کند.


می‌توانید این picture box ویژه را از طریق منوی ToolBox -> Choose items و سپس صفحه‌ی دیالوگ فوق، به نوار ابزار WinForms اضافه کرده و از آن استفاده کنید و یا می‌توان با کدنویسی نیز به آن دسترسی یافت:
using (var iplImage = new IplImage(@"..\..\Images\Penguin.png", LoadMode.Color))
{
    Cv.Dilate(iplImage, iplImage);
 
    var pictureBoxIpl = new OpenCvSharp.UserInterface.PictureBoxIpl
    {
        ImageIpl = iplImage,
        AutoSize = true
    };
    flowLayoutPanel1.Controls.Add(pictureBoxIpl); 
}
در اینجا تصویر مورد نظر را توسط کلاس IplImage بارگذاری کرده و سپس برای نمونه فیلتر Dilate را به آن اعمال کرده‌ایم. سپس وهله‌ی جدیدی از کنترل PictureBoxIpl ایجاد و خاصیت ImageIpl آن، به تصویر بارگذاری شده، تنظیم و در آخر این picture box با کدنویسی به صفحه اضافه شده‌است.

یک نکته
هر نوع تغییری به iplImage پس از انتساب آن به خاصیت ImageIpl، نمایش داده نخواهد شد. برای به حداقل رساندن سربار ایجاد اشیاء جدید (خصوصا برای نمایش اطلاعات رسیده‌ی از دوربین یا WebCam)، از متد RefreshIplImage استفاده کنید. این متد بجای ایجاد یک شیء جدید، تنها ناحیه‌ی موجود را مجددا ترسیم خواهد کرد و بسیار سریع است:
 pictureBoxIpl.RefreshIplImage(iplImage);


استفاده از OpenCVSharp در برنامه‌های WinForms به کمک PictureBox

اگر نخواهید از کنترل جدید PictureBoxIpl استفاده کنید، می‌توان از همان Picture box استاندارد WinForms نیز کمک گرفت:
Bitmap bitmap;
using (var iplImage = new IplImage(@"..\..\Images\Penguin.png", LoadMode.Color))
{
    bitmap = iplImage.ToBitmap(); // BitmapConverter.ToBitmap()
}
 
var pictureBox = new PictureBox
{
    Image = bitmap,
    ClientSize = bitmap.Size
}; 
 
flowLayoutPanel1.Controls.Add(pictureBox);
تنها نکته‌ای که در اینجا جدید است، استفاده از متد الحاقی ToBitmap می‌باشد که در کلاس BitmapConverter کتابخانه‌ی OpenCVSharp تعریف شده‌است. به این ترتیب تصویر با فرمت OpenCV، به یک Bitmap دات نتی تبدیل می‌شود. اکنون می‌توان این بیت‌مپ را برای مثال به یک Picture box استاندارد انتساب داد و یا حتی متد Save آن‌را فراخوانی کرد و آن‌را بر روی دیسک سخت، ذخیره نمود.

یک نکته
در اینجا نیز برای به حداقل رسانی به روز رسانی‌های بعدی picture box بهتر است از متد ToBitmap به شکل زیر کمک گرفت:
 iplImage.ToBitmap(dst: (Bitmap)pictureBox.Image);
به این ترتیب سربار وهله سازی یک شیء جدید Bitmap حذف خواهد شد و صرفا ناحیه‌ی نمایشی مجددا ترسیم می‌شود.





استفاده از OpenCVSharp در برنامه‌های WPF

در WPF می‌توان با استفاده از متد الحاقی ToWriteableBitmap کلاس BitmapConverter، فرمت IplImage را به منبع تصویر یک کنترل تصویر استاندارد، تبدیل کرد:
using System.Windows.Media;
using OpenCvSharp;
using OpenCvSharp.Extensions;
 
namespace OpenCVSharpSample05Wpf
{
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            loadImage();
        }
 
        private void loadImage()
        {
            using (var iplImage = new IplImage(@"..\..\Images\Penguin.png", LoadMode.Color))
            {
                Cv.Dilate(iplImage, iplImage);
 
                Image1.Source = iplImage.ToWriteableBitmap(PixelFormats.Bgr24);
            }
        }
    }
}

کدهای کامل WPF و WinForms این مطلب برای دریافت.
مطالب
بهبود کارآیی کنترل‌های لیستی 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 را انجام داده است.

نظرات مطالب
تولید فایل‌های اکسل حرفه‌ای بدون نیاز به نصب مجموعه‌ی آفیس
پروژه PdfReport، برای تهیه خروجی اکسل، از همین کتابخانه استفاده می‌کند. متدی که در آن تصویر را به یک سلول اضافه می‌کند، به شرح زیر است (پارامتر data آن محتوای تصویر است؛ مثلا File.ReadAllBytes):
        void addImageFromStream(byte[] data)
        {
            if (data == null) return;
            using (var ms = new MemoryStream(data))
            {
                var image = Image.FromStream(ms);
                _worksheet.Row(_row).Height = (image.Height + 1).Pixel2RowHeight();
                _worksheet.Column(_col).Width = _worksheet.Pixel2ColumnWidth(image.Width + 1);
                var picture = _worksheet.Drawings.AddPicture("pic" + _row + _col, image);
                picture.From.Column = _col - 1;
                picture.From.Row = _row - 1;
                picture.From.ColumnOff = 2.Pixel2Mtu();
                picture.From.RowOff = 2.Pixel2Mtu();
                picture.SetSize(image.Width, image.Height);
            }
        }
مطالب
تجزیه یک رشته به کلمات تشکیل دهنده آن توسط Recursive CTE
برای پردازش یک عبارت در بسیاری از موارد نیاز هست که عبارت به کلمات تشکیل دهنده اش تجزیه شود. روش‌های متنوعی برای انجام این عمل وجود دارد که یکی از شناخته شده‌ترین آنها استفاده از جدول اعداد می‌باشد (البته از بین روش‌های مجموعه گرا/set -based).
روشهایی که قرار هست در ادامه توضیح داده شوند بر اساس کوئری بازگشتی می‌باشند. الگوریتم‌های متنوعی بر اساس recursive CTE برای حل این مساله خلق شده اند. که من تنها به دو روش آن اکتفا می‌کنم.

Recursive CTE در نسخه‌ی 2005 به SQL Server اضافه شده است. توسط این تکنیک مسائل پیچیده و گوناگونی را میتوان بسادگی حل نمود. مخصوصا مسائلی که ماهیت بازگشتی دارند مثل پیمایش یک درخت یا پیمایش یک گراف وزن دار.

روش اول:

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

توضیح تکنیک:
در گام اول اندیس شروع و پایان کلمه اول را بدست می‌آوریم.
سپس در گام بعدی از اندیس پایان کلمه قبلی به عنوان اندیس شروع کلمه جدید استفاده می‌کنیم.
و اندیس پایان کلمه توسط تابع charindex بدست می‌آید.
کوئری تا زمانی ادامه پیدا میکند که کلمه برای تجزیه کردن در رشته باقی مانده باشد. فقط فراموش نکنید که حتما باید آخر عبارت یک کارکتر space داشته باشید.
DECLARE @S VARCHAR(50)='I am a student I go to school ';
WITH CTE AS 
(
     SELECT 1 rnk,
            1 start,
            CHARINDEX(' ', @s) - 1 ed

     UNION ALL
 
     SELECT rnk + 1,
            ed + 2,
            CHARINDEX(' ', @s, ed + 2) - 1
       FROM CTE
      WHERE CHARINDEX(' ', @s, ed + 2) > 0
)
SELECT rnk, SUBSTRING(@s, start, ed - start + 1) AS word
FROM CTE
  
/* Result
rnk         word
----------- -------
1           I
2           am
3           a
4           student
5           I
6           go
7           to
8           school
*/



روش دوم:
در این روش در همان CTE عبارت تجزیه می‌شود و عمل تفکیک به مرحله بعدی واگذار نمی‌شود،
در گام اول، اولین کلمه انتخاب می‌شود. و سپس آن کلمه از رشته حذف می‌شود. با این روش همیشه اندیس شروع کلمه برابر با 1 خواهد بود و اندیس پایان کلمه توسط تابع charindex بدست خواهد آمد.
در گام بعدی اولین کلمه موجود در رشته ای که قبلا اولین کلمه از آن جدا شده است بدست می‌آید و باز مثل قبلی کلمه انتخاب شده از رشته جدا شده و رشته برش یافته به مرحله بعد منتقل می‌شود.
در این روش مثل روش قبلی آخر عبارتی که قرار هست تجزیه شود باید یک کارکتر خالی وجود داشته باشد.
DECLARE @a VARCHAR(50)='I am a student I go to school ';
 
WITH MyWords(ranking, word, string) AS(
 
    SELECT 1,
           CAST(SUBSTRING(@a, 1, CHARINDEX(' ', @a) - 1) AS VARCHAR(25)),
           STUFF(@a, 1, CHARINDEX(' ', @a), '')
  
    UNION ALL
  
    SELECT ranking + 1,
           CAST(SUBSTRING(string, 1, CHARINDEX(' ', string) - 1) AS VARCHAR(25)),
           STUFF(string, 1, CHARINDEX(' ', string), '')
      FROM MyWords
     WHERE CHARINDEX(' ', string) > 0
)
SELECT ranking, word FROM MyWords;
و خروجی:
ranking     word
----------- -------------------------
1           I
2           am
3           a
4           student
5           I
6           go
7           to
8           school

نظرات مطالب
EF Code First #14
مدیریت Context (یا همان سیستم ردیابی خودکار به بیانی دیگر) در برنامه‌های ویندوزی «معمولی» مانند WPF یا WinForms یا سرویس‌های ویندوز NT و ...، یا در سطح فرم است (با آغاز فرم، Context، وهله سازی می‌شود و با بسته شدن آن خاتمه خواهد یافت) یا در طی یک عملیات کوتاه مانند کلیک بر روی یک دکمه فعال و سپس Dispose می‌شود. یکی از این دو حالت رو بسته به سناریویی که دارید می‌تونید دنبال کنید.
شما شیء Context رو در سطح فرم تعریف می‌کنید (چون می‌تونید؛ چون برنامه‌های ویندوزی متفاوت‌اند از برنامه‌های وب بدون حالت که در آن‌ها پس از نمایش صفحه، کلیه اشیاء تخریب می‌شوند)، حالا هر شیءایی که اضافه بشه، به Context جاری اضافه شده، حذف بشه از این مرجع حذف شده یا اگر ویرایش شود باز هم به صورت خودکار، تحت نظر Context تعریف شده در سطح فرم است. نهایتا با فراخوانی یک SaveChanges تمام این تغییرات بدون نیاز به محاسبه خاصی در کدهای ما، توسط EF اعمال می‌شوند. سیستم Tracking به صورت خودکار، کوئری‌های insert، update و delete رو محاسبه و اجرا می‌کنه. نیازی به مدیریت خاصی بجز تعریف Context در سطح فرم نداره.
به صورت خلاصه مرسوم نیست در مثلا WinForms «متداول»، منقطع از Context کار کرد، چون اساسا می‌شود به سادگی، تا زمانیکه یک فرم در حال نمایش است، Context و سیستم ردیابی خودکار آن‌را زنده نگه داشت و از آن استفاده کرد.