Tuesday, October 28, 2008

Farsi Library - FAQ

A lot of people keep asking me to provide a VB.NET Sample on how to use Farsi Library component. The library is written in C# after all and no sample code is provided to demonstrate VB.NET usage. This post is not a tutorial to Farsi Library per se. I'm answering some of the question regarding VB.NET usage, and some common questions about Farsi Library you've kept asking.

Yet, there are still some people don't know how to create an explicit Main method in VB.NET, so if this post is a low-level for you professionals, just skip this post ;)

Q : I'm using VB.NET but there's no main method to set my thread's culture!

A : Since everything supposed to be easier in VB.NET, you normally do not create an entry point for an application written in VB.NET, but only select a form which is the startup form of your application. To have more control on application initializations, you need to write the application entry method as well. Simply add a new Module (e.g. Named Program) and add a method to initialize and run the main form :

Public Module Program
<STAThread()> _
Public Sub Main()
Application.Run(New MainForm())
End Sub
End Module

To actually use this Main method, open the Project's properties by double-clicking on "My Project" in solution explorer and in the Application Tab, uncheck the check box that reads "Enable Application Framework" and set your startup object as "Sub Main".

Now when running your application, the main form is created through the Main method in Program class. You can set a breakpoint to check if it is working. Easily add any additional initialization logic to the Main method. To set the running thread's Culture use this code :

Imports System.Threading
Imports System.Globalization

Public Class Program
<STAThread()> _
Public Shared Sub Main()
Thread.CurrentThread.CurrentUICulture = New CultureInfo("fa-ir")
Thread.CurrentThread.CurrentCulture = New CultureInfo("fa-ir")

Application.Run(New MainForm())
End Sub
End Class

Q : I'm running a form with Farsi Library controls. All the dates are in Gregorian calendar.

A : You need to set the running thread's culture information to "fa-ir" culture to see the Persian Calendar information. For Arabic calendar, use "ar-sa" culture.

Q : I've downloaded the source files but it won't compile. When compiling the sources VS.NET says the license key is missing.

A : Farsi Library is an open source project. There's no such thing as license key in this project. To be able to use the compiled dll in certain scenarios (Putting them in GAC, etc.) you need to specify a key which VS.NET uses to sign the built assemblies. You can create a key file using SN utility (provided with Visual Studio .NET) and put it in a path specified in CommonAssemblyInfo.cs (default value is C:\KeyFile.snk) :

C:\>sn -k KeyFile.snk

Q : How can I use the Farsi Library on a Web Site or Web Project?

A : I was going to provide an ASP.NET Server control in one of the first releases, but since my web project was canceled, there's no ASP.NET control available. However, you can use the FarsiLibrary.Utils project to convert dates on a web project.

Q : I have downloaded the binary files. What should I do with them? How can I use the controls?

A : First, put the dll files somewhere near your solution / project (e.g. in a Lib folder). Then, you should add controls to VS.NET Toolbox. To do this, open the Toolbox window, right-click and select "Choose Items..." from the menu. On the next dialog, select "Browse..." button and select the "FarsiLibrary.Win.dll" file (or "FarsiLibrary.WPF" if you're working on a WPF project). All the controls will be added to your toolbox. You can simply drag-and-drop them on your form.

Q : I'm working on an application that uses a Database to store dates. On the UI I need to display dates in Persian Calendar. What should I do?

A : Since you only need to "display" the dates in Persian Calendar, you can use DateTime data type on your entities as well as in your database designs. On the front-end, you can use FarsiLibrary controls which will bind to Business Entities, or DataSets, to display the DateTime value in Persian Calendar. You don't need to (and you're strongly advised not to!) use string data type (or other types) to support dates in Persian or other Calendars.

Q : What type of look and feel does the control support?

A : Controls support System Theme (Windows XP, Vista, etc.) plus Office 2000, Office 2003, and partial Office 2007 themes. You can set each control's theme using Theme property, or use the global theme manager :

FAThemeManager.Theme = ThemeTypes.Office2007

Q : How do I change the strings used in controls? How can I localize the strings?

A : Create a class and inherit from one of the available Localizer classes in FarsiLibrary.Resources namespace. Override GetLocalizedString method and provide a suitable representation for StringIDs you want. Later set the instance of your localizer on FALocalizeManager :

Public Class ESLocalizer
Inherits ENLocalizer

