مطالب
تقویم شمسی در Xamarin Forms
BitDatePicker یک Date Picker، برای استفاده در برنامه‌هایی مبتنی بر زمارین فرم (Android - iOS - UWP) است.

مهم‌ترین ویژگی ها:
  • پشتیبانی از تمامی Calendar System هایی که noda time ساپورت می‌کند؛ اعم از شمسی، قمری، میلادی و ...
  • پشتیبانی از تمامی Locale هایی که NET. پشتیبانی می‌کند؛ اعم از فارسی، عربی، انگلیسی و ...
  • قابلیت ارائه Template سفارشی شده برای UI
  • سازگار شده با MVVM
بر روی گیت هاب یک نمونه کد که در آن از کنترل BitDatePicker استفاده شده، قرار داده‌ایم. در ادامه  توضیح مختصری را از نحوه‌ی استفاده‌ی از آن داریم.

چگونه BitDatePicker را در پروژه‌ی خود داشته باشیم؟
  • دریافت و نصب پکیج Bit.CSharpClient.Controls از nuget.
  • اضافه کردن کدهای زیر در کلاس AppDelegate پروژه‌ی iOS و کلاس Main Activity در Android و کلاس App پروژه‌ی UWP قبل از Forms.Init .
BitCSharpClientControls.Init();

چگونگی استفاده از BitDatePicker در فرم Xaml: 
  • اضافه کردن namepsace های زیر در فرم Xaml:

  • xmlns:bitControls="clr-namespace:Bit.CSharpClient.Controls;assembly=Bit.CSharpClient.Controls"
    xmlns:noda="clr-namespace:NodaTime;assembly=NodaTime"

    مثال تقویم شمسی:
<bitControls:BitDatePicker
    Text="لطفا یک روز را انتخاب کنید" 
    Culture="Fa"
    DateDisplayFormat="dd MMM yyyy"
    CalendarSystem="{x:Static noda:CalendarSystem.PersianArithmetic}"
    FlowDirection="RightToLeft" 
    SelectedDate =" {Binding SelectedDate}"/>

برای داشتن تقویم شمسی  با اعداد فارسی تنها کافی است از یک Font که همیشه اعداد فارسی را در خود دارد مثل Vazir-FD-WOL، استفاده کنیم. فونتی سبک، سورس باز و زیبا! (FD مخفف Farsi Digit و WOL مخفف Without Latin است)

برای درک بهتر از نحوه‌ی استفاده‌ی از این Date Picker، نگاهی به Sample های آن بیاندازید. همچنین می‌توانید در همینجا نیز سؤالات خود را بپرسید؛ یا این که در Stackoverflow.com سوال ایجاد کنید و یا در GitHub یک Issue را ثبت کنید.

مطالب
فایل‌های chm و مشکل فارسی - قسمت اول

همانطور که مطلع هستید از ویندوز ویستا به بعد، فرمت قدیمی فایل‌های راهنمای ویندوز (فایل‌های hlp) منسوخ شده تلقی می‌شود و فرمت پیشنهادی، chm است. نرم افزارهای زیادی برای تهیه فایل‌های compiled html help یا همان chm های معروف وجود دارند که معروفترین آن‌ها برنامه‌ی Help & Manual است.
اما تمام این برنامه‌ها در حقیقت پوسته‌ای هستند برای برنامه‌ی رایگان html help work shop مایکروسافت و در نهایت از کامپایلر آن استفاده می‌کنند. بنابراین چرا از برنامه‌ی رایگان اصلی استفاده نشود؟

اگر تا به حال با html help work shop کار نکرده‌اید، در ادامه مروری سریع بر آن خواهیم داشت:

الف) درست کردن فایل‌های صفحات راهنما
برنامه‌ی Help & Manual ایی که معرفی شد و تمام نمونه‌های مشابه آن، تنها کار مهمی را که انجام می‌دهند این است که شما را از یک html editor بی‌نیاز می‌کنند. بنابراین زمانیکه می‌خواهیم از برنامه‌ی اصلی html help work shop استفاده کنیم نیاز به یک html editor خارجی برای تهیه فایل‌های راهنما خواهیم داشت. مثلا مرحوم front page یا نگارش جدید آن به نام Microsoft expression web یا Dreamweaver یا Aptana یا حتی notepad !
در اینجا تنها مشخص کردن نوع encoding نمایش صفحه برای صحیح نمایش داده شدن متون فارسی کافی است. اما این تمام ماجرا نیست.

