نظرات مطالب
C# 6 - String Interpolation

یک نکته‌ی تکمیلی: در نگارش‌های جدیدتر دات‌نت، بجای متد Invariant از متد string.Create استفاده کنید

همانطور که پیشتر نیز عنوان شد، formattable stringها، بر اساس فرهنگ جاری سیستم عامل، خروجی را تغییر می‌دهند. یعنی حاصل نهایی رشته‌ی "{Id} :value"$ بسته به فرهنگ جاری، می‌تواند یکبار با اعداد انگلیسی و بار دیگر با اعداد فارسی جایگزین شود. برای عدم مواجه شدن با یک چنین ناهماهنگی‌هایی، استفاده از متد System.FormattableString.Invariant بر روی یک چنین رشته‌هایی، توصیه می‌شد. اکنون (از زمان NET Core 2.1. به بعد)، استفاده از متد string.Create بجای آن توصیه می‌شود که سرعت بیشتری داشته و همچنین مصرف حافظه‌ی کمتری را نیز به همراه دارد.

همچنین اگر علاقمند هستید تا این موارد را به صورت یک خطا دریافت کنید و مجبور به تغییر آن‌ها شوید، یک سطر زیر را به فایل editorconfig. خود اضافه کنید؛ که مرتبط است به Meziantou.Analyzer:

dotnet_diagnostic.MA0111.severity = error
نظرات مطالب
ترفندهای یونیکد برای زبان‌های راست به چپ
سلام. بسیار استفاده بردیم. اما یک سوال؛ من دیتایی مثل تصویر زیر دارم. اما وقتی اعداد وارد میکنم و اسلش میزنم، رشته به هم میریزه:

من میخوام مثل فایل ورد باشه و همه چیز سرجاش. اما وقتی همون فایل ورد کپی می‌گیرم داخل Notpad به هم میزه. از روش شما استفاده کردم. تونستم جمله‌ی فارسی+انگلیسی بنویسم. البته من می‌خوام اول بنویسم dvd/214/CharFarsi/121/452/12. اما همیشه اون بخش CharFarsi میره به آخر. ممنون میشم بهم یاد بدید که چطوری از کاربر بگیرم که به هم نریزه و حتی وقتی سرچ میکنم رشته رو بدون مشکل پیداش کنم.

نظرات مطالب
تبدیل عدد به حروف
چند بحث کلی اینجا هست:
- چون عموما از عدد به حروف در گزارشات مالی استفاده می‌شود، اعداد همه int و big int هستند. بنابراین آنچنان کاربرد دنیای واقعی ندارد سایر حالت‌ها.
- بحث اضافه کردن سایر زبان‌ها ... خوب، بستگی به تسلط به زبان‌های مختلف هم دارد. مثلا در انگلیسی می‌گویند Three hundred اما در فارسی مرسوم نیست که کسی بگه «سه صد». به همین جهت یک قسمت اضافه‌تر برای معرفی سیصد و امثال آن در کد فوق وجود دارد. به احتمال زیاد زبان‌های دیگر هم ریزه‌کاری‌های خاص خودشان را دارند.
- بحث سرعت را هم در نظر بگیرید. در این نوع الگوریتم‌ها به علت استفاده مکرر، ترجیح داده می‌شود که از کالکشن‌های تشکیل شده در حافظه (بجای خواندن از فایل) جهت سرعت بالاتر دسترسی به اطلاعات و سربار کمتر استفاده شود.
نظرات مطالب
معرفی برنامه‌ی Subtitle Tools
یه نفر هم پیشنهاد اصلاح متون حاوی فارسی-انگلیسی رو برای زیرنویس ها داده بود که یه برنامه کوچولو براش نوشتم.
http://salarblog.wordpress.com/2010/04/18/correct-persian-english-text-to-display-in-left-to-right-direction/#comment-484

دانلود برنامه:
http://www.4shared.com/file/ET-QeiW7/PersianLeftToRightCorrection.html
نظرات مطالب
اشتباهات متداول برنامه‌نویس‌های دات نت
سلام

