Skip to content

Commit 94b64b2

Browse files
spiegelpKeboo
authored andcommitted
Support for PersianCalendar (#1080)
* basic support for PersianCalendar * basic support for PersianCalendar * Minor code cleanup
1 parent cdb733a commit 94b64b2

File tree

3 files changed

+57
-75
lines changed

3 files changed

+57
-75
lines changed

MainDemo.Wpf/App.xaml.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ protected override void OnStartup(StartupEventArgs e)
1919
XmlLanguage.GetLanguage(CultureInfo.CurrentCulture.IetfLanguageTag)));
2020
*/
2121

22+
// test setup for Persian culture settings
23+
/*System.Threading.Thread.CurrentThread.CurrentCulture = new System.Globalization.CultureInfo("fa-Ir");
24+
System.Threading.Thread.CurrentThread.CurrentUICulture = new System.Globalization.CultureInfo("fa-Ir");
25+
FrameworkElement.LanguageProperty.OverrideMetadata(typeof(FrameworkElement), new FrameworkPropertyMetadata(
26+
System.Windows.Markup.XmlLanguage.GetLanguage(System.Globalization.CultureInfo.CurrentCulture.IetfLanguageTag)));*/
27+
2228
base.OnStartup(e);
2329
}
2430
}

MaterialDesignThemes.Wpf/DateTimeEx.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ internal static DateTimeFormatInfo GetDateFormat(this CultureInfo culture)
1010
{
1111
if (culture == null) throw new ArgumentNullException(nameof(culture));
1212

13-
if (culture.Calendar is GregorianCalendar)
13+
if (culture.Calendar is GregorianCalendar || culture.Calendar is PersianCalendar)
1414
{
1515
return culture.DateTimeFormat;
1616
}
Lines changed: 50 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
using System;
2-
using System.Globalization;
2+
using System.Linq;
33
using System.Windows;
44
using System.Windows.Controls;
5+
using Calendar = System.Windows.Controls.Calendar;
56

67
namespace MaterialDesignThemes.Wpf
7-
{
8+
{
89
public class MaterialDateDisplay : Control
910
{
1011
static MaterialDateDisplay()
@@ -14,11 +15,11 @@ static MaterialDateDisplay()
1415

1516
public MaterialDateDisplay()
1617
{
17-
SetCurrentValue(DisplayDateProperty, DateTime.Now.Date);
18+
SetCurrentValue(DisplayDateProperty, DateTime.Today);
1819
}
1920

2021
public static readonly DependencyProperty DisplayDateProperty = DependencyProperty.Register(
21-
nameof(DisplayDate), typeof (DateTime), typeof (MaterialDateDisplay), new PropertyMetadata(default(DateTime), DisplayDatePropertyChangedCallback));
22+
nameof(DisplayDate), typeof(DateTime), typeof(MaterialDateDisplay), new PropertyMetadata(default(DateTime), DisplayDatePropertyChangedCallback));
2223

2324
private static void DisplayDatePropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
2425
{
@@ -27,127 +28,102 @@ private static void DisplayDatePropertyChangedCallback(DependencyObject dependen
2728

2829
public DateTime DisplayDate
2930
{
30-
get { return (DateTime) GetValue(DisplayDateProperty); }
31+
get { return (DateTime)GetValue(DisplayDateProperty); }
3132
set { SetValue(DisplayDateProperty, value); }
3233
}
3334

3435
private static readonly DependencyPropertyKey ComponentOneContentPropertyKey =
3536
DependencyProperty.RegisterReadOnly(
36-
"ComponentOneContent", typeof (string), typeof (MaterialDateDisplay),
37+
nameof(ComponentOneContent), typeof(string), typeof(MaterialDateDisplay),
3738
new PropertyMetadata(default(string)));
3839

3940
public static readonly DependencyProperty ComponentOneContentProperty =
4041
ComponentOneContentPropertyKey.DependencyProperty;
4142

4243
public string ComponentOneContent
4344
{
44-
get { return (string) GetValue(ComponentOneContentProperty); }
45+
get { return (string)GetValue(ComponentOneContentProperty); }
4546
private set { SetValue(ComponentOneContentPropertyKey, value); }
4647
}
4748

4849
private static readonly DependencyPropertyKey ComponentTwoContentPropertyKey =
4950
DependencyProperty.RegisterReadOnly(
50-
"ComponentTwoContent", typeof (string), typeof (MaterialDateDisplay),
51+
nameof(ComponentTwoContent), typeof(string), typeof(MaterialDateDisplay),
5152
new PropertyMetadata(default(string)));
5253

5354
public static readonly DependencyProperty ComponentTwoContentProperty =
5455
ComponentTwoContentPropertyKey.DependencyProperty;
5556

5657
public string ComponentTwoContent
5758
{
58-
get { return (string) GetValue(ComponentTwoContentProperty); }
59+
get { return (string)GetValue(ComponentTwoContentProperty); }
5960
private set { SetValue(ComponentTwoContentPropertyKey, value); }
6061
}
6162

6263
private static readonly DependencyPropertyKey ComponentThreeContentPropertyKey =
6364
DependencyProperty.RegisterReadOnly(
64-
"ComponentThreeContent", typeof (string), typeof (MaterialDateDisplay),
65+
nameof(ComponentThreeContent), typeof(string), typeof(MaterialDateDisplay),
6566
new PropertyMetadata(default(string)));
6667

6768
public static readonly DependencyProperty ComponentThreeContentProperty =
6869
ComponentThreeContentPropertyKey.DependencyProperty;
6970

7071
public string ComponentThreeContent
7172
{
72-
get { return (string) GetValue(ComponentThreeContentProperty); }
73+
get { return (string)GetValue(ComponentThreeContentProperty); }
7374
private set { SetValue(ComponentThreeContentPropertyKey, value); }
7475
}
7576

76-
private static readonly DependencyPropertyKey IsDayInFirstComponentPropertyKey =
77-
DependencyProperty.RegisterReadOnly(
78-
"IsDayInFirstComponent", typeof (bool), typeof (MaterialDateDisplay),
79-
new PropertyMetadata(default(bool)));
77+
private static readonly DependencyPropertyKey IsDayInFirstComponentPropertyKey =
78+
DependencyProperty.RegisterReadOnly(
79+
nameof(IsDayInFirstComponent), typeof(bool), typeof(MaterialDateDisplay),
80+
new PropertyMetadata(default(bool)));
8081

81-
public static readonly DependencyProperty IsDayInFirstComponentProperty =
82-
IsDayInFirstComponentPropertyKey.DependencyProperty;
82+
public static readonly DependencyProperty IsDayInFirstComponentProperty =
83+
IsDayInFirstComponentPropertyKey.DependencyProperty;
8384

84-
public bool IsDayInFirstComponent
85-
{
86-
get { return (bool) GetValue(IsDayInFirstComponentProperty); }
87-
private set { SetValue(IsDayInFirstComponentPropertyKey, value); }
88-
}
85+
public bool IsDayInFirstComponent
86+
{
87+
get { return (bool)GetValue(IsDayInFirstComponentProperty); }
88+
private set { SetValue(IsDayInFirstComponentPropertyKey, value); }
89+
}
8990

90-
//FrameworkElement.LanguageProperty.OverrideMetadata(typeof (Calendar), (PropertyMetadata) new FrameworkPropertyMetadata(new PropertyChangedCallback(Calendar.OnLanguageChanged)));
9191
private void UpdateComponents()
9292
{
9393
var culture = Language.GetSpecificCulture();
9494
var dateTimeFormatInfo = culture.GetDateFormat();
95+
var minDateTime = dateTimeFormatInfo.Calendar.MinSupportedDateTime;
96+
var maxDateTime = dateTimeFormatInfo.Calendar.MaxSupportedDateTime;
9597

96-
ComponentOneContent = DisplayDate.ToString(dateTimeFormatInfo.MonthDayPattern.Replace("MMMM", "MMM"), culture).ToTitleCase(culture); //Day Month folowing culture order. We don't want the month to take too much space
97-
ComponentTwoContent = DisplayDate.ToString("ddd,", culture).ToTitleCase(culture); // Day of week first
98-
ComponentThreeContent = DisplayDate.ToString("yyyy", culture).ToTitleCase(culture); // Year always top
99-
}
100-
101-
/// <summary>
102-
/// Ripped straight from .Net FX.
103-
/// </summary>
104-
/// <param name="culture"></param>
105-
/// <returns></returns>
106-
internal static DateTimeFormatInfo GetDateFormat(CultureInfo culture)
107-
{
108-
if (culture.Calendar is GregorianCalendar)
98+
if (DisplayDate < minDateTime)
10999
{
110-
return culture.DateTimeFormat;
100+
SetDisplayDateOfCalendar(minDateTime);
101+
102+
// return to avoid second formatting of the same value
103+
return;
111104
}
112-
else
105+
106+
if (DisplayDate > maxDateTime)
113107
{
114-
GregorianCalendar foundCal = null;
115-
DateTimeFormatInfo dtfi = null;
116-
117-
foreach (System.Globalization.Calendar cal in culture.OptionalCalendars)
118-
{
119-
if (cal is GregorianCalendar)
120-
{
121-
// Return the first Gregorian calendar with CalendarType == Localized
122-
// Otherwise return the first Gregorian calendar
123-
if (foundCal == null)
124-
{
125-
foundCal = cal as GregorianCalendar;
126-
}
127-
128-
if (((GregorianCalendar)cal).CalendarType == GregorianCalendarTypes.Localized)
129-
{
130-
foundCal = cal as GregorianCalendar;
131-
break;
132-
}
133-
}
134-
}
135-
136-
if (foundCal == null)
137-
{
138-
// if there are no GregorianCalendars in the OptionalCalendars list, use the invariant dtfi
139-
dtfi = ((CultureInfo)CultureInfo.InvariantCulture.Clone()).DateTimeFormat;
140-
dtfi.Calendar = new GregorianCalendar();
141-
}
142-
else
143-
{
144-
dtfi = ((CultureInfo)culture.Clone()).DateTimeFormat;
145-
dtfi.Calendar = foundCal;
146-
}
147-
148-
return dtfi;
108+
SetDisplayDateOfCalendar(maxDateTime);
109+
110+
// return to avoid second formatting of the same value
111+
return;
149112
}
150-
}
151113

114+
ComponentOneContent = DisplayDate.ToString(dateTimeFormatInfo.MonthDayPattern.Replace("MMMM", "MMM"), culture).ToTitleCase(culture); //Day Month following culture order. We don't want the month to take too much space
115+
ComponentTwoContent = DisplayDate.ToString("ddd,", culture).ToTitleCase(culture); // Day of week first
116+
ComponentThreeContent = DisplayDate.ToString("yyyy", culture).ToTitleCase(culture); // Year always top
117+
}
118+
119+
private void SetDisplayDateOfCalendar(DateTime displayDate)
120+
{
121+
Calendar calendarControl = this.GetVisualAncestry().OfType<Calendar>().FirstOrDefault();
122+
123+
if (calendarControl != null)
124+
{
125+
calendarControl.DisplayDate = displayDate;
126+
}
127+
}
152128
}
153129
}

0 commit comments

Comments
 (0)