ب) کامپایل کردن فایل‌های راهنمای ایجاد شده
برای این منظور بجای آپلود بیش از 30 تصویر جهت توضیحات قدم به قدم نحوه‌ی انجام این‌کار، یک فایل ویدیویی درست کرده‌ام که آن‌‌را از آدرس زیر می‌توانید دریافت کنید.
دریافت فایل

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

در قسمت دوم، نحوه‌ی رفع این دو مشکل (مشکل جستجوی عبارات فارسی و مشکل عنوان‌های به هم ریخته) را بررسی خواهیم کرد.

ادامه دارد ...

نظرات مطالب
OpenCVSharp #11
به طور مشخص با توجه به توضیحات بالا می‌توان گفت اگر مقدار k در الگوریتم k-means را برابر 2 در نظر بگیریم، تصویر ما به دو رنگ کوانتیزه  می‌شود
            using (var src = new Mat(@"test.jpg", LoadMode.Color))
            {
                image1.Source = KMeans(src, 2).ToWriteableBitmap();
                image2.Source = Binary(src).ToWriteableBitmap();
            }
که تقریبا با تصویر بدست آمده پس از باینری کردن آن معادل است 
        private static Mat Binary(Mat src)
        {
            // Convert the image to Gray
            src = src.CvtColor(ColorConversion.RgbToGray);
            // Convert the Gray to Binary with auto threshold
            Cv2.Threshold(src, src, 0, 255, ThresholdType.Binary | ThresholdType.Otsu);
            // Convert the Gray to Binary with manual threshold
            //Cv2.Threshold(src, src, 127, 255, ThresholdType.Binary);

            return src;
        }

        private static Mat KMeans(Mat src, int k)
        {
            var columnVector = src.Reshape(cn: 3, rows: src.Rows * src.Cols);
            var samples = new Mat();
            columnVector.ConvertTo(samples, MatType.CV_32FC3);

            var bestLabels = new Mat();
            var centers = new Mat();
            Cv2.Kmeans(
                data: samples,
                k: k,
                bestLabels: bestLabels,
                criteria: new TermCriteria(type: CriteriaType.Epsilon | CriteriaType.Iteration, maxCount: 10, epsilon: 1.0),
                attempts: 3,
                flags: KMeansFlag.PpCenters,
                centers: centers);


            var dst = new Mat(src.Rows, src.Cols, src.Type());
            for (var size = 0; size < src.Cols * src.Rows; size++)
            {
                var clusterIndex = bestLabels.At<int>(0, size);
                var newPixel = new Vec3b
                {
                    Item0 = (byte)(centers.At<float>(clusterIndex, 0)), // B
                    Item1 = (byte)(centers.At<float>(clusterIndex, 1)), // G
                    Item2 = (byte)(centers.At<float>(clusterIndex, 2)) // R
                };
                dst.Set(size / src.Cols, size % src.Cols, newPixel);
            }

            return dst;
        }

نتایج :

اشتراک‌ها
معرفی فریمورک متن باز رابط کاربری HandyControl برای WPF

یک سالی میشود که روی یک فریمورک رابط کاربری بصورت متن باز به اسم HandyControl مشارکت دارم، این فریمورک در درجه اول مخصوص برنامه نویس‌های چین طراحی شده بود اما با بازخوردهایی که دریافت کرد، جامعه انگلیسی زبان را هم پشتیبانی میکند. بدلیل اینکه هدف این فریمورک ارائه کنترل‌های ساده و بدور از پیچیدگی هست، Nabian با اضافه کردن کنترل‌های پیچیده مخالف هست. به همین دلیل تصمیم گرفتم تا شاخه جدایی از این پروژه را ایجاد کنم و کنترل‌ها و ویژگی‌های مختلفی که سازگار با برنامه نویس‌های ایرانی باشد را اضافه کنم. درحال حاضر تقویم شمسی، ساعت_تقویم شمسی، پشتیبانی از کد ملی، حروف فارسی در نوع ورودی TextBox ،استایل‌های جدید بارگذاری، کنترل BusyIndicator، کنترل سرعت شمار (SpeedoMeter) و چندین کلاس هلپر جهت کار با رجیستری، رمزنگاری و... را به پروژه اضافه کردم.(لیست ویژگی‌های اضافه شده را میتوانید از این قسمت مشاهده کنید) (جهت مشاهده کنترل‌ها و ویژگی‌های اضافه شده در نسخه شخصی سازی شده بعد از اجرای دمو از بخش Controls بخش PersianToolkit را انتخاب کنید)