Public Overrides Function GetLocalizedString(ByVal id As Resources.StringID) As String
Select Case
Case StringID.Validation_NullText
Return "<Ningun fecha esta seleccionada>"
Case StringID.FAMonthView_None
Return "Nada"
Case StringID.FAMonthView_Today
Return "¡Hoy!"
End Select

Return MyBase
End Function
End Class
FALocalizeManager.Instance.CustomLocalizer = New ESLocalizer()

Q : I want to use the controls in another calendar. Can I use other cultures (e.g. "es-ES" culture) when using these controls?

A : To globally change the culture set an instance of your culture on CustomCulture property of FALocalizeManager :

FALocalizeManager.Instance.CustomCulture = New CultureInfo("es-ES")

Q : How can I do validation to check if a selected date is correct? How do I restrict the selection to a specific date range?

A : Use the SelectedDateTimeChanging event and set the e.Cancel to true. You can also set an error message on e.Message :

Private Sub faDatePicker_SelectedDateTimeChanging(ByVal sender As System.Object, ByVal e As FarsiLibrary.Win.Events.SelectedDateTimeChangingEventArgs) Handles faDatePicker2.SelectedDateTimeChanging
Dim pd As PersianDate = e.NewValue

If pd.Day <> 20 And Not faDatePicker2.IsNull Then
e.Message = "Invalid date. Default Date is applied."
e.NewValue = New DateTime(2010, 1, 20, 0, 0, 0)
End If
End Sub

Q : How can I custom draw a certain day in calendar? How can I draw the holidays in red?

A : You need to plug-in your drawing logic on DrawCurrentDay event. You have access to Day / Month / Year values as well as Graphics object. A Rectange representing date bounds is also available. Remember to set the IsHandled to true if you want to override the base class drawing logic :

Private Sub faMonthView_DrawCurrentDay(ByVal sender As System.Object, ByVal e As FarsiLibrary.Win.Events.CustomDrawDayEventArgs) Handles faMonthView.DrawCurrentDay
If e.Date.DayOfWeek = DayOfWeek.Friday Then
br1 As New SolidBrush(Color.Wheat)
Dim br2 As New LinearGradientBrush(e.Rectangle, Color.PaleVioletRed, Color.DarkRed, 45, True)
Dim fnt As New Font("Tahoma", 8, FontStyle.Bold)
Dim fmt As New StringFormat
Dim dayNo As String = e.Day

fmt.Alignment = StringAlignment.Center
fmt.LineAlignment = StringAlignment.Center

e.Graphics.FillRectangle(br2, e.Rectangle)
e.Graphics.DrawString(dayNo, fnt, br1, e.Rectangle, fmt)


e.Handled = True
End If
End Sub

Q : How do I convert dates from / to PersianCalendar to / from Gregorian Calendar?

A : You can convert instances of DateTime directly to PersianDate values, which represents their equivalance in PersianCalendar :

Dim pd As PersianDate = CType(DateTime.Now, PersianDate)
lblCastTo.Text = pd.ToString("G")

Dim dt As DateTime = CType(PersianDate.Now, DateTime)
lblCastFrom.Text = dt.ToString("G")

If you're using PersianCultureInfo (which uses standard .NET Framework Persian Calendar), you have access to all standard DateTime formattings as well. See MSDN page for standard and custom date formattings.

Q : I need to do calculations in Persian Calendar. I need to add / remove days to / from specific day in the Persian Calendar.

A : You can use the PersianCalendar class provided in .NET Framework to do so. There's an internal implementation of PersianCalendar in FarsiLibrary.Utils namespace which originally was historically developed before PersianCalendar appearing in .NET 2 :

Dim calendar As New PersianCalendar()
Dim pd = New PersianDate(calendar.AddYears(DateTime.Now, 10))
lblMessage.Text = pd.ToString()
lblToWritten.Text = pd.ToWritten()

You can download VB.NET code related to this FAQ from here.

Submit this story to DotNetKicks Shout it


TearsOfDevil said...

CustomDrawDayEventArgs dosen't have e.Date.DayOfWeek or such a thing in version RC2 or NightBuild.
Please help

TearsOfDevil said...
This comment has been removed by the author.
TearsOfDevil said...

I made a simple code to save end-user selection into DB, and also i wanna show current date(as a default date ofcourse).

But when i reclaim SelectedDate as
mw.SelectedDateTime = DateTime.Now.Date;

an event occurs and it assumes that end-user selected a new date !

How can i prevent it ?!