I have experienced an error in RadCalendar where the years displayed are wrong, after navigating outwards from the current month to the current year and then again to the current decade and out to the current century and moving back and forth. The Text property is not dislaying the CalendarButtonContent Date. Why this happens is not something I am sure, but I set the Culture of the calendar to Norwegian bokmål (nb-no). Let me show you how at least I managed to get the RadCalendar working again.
First off in your resource file, define a style for the RadCalendar:
<Style TargetType="{x:Type telerikInput:RadCalendar}"><Setter Property="FontFamily" Value="Segoe UI" /><Setter Property="FontSize" Value="9" /> <EventSetter Event="Loaded" Handler="RadCalendar_Loaded" /></Style>
The style got no key, so it will be the implicit style of any RadCalendar control/instance in your app. Ok, so now let's look at the EventSetter.
public void RadCalendar_Loaded(object sender, EventArgs e)
{
try {
var radCalendar = sender as RadCalendar;
if (radCalendar != null)
{
radCalendar.Culture = new CultureInfo("nb-NO");
radCalendar.DisplayModeChanged += radCalendar_DisplayModeChanged;
radCalendar.DisplayDateChanged += radCalendar_DisplayDateChanged;
}
}
catch (Exception) { }
}
void radCalendar_DisplayDateChanged(object sender, Telerik.Windows.Controls.Calendar.CalendarDateChangedEventArgs e)
{
AdjustRadCalendarDisplayYearsFix(sender);
}
void radCalendar_DisplayModeChanged(object sender, Telerik.Windows.Controls.Calendar.CalendarModeChangedEventArgs e)
{
AdjustRadCalendarDisplayYearsFix(sender);
}
private static void AdjustRadCalendarDisplayYearsFix(object sender)
{
//TA 11.11.2015: Resolution of the calendar bug observed when navigating years and decades in the calendar var calendar = sender as RadCalendar;
if (calendar == null)
return;
DispatcherUtil.DelayedInvokeAction(() =>
{
var calendarButtons = calendar.ChildrenOfType<CalendarButton>().ToList();
if (calendarButtons.Any())
{
foreach (var c in calendarButtons.Where(cb => cb.ButtonType == CalendarButtonType.Year || cb.ButtonType == CalendarButtonType.Decade))
{
try {
if (c.DataContext is CalendarButtonContent)
{
var cbc = c.DataContext as CalendarButtonContent;
var tb = c.FindChildByType<TextBlock>();
if (tb != null)
tb.Text = cbc.ButtonType == CalendarButtonType.Year ? cbc.Date.ToString("yyyy") :
cbc.Date.ToString("yyyy") + "-" + cbc.Date.AddYears(10).ToString("yy");
}
}
catch (Exception err)
{
Debug.WriteLine(err.Message);
}
}
}
}, 500);
}
Ok, so we also use something called DelayedInvokeAction here:
/// <summary> /// Executes an action passed into this method by a timeout measured in milliseconds /// </summary> /// <param name="executeAction">Action to execute</param> /// <param name="timeOut">The timeout to wait before executing (in milliseconds)</param> /// <param name="priority"></param> /// /// <param name="keyToken">A key token to identity the switch (basic grouing). Will be used as a tag on the DispatcherTimer</param> public static bool DelayedInvokeAction(Action executeAction, int timeOut, DispatcherPriority priority = DispatcherPriority.Background, Guid? keyToken = null)
{
var delayedAction = new DelayedAction(executeAction, timeOut, keyToken);
ActionsRegistered.Add(delayedAction);
DispatcherTimer dtimer = new DispatcherTimer(priority);
dtimer.Interval += new TimeSpan(0, 0, 0, 0, timeOut);
dtimer.Tag = delayedAction.ExecuteGuid;
dtimer.Tick += DelayedInvokeTimerTick;
dtimer.IsEnabled = true;
dtimer.Start();
return true;
}
public class DelayedAction {
private readonly Action actionToExecute;
private readonly int timeOut;
private readonly Guid executeGuid;
public Action ActionToExecute
{
get { return actionToExecute; }
}
public int TimeOut
{
get { return timeOut; }
}
public Guid ExecuteGuid
{
get { return executeGuid; }
}
public DelayedAction(Action actionToExecute, int timeOut, Guid? keytoken)
{
this.actionToExecute = actionToExecute;
this.timeOut = timeOut;
this.executeGuid = keytoken ?? Guid.NewGuid();
}
}
Hope this helps!