صفحات پروژه اصلی===> سورس برنامه | صفحه ناگت | صفحه مارکت پلیس مستندات چینی | مستندات انگلیسی | مستندات ویکی

 اگر پیشنهادی برای اضافه کردن کدهای کاربردی یا کنترل‌های کاربردی دارید لطفا در نظرات اعلام کنید و یا اگر خودتان توانایی آن را دارید در گیتهاب PR ارسال کنید.
 

معرفی فریمورک متن باز رابط کاربری HandyControl برای WPF
مطالب
امکان انجام محاسبات سمت کلاینت در EF Core
در دنیای NET. همواره دو نوع LINQ وجود داشته داشته است: LINQ to Objects و ... مابقی.  در حالت اول با <IEnumerable<T‌ها کار می‌کنیم که تمام عملیات در حافظه انجام می‌شود و در مابقی حالات یک <IQueryable<T وجود دارد که عبارت حاصل از آن جهت کاربردهای مختلفی به زبان‌های متفاوتی مانند SQL ترجمه می‌شوند. در هر دو حالت کلی، Syntax نهایی یکی است و تنها اگر به منبع داده‌ی آن‌ها دقت کنیم، می‌توانیم نوع آن‌ها را تشخیص دهیم. برای نمونه کوئری ذیل بر اساس منبع Blogs است که می‌تواند LINQ to Objects باشد و یا حالت <Queryable<Blog که قرار است به زبانی مشخص ترجمه شود:
var blogs = from blog in Blogs
   where blog.Name.Contains("Development")
   select blog;
اکنون فرض کنید که این عبارت قرار است به SQL ترجمه شده و سپس بر روی یک بانک اطلاعاتی اجرا شود. در این حالت مفسر LINQ باید بداند که متد Contains را چگونه به معادل SQL آن ترجمه کند و این ترجمه می‌تواند بر اساس بانک‌های اطلاعاتی مختلف، متفاوت نیز باشد. اما در حالت LINQ to Objects یک چنین مشکلی وجود ندارد و این ترجمه مستقیما بر روی متد Contains کلاس string انجام می‌شود.
اما اکنون چطور؟
var blogs = from blog in Blogs
   where blog.Name.ComputeHash() == 0
   select blog;
فرض کنید یک متد الحاقی را به نام ComputeHash به کلاس string اضافه کرده‌ایم. یک چنین کوئری را اگر بر روی EF 6.x اجرا کنیم، برنامه با یک استثناء متوقف خواهد شد؛ چون امکان ترجمه‌ی متد ComputeHash را به معادل SQL آن ندارد؛ اما EF Core برای انجام یک چنین کوئری‌هایی بهبود یافته‌است که به آن، محاسبات سمت کلاینت گفته می‌شود.


یک مثال: بررسی تاثیر ارزیابی‌های سمت کلاینت در EF Core

فرض کنید ساختار جدول بلاگ‌ها به صورت زیر است:
public class Blog
{
   public int BlogId { get; set; }
   public string Url { get; set; }  
}
همچنین یک متد الحاقی را به نام ComputeHash به صورت ذیل تعریف کرده‌ایم:
    public static class StringExtensions
    {
        public static int ComputeHash(this string str)
        {
            var hash = 0;
            foreach (var ch in str)
            {
                hash += (int)ch;
            }
            return hash;
        }
    }
اکنون می‌خواهیم بلاگ‌هایی را پیدا کنیم که Hash مربوط به Url آن‌ها بیشتر از 10 است (صرفا جهت نمایش این قابلیت جدید):
using (var context = new BloggingContext())
{
   var blogs = context.Blogs
     .Where(blog => blog.Url.ComputeHash() >= 10)
     .ToList();
   Console.WriteLine(blogs.First().Url);
}
اگر این کوئری را اجرا کنیم، یک چنین خروجی SQL ایی تولید خواهد شد و همچنین برنامه کرش هم نمی‌کند:
SELECT [blog].[BlogId], [blog].[Url]
   FROM [Blogs] AS [blog]