یک مقایسه. تصویر بدون به هم ریختگی هم در ie و هم فایرفاکس
http://tinyurl.com/ahkw5u
http://tinyurl.com/asohbo
و تصویری که در ie کاملن سالم است و در فایرفاکس فقط یک کلمه آن جلو و عقب شده است
http://tinyurl.com/cf2yos

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

به نظر من نمیرسد مشکل حادی در این رابطه وجود داشته باشد و شاید هم بنده کاملن مقصود شما را متوجه نشده ام که ممنون میشوم توضیح بدهید. در عین حال یک پست در رابطه با فید پرشین بلاگرز را در حال آماده کردن هستم که بزودی پست میکنم. در این پست مقایسه بیشتری به عمل خواهد آمد.
نظرات نظرسنجی‌ها
آخرین باری که یک کتاب فارسی را در زمینه‌ی دات نت خریدید، کی بوده؟
آخرین کتابی که خریدم فکر کنم کتاب اسکرام و کتاب مهندسی نیازها بود و ^  
------------------------------------------------------------------------
با گفته این دوستمون هم شدیدا موافقم :
"سری آموزشی ASP.NET MVC وحید نصیری که اگه چاپ شده بود حتما می‌خریدمش "

البته به نظر بنده یک کتاب که 0 تا 100 زدن یک پروژه MVC اصولی رو یاد بده واقعا نیاز است
من شخصا حاضرم تا 200 تومن هم پای یک جلد این کتاب بدم :دی
کنابی که بیاد از 0 ام وی سی، EF Code First ، مباحث معکوس سازی مسئولیت‌ها و تزریق وابستگی و IDENTITY رو بصورت پشت سر هم و به ترتیب توضیح بده و کاملا عملی هم باشه.
(مخصوصا IDENTITY که چند روزیه سر شخصی سازیش به مشکل خوردم و 3 روزه مقالات مختلف فارسی و انگلیسی رو دارم زیر و رو میکنم :(  )
نظرات مطالب
Angular CLI - قسمت ششم - استفاده از کتابخانه‌های ثالث
یک نکته‌ی تکمیلی: تغییرات در فایل angular-cli.json نیاز به راه اندازی مجدد watchers را دارد

فرض کنید برنامه را توسط دستورات ng build --watch و یا ng serve -o تهیه و یا اجرا کرده‌اید. در این حال، برای مثال جهت افزودن مجموعه آیکن‌های قلم font-awesome به صورت زیر عمل کرده‌اید:
 npm install font-awesome --save
و سپس تعریف css آن‌را نیز به قسمت styles فایل angular-cli.json افزوده‌اید:
"styles": [
   "../node_modules/bootstrap/dist/css/bootstrap.css",
   "../node_modules/font-awesome/css/font-awesome.css",
   "styles.css"
],
اکنون اگر برنامه مجددا به صورت خودکار build شود، فونت‌ها و آیکن‌ها را مشاهده نخواهید کرد. علت اینجا است که دستورات یاد شده که در حالت watch اجرا می‌شوند، تنها به تغییرات پوشه‌ی src واکنش نشان می‌دهند و تغییرات فایل angular-cli.json از دید آن‌ها مخفی است.
به همین جهت باید یکبار آن‌ها را بسته و مجددا از ابتدا اجرا کنید تا اینبار قلم آیکن font-awesome اعمال شده و قابل نمایش شود.
مطالب
آموزش Prism #3
در پست‌های قبلی با Prism و روش استفاده از آن آشنا شدیم (قسمت اول) و (قسمت دوم). در این پست با استفاده از Mef قصد ایجاد یک پروژه Silverlight رو به صورت ماژولار داریم. مثال پیاده سازی شده در پست قبلی را در این پست به صورت دیگر پیاده سازی خواهیم کرد.
تفاوت‌های پیاده سازی مثال پست قبلی با این پست:
  • در مثال قبل پروژه به صورت Desktop و با WPF پیاده سازی شده بود ولی در این مثال با Silverlight می‌باشد؛
  • در مثال قبل از UnityBootstrapper استفاده شده بود ولی در این مثال از MefBootstrapper؛
  • در مثال قبل هر View در یک ماژول قرار داشت ولی در این مثال هر دو View را در یک ماژول قرار دادم؛
  • در مثال قبل از Prism Libary 2.x استفاده شده بود ولی در این مثال از PrismLibrary 4.x؛
  • و...

نکته : برای فهم بهتر مفاهیم، آشنایی اولیه با MEF و مفاهیمی نظیر Export و Import و AggregateCatalog و AssemblyCatalog نیاز است. در صورتی که با این مطالب آشنایی ندارید می‌توانید از (^) شروع کنید.


برای شروع یک پروژه Silverlight ایجاد کنید. بعد از اضافه شدن دو پروژه Silverlight و Web، یک Silverlight Class Library جدید بسازید.
ابتدا یک Page ایجاد کنید و کد‌های زیر را در آن کپی کنید.
<UserControl 
             x:Class="Module1.Module1View1"
             xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk" 
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" FlowDirection="RightToLeft" FontFamily="Tahoma">
    <StackPanel>
        <sdk:DataGrid Height="100">
            <sdk:DataGrid.Columns>
                <sdk:DataGridTextColumn Header="کد" Width="50"  />
                <sdk:DataGridTextColumn Header="عنوان" Width="200" />
                <sdk:DataGridTextColumn Header="نویسنده" Width="150"  />
            </sdk:DataGrid.Columns>
        </sdk:DataGrid>
        <Button x:Name="NextViewButton"
                Width="150"
                Height="25"
                Foreground="Red"
                Background="Blue"
                Content="لیست طبقه بندی ها" />
    </StackPanel>
</UserControl>
بر روی Page مربوطه راست کلیک کنید و گزینه ViewCode را انتخاب کنید و کد‌های زیر را در آن کپی کنید.
 [Export(typeof(Module1View1))]
    public partial class Module1View1 : UserControl
    {
        [Import]
        public IRegionManager TheRegionManager { private get; set; }

        public Module1View1()
        {
            InitializeComponent();

            NextViewButton.Click += NextViewButton_Click;
        }

        void NextViewButton_Click(object sender, RoutedEventArgs e)
        {
            TheRegionManager.RequestNavigate
            (
                "MyRegion1",
                new Uri("Module1View2", UriKind.Relative),
                a => { }
            );
        }
    }
ابتدا خود این View باید حتما Export شود. در رویداد کلیک با استفاده از متد RequestNavigate می‌توانیم به View مورد نظر برای نمایش در Shell اشاره کنیم و این View در Region نمایش داده می‌شود. به دلیل اینکه در این کلاس به RegionManager نیاز داریم از ImportAttribute استفاده کردیم. این بدین معنی است که کلاس Module1View1 وابستگی مستقیم به IRegionManager دارد.

حال یک Page دیگر برای طبقه بندی کتاب‌ها ایجاد کنید و کدهای زیر را در آن کپی کنید.
<UserControl 
             xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk"  x:Class="Module1.Module1View2"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" FlowDirection="RightToLeft" FontFamily="Tahoma">
    <StackPanel>
        <sdk:DataGrid Height="100">
            <sdk:DataGrid.Columns>
                <sdk:DataGridTextColumn Header="کد" Width="150"/>
                <sdk:DataGridTextColumn Header="عنوان" Width="150"/>                
            </sdk:DataGrid.Columns>
        </sdk:DataGrid>
        <Button x:Name="NextViewButton"
                Width="150"
                Height="25"
                Foreground="Green"
                Background="Yellow"
                Content="لیست کتاب ها" />
    </StackPanel>
</UserControl>
در Code Behind این Page نیز کد‌های زیر را قرار دهید.
using Microsoft.Practices.Prism.Regions;
using System;
using System.ComponentModel.Composition;
using System.Windows;
using System.Windows.Controls;

namespace Module1
{
    [Export]
    public partial class Module1View2 : UserControl
    {
        IRegion _region1;

        [ImportingConstructor]
        public Module1View2( [Import] IRegionManager regionManager )
        {
            InitializeComponent();
         
            ViewModel viewModel = new ViewModel();
            DataContext = viewModel;

            viewModel.ShouldNavigateFromCurrentViewEvent += () => { return true; };

            _region1 = regionManager.Regions["MyRegion1"];

            NextViewButton.Click += NextViewButton_Click;
        }

        void NextViewButton_Click( object sender, RoutedEventArgs e )
        {
            _region1.RequestNavigate
            (
                new Uri( "Module1View1", UriKind.Relative ),
                a => { }
            );
        }
    }
}
در این ماژول برای اینکه بتوانیم حالت گردشی در فراخوانی ماژول‌ها را داشته باشیم ابتدا DataContext این کلاس را برابر با ViewModel ساخته شده قرار دادیم. با استفاده از رویداد ShoudlNavigateFromCurrentViewEvent که در کلاس ViewModel وجود دارد تعیین می‌کنیم که آیا باید از این View به View قبلی برگشت داشته باشیم یا نه. در صورتی که مقدار false برگشت داده شود خواهید دید که امکان فراخوانی View1 از View2 امکان پذیر نیست. در رویداد کلیک نیز همانند Page قبلی با استفاده از RegionManager و متد RequestNavigate به View مورد نظر راهبری کرده ایم.
نکته: اگر یک کلاس، سازنده با پارامتر داشته باشد باید با استفاده از ImportingConstructor حتما سازنده مورد نظر را هنگام وهله سازی مشخص کنیم در غیر این صورت با Exception مواجه خواهید شد.
حال قصد ایجاد کلاس ViewModel بالا را داریم:
using System;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.ComponentModel.Composition;
using Microsoft.Practices.Prism.Regions;

namespace Module1
{
    public class ViewModel : IConfirmNavigationRequest
    {       
        public event Func<bool> ShouldNavigateFromCurrentViewEvent;      

        public bool IsNavigationTarget( NavigationContext navigationContext )
        {
            return true;
        }

        public void OnNavigatedTo( NavigationContext navigationContext )
        {

        }

        public void OnNavigatedFrom( NavigationContext navigationContext )
        {

        }         

        public void ConfirmNavigationRequest( NavigationContext navigationContext, Action<bool> continuationCallback )
        {
            bool shouldNavigateFromCurrentViewFlag = false;

            if ( ShouldNavigateFromCurrentViewEvent != null )
                shouldNavigateFromCurrentViewFlag = ShouldNavigateFromCurrentViewEvent();

            continuationCallback( shouldNavigateFromCurrentViewFlag );
        }    
    }
}
توضیح متد‌های بالا:
  • IsNavigateTarget : برای تعیین اینکه آیا کلاس پیاده سازی کننده اینترفیس، می‌تواند عملیات راهبری را مدیریت کند یا نه.
  • OnNavigateTo : زمانی عملیات راهبری وارد View شود(بهتره بگم View مورد نظر در Region صفحه لود شود) این متد فراخوانی می‌شود.
  • OnNavigateFrom : زمانی که راهبری از این View خارج می‌شود (View از حالت لود خارج می‌شود) این متد فراخوانی خواهد شد.
  • ConfirmNavigationRequest : برای تایید عملیات راهبری توسط کلاس پیاده سازی کننده اینترفیس استفاده می‌شود. 
حال یک کلاس برای پیاده سازی و مدیریت ماژول می‌سازیم.
using Microsoft.Practices.Prism.MefExtensions.Modularity;
using Microsoft.Practices.Prism.Modularity;
using Microsoft.Practices.Prism.Regions;
using System.ComponentModel.Composition;

namespace Module1
{
    [ModuleExport(typeof(Module1Impl))]
    public class Module1Impl : IModule
    {       
        [Import]
        public IRegionManager TheRegionManager { private get; set; }     

        public void Initialize()
        {
            TheRegionManager.RegisterViewWithRegion("MyRegion1", typeof(Module1View1));

            TheRegionManager.RegisterViewWithRegion("MyRegion1", typeof(Module1View2));
        }
    }
}
همان طور که مشاهده می‌کنید از ModuleExportAttribute برای شناسایی ماژول توسط MefBootstrapper استفاده کردیم و نوع آن را Module1Imp1 قرار دادیم.  ImportAttribute استفاده شده در این کلاس و خاصیت TheRegionManager برای این است که در هنگام ساخت Instance از این کلاس IRegionManager موجود در Container باید در اختیار این کلاس قرار گیرد(نشان دهنده وابستگی مستقیم این کلاس با IRegionManager است). روش دیگر این است که در سازنده این کلاس هم این اینترفیس را تزریق کنیم.
در متد Initialize برای RegionManager دو View ساخته شده را رجیستر کردیم. این کار باید به تعداد View‌های موجود در ماژول انجام شود.
Shell
در پروژه اصلی بک Page به نام Shell ایجاد کنید و کد‌های زیر را در آن کپی کنید.
<UserControl x:Class="NavigationViaViewModel.Shell"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:prism="http://www.codeplex.com/prism" FlowDirection="RightToLeft" FontFamily="Tahoma">

    <Grid x:Name="LayoutRoot"
          Background="White">
        <TextBlock Text="لیست کتاب‌ها به همراه طبقه بندی آن ها"
                   FontSize="19"
                   Foreground="Black"
                   HorizontalAlignment="Center"
                   VerticalAlignment="Top" />
        <ContentControl HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        prism:RegionManager.RegionName="MyRegion1" />
    </Grid>
</UserControl>
همانند مثال قبلی یک ContentControl داریم و به وسیله RegionName که یک AttachedProperty است یک Region به نام MyRegion1 ایجاد کردیم. تمام ماژول‌های این مثال در این محدوده نمایش داده خواهند شد.
Bootstrapper
حال نیاز به یک Bootstrapper داریم. برای این کار یک کلاس به نام TheBootstrapper بسازید:
using Microsoft.Practices.Prism.MefExtensions;
using Microsoft.Practices.Prism.Modularity;
using System.ComponentModel.Composition.Hosting;
using System.Windows;

namespace NavigationViaViewModel
{
    public class TheBootstrapper : MefBootstrapper
    {
        protected override void InitializeShell()
        {
            base.InitializeShell();

            Application.Current.RootVisual = (UIElement)Shell;
        }

        protected override DependencyObject CreateShell()
        {
            return Container.GetExportedValue<Shell>();
        }

        protected override void ConfigureAggregateCatalog()
        {
            base.ConfigureAggregateCatalog();        
            AggregateCatalog.Catalogs.Add(new AssemblyCatalog(this.GetType().Assembly));
        }

        protected override IModuleCatalog CreateModuleCatalog()
        {
            ModuleCatalog moduleCatalog = new ModuleCatalog();
    
            moduleCatalog.AddModule
            (
                new ModuleInfo
                {
                    InitializationMode = InitializationMode.WhenAvailable,
                    Ref = "Module1.xap",
                    ModuleName = "Module1Impl",
                    ModuleType = "Module1.Module1Impl, Module1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"
                }
            );

            return moduleCatalog;
        }
    }
}
متد CreateShell اولین متد در این کلاس است که اجرا خواهد شد. بعد از متد CreateShell، متد InitializeShell اجرا خواهد شد. خاصیت Shell دقیقا به مقدار برگشتی متد CreateShell اشاره خواهد کرد. در متد InitializeShell  مقدار خاصیت Shell به RootVisual این پروژه اشاره می‌کند(مانند MainWindow در کلاس Application پروژه‌های WPF).
متد ConfigureAggregateCatalog برای مدیریت کاتالوگ‌ها و ماژول‌ها که هر کدام در یک اسمبلی جدا وجود خواهند شد استفاده می‌شود. در این متد من از AssemblyCatalog استفاده کردم. AssemblyCatalog  تمام کلاس هایی که ExportAttribute را به همراه دارند شناسایی می‌کند و آن‌ها را در Container نگهداری خواهد کرد(^). مانند یک ServiceLocator در Microsoft unity Service Locator(^) .
متد آخر به نام CreateModuleCatalog است و باید در آن تمام ماژول‌های برنامه را به کلاس ModuleCatalog اضافه کنیم. در مثال پست قبلی به دلیل استفاده از UnityBootstrapper باید این کار را از طریق BuildEvent ‌ها مدیریت می‌کردیم ولی در این جا Mef به راحتی این کار را انجام خواهد داد.
تغییرات زیر را در فایل App.Xaml قرار دهید و پروژه را اجرا کنید.
public partial class App : Application
 {
        public App()
        {
            this.Startup += this.Application_Startup;                 
            InitializeComponent();
        }

        private void Application_Startup(object sender, StartupEventArgs e)
        {
           var bootstrapper = new TheBootstrapper();
            bootstrapper.Run(); 
        }
}
با کلیک بر روی ماژول عملیات راهبری برای ماژول انجام خواهد شد.

دریافت سورس پروژه
ادامه دارد..
نظرات مطالب
فقط به خاطر یک نیم فاصله!
از اصلاح استاندارد ۲۹۰۱ سپاسگذارم و در ارتباط با
«اصولا استاندارد باید برگرفته از صنعت کشور باشد نه تحمیل بی منطق به آن.»

باید عرض کنم که با این مطلب موافقم اما دقت کنید که در استاندارد ۹۱۴۷ مزایای بسیاری هست که از آن جمله می توان به داشتن کاراکترهای RLE- lRE - RLO - LRO - و چند کاراکتر بدربخور دیگر و همچنین سایر کاراکترهای مورد نیاز در فارسی برای مثال حروف «» که باید در فارسی بجای () استفاده شوند نیز هست
گرچه خودمن در ۹۵ درصدر موارداز همین () استفاده می کنم و حتی اینکه سایر کیبورد ها هم در بعضی موارد این کلیدهای «» را در بردارند اما در نظر داشته باشید که گرداوری این کلیدها و چینش آن در کنار هم امر بسیار مهمی است.
من هم امیدوارم که در آینده صنعت کشور از تولید کیبوردهای غیراستاندارد دست برداشته و با فشار موسسه استاندارد از صفحه کلید جدید استفاده کند
خود من خیلی به تعویض این رویه با تعویض قالب استاندارد در خود ویندوز امیدوار هستم و سعی می کنم برای استفاده از این قالب کیبورد به همه گوشزدهای کافی را بکنم و شاید با این کار استفاده از فونت های غیراستاندارد و غیر یونیکد بخصوص فونتهای سری‫ B منسوخ شود
بازخوردهای پروژه‌ها
خطا هنگام ایجاد هدر سفارشی با html
من میخواستم بااستفاده از html هدرم رو طراحی کنم ولی با خطاهای زیر روبرو میشم : 
[0] = {"Object reference not set to an instance of an object."}
[1] = {"The document has no pages."}

نمیدونم چون که نگارش پایین این کتابخانه رو استفاده میکنم این مشکل بوجود میاد یا نه؟
کدهای من :
PdfReport pdfrpt = new PdfReport();
                pdfrpt.DocumentPreferences(doc =>
                {
                    doc.RunDirection(PdfRunDirection.RightToLeft);
                    doc.Orientation(PageOrientation.Portrait);
                    doc.PageSize(PdfPageSize.A4);
                    doc.DocumentMetadata(new DocumentMetadata { Author = "Hovze", Application = "PdfRpt", Keywords = "Report", Subject = "Test Rpt", Title = "Report" });
                    doc.Compression(new CompressionSettings
                    {
                        EnableCompression = true,
                        EnableFullCompression = true
                    });
                    doc.PrintingPreferences(new PrintingPreferences
                    {
                        ShowPrintDialogAutomatically = true
                    });
                })
                .DefaultFonts(fonts =>
                {
                    fonts.Path(fontPath + "\\BNAZANIN.ttf", fontPath + "\\BNAZNNBD.ttf");
                    fonts.Size(13);
                })
                .PagesFooter(footer =>
                {
                    footer.DefaultFooter(PersianDate.ToPersianDateTime(DateTime.Now, "/", false, false));
                })
                .PagesHeader(header =>
                {
                    
                    header.HtmlHeader(rptheader =>
                    {
                        rptheader.PageHeaderProperties(new HeaderBasicProperties
                        {
                            RunDirection = PdfRunDirection.RightToLeft,
                            ShowBorder = true
                        });
                        rptheader.AddPageHeader(pageHeader =>
                        {
                            var message = "باسمه تعالی " + "</br>" + "حوزه علمیه امیر المومنین (ع) - معاونت آموزش - کارنامه تحصیلی طلبه";
                            var image = string.Format("<img src='{0}' />", imgPath);
                            return string.Format(@"<table style='width: 100%;font-size:9pt;font-family:BNAZANIN;'>
            <tr>
            <td align='center'>{0}</td>
            </tr>
            <tr>
            <td align='center'><b>{1}</b></td>
            </tr>
            <tr>
            <td align='center'>{2}</td>
            </tr>
                </table>", image, message, " تاریخ  " + PersianDate.ToPersianDateTime(DateTime.Now.Date, "/", false));
                        });

                    });
                })
                .MainTableTemplate(template =>
                {
                    template.BasicTemplate(BasicTemplate.SilverTemplate);
                })
                .MainTablePreferences(table =>
                {
                    table.ColumnsWidthsType(TableColumnWidthType.Relative);
                    table.NumberOfDataRowsPerPage(0);
                    table.GroupsPreferences(new GroupsPreferences
                    {
                        GroupType = GroupType.HideGroupingColumns,
                        RepeatHeaderRowPerGroup = true,
                        ShowOneGroupPerPage = true,
                        SpacingBeforeAllGroupsSummary = 10f,
                    });
                })
                .MainTableDataSource(dataSource =>
                {
                    dataSource.DataTable(dt);
                })
                .MainTableSummarySettings(summarySettings =>
                {
                    summarySettings.PreviousPageSummarySettings("نقل از صفحه قبل");
                })
                .MainTableColumns(columns =>
                {
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("سال");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Center);
                        column.IsVisible(true);
                        column.Order(0);
                        column.Width(2);
                        column.HeaderCell("سال تحصیلی");
                    });
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("نیمسال");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(1);
                        column.Width(1);
                        column.HeaderCell("نیمسال");
                       
                    });
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("پایه");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(2);
                        column.Width(1);
                        column.HeaderCell("پایه");
                    });
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("درس");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(3);
                        column.Width(1);
                        column.HeaderCell("درس");
                    });
                    for (int i = 6; i < countScore + 6; i++)
                    {
                            columns.AddColumn(column =>
                        {
                            column.PropertyName(dt.Columns[i].ToString());
                            column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                            column.IsVisible(true);
                            column.Order(i - 2);
                            column.Width(1);
                            column.HeaderCell(dtTitle.Rows[0][i - 5].ToString());
                        });
                     
                    }
                    
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("FinalScore1");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(countScore + 4);
                        column.Width(1);
                        column.HeaderCell("نمره نهایی");
                    });
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("t_term1");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(countScore+5);
                        column.Width(1);
                        column.HeaderCell("نمره تجدیدی");
                    });
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("t_term11");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(countScore + 6);
                        column.Width(1);
                        column.HeaderCell("نمره استادیاری");
                    });
                   
                   
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("tabestan1");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(countScore + 10);
                        column.Width(1);
                        column.HeaderCell("نمره تابستان");
                    });
                    
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("viewTermic");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(countScore + 11);
                        column.Width(1);
                        column.HeaderCell("ترم نمایشی");
                    });
                    columns.AddColumn(column =>
                    {
                        column.PropertyName("Ghabol");
                        column.CellsHorizontalAlignment(PdfRpt.Core.Contracts.HorizontalAlignment.Left);
                        column.IsVisible(true);
                        column.Order(countScore + 12);
                        column.Width(1);
                        column.HeaderCell("قبول");
                    });
                });
               

                return  pdfrpt.MainTableEvents(events =>
                   {
                       events.DataSourceIsEmpty(message: "داده ای برای نمایش وجو د ندارد");
                       events.MainTableAdded(args =>
                       {
                           var taxTable = new PdfPTable(1);  // Create a clone of the MainTable's structure
                           taxTable.RunDirection = 3;
                           //taxTable.SetWidths(new float[] { 3, 3, 3 });
                           taxTable.WidthPercentage = 100f;
                           taxTable.SpacingBefore = 10f;

                           taxTable.AddSimpleRow(
                               (data, cellProperties) =>
                               {
                                   data.Value = "مهر و امضای مدیر";
                                   cellProperties.ShowBorder = false;
                                   cellProperties.HorizontalAlignment = HorizontalAlignment.Left;
                                   cellProperties.PdfFont = args.PdfFont;
                               });
                           args.PdfDoc.Add(taxTable);
                       });
                   })
                .Export(export =>
                {
                    // export.ToExcel();
                })
                .Generate(data => data.AsPdfFile(fo.Name));
               
            }