به این معنا که در ارزیابی‌های سمت کلاینت:
الف) مفسر LINQ در EF Core، شروع به ارزیابی کوئری نوشته شده می‌کند و هرجائیکه متدی را یافت و از درک آن عاجز بود (معادل SQL ایی را برای آن نیافت)، آن‌را از کوئری حذف می‌کند.
ب) کوئری SQL نهایی بدون متد ComputeHash بر روی بانک اطلاعاتی اجرا شده و نتیجه به سمت کلاینت بازگشت داده می‌شود. به همین جهت است که در خروجی SQL فوق خبری از متد ComputeHash نیست.
ج) اکنون که EF Core اطلاعات لازم را از سمت سرور دریافت کرده‌است، متد ComputeHash را در سمت کلاینت بر روی این نتیجه‌ی دریافتی اعمال می‌کند. یعنی مرحله‌ی آخر همان LINQ to Objects متداول خواهد بود.
به این ترتیب است که EF Core قابلیت اجرای هر نوع متدی را که معادل SQL ایی برای آن وجود ندارد، خواهد یافت.


چگونه متوجه شویم که ارزیابی سمت کلاینت رخ داده‌است؟

EF Core این قابلیت را دارد تا گزارش کاملی را از ارزیابی‌های سمت کلاینت صورت گرفته ارائه دهد. هرچند در مثال فوق متد الحاقی ComputeHash بسیار واضح است، اما برای نمونه متد string.Join نیز معادل SQL ایی ندارد:
var idUrls = context.Blogs
   .Select(b => new
   {
      IdUrlString = string.Join(", ", b.BlogId, b.Url),
   }).ToList();
این مثال بدون مشکل توسط EF Core و قابلیت جدید ارزیابی سمت کلاینت آن اجرا می‌شود، اما بهتر است از وقوع یک چنین رخ‌دادهایی مطلع شویم:
    public class BloggingContext : DbContext
    {
        public BloggingContext()
        { }

        public BloggingContext(DbContextOptions options)
            : base(options)
        { }

        public DbSet<Blog> Blogs { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                optionsBuilder.UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=Demo.ClientSideEvaluation;Trusted_Connection=True;");
                optionsBuilder.ConfigureWarnings(warnings =>
                {
                    warnings.Log(CoreEventId.IncludeIgnoredWarning);
                    warnings.Log(RelationalEventId.QueryClientEvaluationWarning);
                });
            }
        }
    }
برای این منظور تنها کافی است درخواست فعالسازی لاگ کردن QueryClientEvaluationWarning را در قسمت ConfigureWarnings آن ارائه دهیم. در این حالت اگر برنامه را مجددا اجرا کنیم، ابتدا یک چنین خروجی لاگ می‌شود:
 warn: Microsoft.EntityFrameworkCore.Query[200500]
The LINQ expression 'where ([blog].Url.ComputeHash() >= 10)' could not be translated and will be evaluated locally.
عنوان کرده‌است که قابلیت ترجمه‌ی ComputeHash را به SQL نداشته و آن‌را در نهایت به صورت محلی و در سمت کلاینت محاسبه می‌کند.

اگر می‌خواهید ارزیابی سمت کلاینت را ممنوع کنید، در تنظیمات فوق warnings.Log را به warnings.Throw تغییر دهید. این مورد سبب خواهد شد تا اگر برنامه به این نوع ارزیابی‌ها رسید، با یک استثناء متوقف شود (شبیه به حالت EF 6.x).


تاثیر ارزیابی‌های سمت کلاینت بر روی کارآیی برنامه

هرچند قابلیت ارزیابی‌های سمت کلاینت بسیار مفید است اما باید دقت داشت:
الف) در این حالت چون ابتدا متدهایی که قابلیت ارزیابی در سمت سرور را دارا نیستند، حذف خواهند شد، ممکن است تمام رکوردها به سمت کلاینت بازگشت داده شده و سپس فیلترینگ نهایی در سمت کلاینت صورت گیرد. مانند مثال محاسبه‌ی hash که در SQL تولیدی آن، خبری از قسمت where نیست و این شرط در انتهای کار، در سمت کلاینت و به صورت LINQ to Objects اعمال می‌شود.
ب) این قابلیت ممکن است برنامه نویس‌ها را از تفکر در مورد یافتن روش‌های محاسباتی سمت سرور دور کند. برای مثال هر چند مثال string.Join نوشته شده در سمت کلاینت محاسبه خواهد شد و این کوئری بدون مشکل اجرا می‌شود، اما اگر آن‌را به صورت ذیل جایگزین کنیم:
var idUrls2 = context.Blogs
   .Select(b => new
   {
     IdUrlString = b.BlogId + "," + b.Url
   }).ToList();
اینبار به یک خروجی SQL قابل محاسبه‌ی در سمت سرور، خواهیم رسید:
SELECT (CAST([b].[BlogId] AS nvarchar(max)) + N',') + [b].[Url] AS [IdUrlString]
FROM [Blogs] AS [b]
به همین جهت حداقل لاگ کردن ارزیابی‌های سمت کلاینت را روشن کنید تا از وقوع یک چنین مسایلی مطلع گردید.


کدهای کامل این مثال را از اینجا می‌توانید دریافت کنید: ClientSideEvaluation.zip
پروژه‌ها
PdfReport
کتابخانه PdfReport جهت ایجاد گزارشات متنوعی با خروجی PDF کاملا سازگار با زبان فارسی تهیه شده است. استفاده از آن صرفا با کدنویسی (Code first) میسر بوده و بازه وسیعی از فناوری‌های مختلف مبتنی بر دات نت را پوشش می‌دهد؛ مانند WinForms، WPF، برنامه‌های وب و غیره و کلا هرجایی که دات نت فریم ورک 3.5 به بعد به صورت کامل در دسترس باشد.
به کمک کتابخانه PdfReport دسترسی گسترده‌ای به منابع داده‌ای مختلف خواهید یافت. منابعی که لزوما بانک اطلاعاتی نیستند؛ مانند یک لیست جنریک و یا حتی یک anonymously typed list حاصل از یک کوئری LINQ.
این کتابخانه علاوه بر تبدیل اطلاعات شما به گزارشات مبتنی بر PDF، امکان تهیه خروجی خودکار اکسل (2007 به بعد) را نیز دارد. فایل خروجی آن، به صورت پیوست درون فایل PDF تهیه شده قرار می‌گیرد و جزئی از آن می‌شود.
مسایل امنیتی مانند رمزنگاری فایل PDF حاصل و یا حتی افزودن امضای دیجیتال به فایل نهایی تولیدی نیز در آن لحاظ شده است.
کتابخانه PdfReport بر پایه کتابخانه‌های معروف سورس باز iTextSharp و EPPlus تهیه شده است. حداقل مزیت استفاده از آن، صرفه جویی در وقت شما جهت آموختن ریزه کاری‌های مرتبط با هر کدام از کتابخانه‌های یاده شده است. برای نمونه جهت فراگیری کار با iTextSharp نیاز است یک کتاب 600 صفحه‌ای به نام iText in action را مطالعه و تمرین کنید. این مورد منهای مسایل و نکات متعدد مرتبط با زبان فارسی است که در این کتاب به آن‌ها اشاره‌ای نشده است.

مطالب
نصب خودکار اطلاعات فایل‌های PFX در سیستم

در مورد نحوه رمزنگاری فایل‌های PDF به کمک روش Public-key encryption توسط iTextSharp مطلبی را پیشتر در این سایت مطالعه کرده‌اید.
این روش یک مشکل مهم دارد: «ارائه فایل PFX و همچنین کلمه عبور آن به کاربر نهایی»
خوب، این یعنی اینکه شما به راحتی می‌تونید اطلاعات را رمزگشایی کنید؛ چون همه چیز سخاوتمندانه در اختیارتان است. بنابراین ضرورت رمزنگاری آن در ابتدای امر زیر سؤال می‌رود.
اکنون این سؤال مطرح می‌شود که آیا می‌توان این اطلاعات را تا حد قابل قبولی مخفی کرد؟ مثلا یک برنامه را در اختیار کاربر قرار داد که اطلاعات فایل PFX را به همراه کلمه عبور آن در سیستم نصب کند.
پاسخ:
دات نت به صورت توکار از این نوع فایل‌های مجوز پشتیبانی می‌کند:

using System.Security.Cryptography.X509Certificates;

namespace InstallPfx
{
class Program
{
private static void InstallCertificate(string cerFileName, string password)
{
var certificate = new X509Certificate2(cerFileName, password, X509KeyStorageFlags.PersistKeySet);
var store = new X509Store(StoreName.My);
store.Open(OpenFlags.ReadWrite);
store.Add(certificate);
store.Close();
}

static void Main(string[] args)
{
InstallCertificate(@"D:\forTest\file.pfx", "123456");
}
}
}

پس از اجرای کد فوق، امکان مشاهده فایل‌های PDF رمزنگاری شده به کمک اطلاعات فایل file.pfx، میسر می‌شود.
برای مشاهده این مجوز نصب شده هم می‌توان در دیالوگ Run ویندوز نوشت : certmgr.msc تا کنسول مدیریتی مجوز‌های ویندوز ظاهر شود. سپس به قسمت personal certificates باید مراجعه کرد.