private static void OnIsDropDownOpenChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var datepicker = (FXDatePicker)d;
if(datepicker.MonthView != null)
{
datepicker.MonthView.ShowTodayButton = datepicker.ShowTodayButton;
datepicker.MonthView.ShowEmptyButton = datepicker.ShowEmptyButton;
datepicker.MonthView.ShowWeekDayNames = datepicker.ShowWeekDayNames;
}
if ((bool)e.NewValue)
{
//Remember the previous SelectedDateTime for cancel action (Key.Escape)
datepicker.prevValue = datepicker.SelectedDateTime;
if (datepicker.MonthView != null && datepicker.SelectedDateTime != datepicker.MonthView.SelectedDateTime)
{
datepicker.MonthView.SelectedDateTime = datepicker.SelectedDateTime;
}
// When the drop down opens, take capture
Mouse.Capture(datepicker, CaptureMode.SubTree);
// Popup.IsOpen is databound to IsDropDownOpen. We don't know
// if IsDropDownOpen will be invalidated before Popup.IsOpen.
// If we are invalidated first and we try to focus the item, we
// might succeed. When the popup finally opens, Focus
// will be sent to null because Core doesn't know what else to do.
// So, we must focus the element only after we are sure the popup
// has opened. We will queue an operation (at Send priority) to
// do this work -- this is the soonest we can make this happen.
if (datepicker.MonthView != null && datepicker.SelectedDateTime.HasValue)
{
datepicker.Dispatcher.BeginInvoke(DispatcherPriority.Send, (DispatcherOperationCallback)delegate(object arg)
{
FXDatePicker dp = (FXDatePicker)arg;
if (dp.IsKeyboardFocusWithin)
{
FXMonthViewItem item = dp.MonthView.GetMonthViewItemFromDate(dp.SelectedDateTime.Value);
if (item != null)
{
item.Focus();
}
}
return null;
}, datepicker);
}
datepicker.OnDropDownOpened(new RoutedEventArgs(DropDownOpenedEvent));
}
else
{
// If focus is within the subtree, make sure we have the focus so that focus isn't in the disposed hwnd
if (datepicker.IsKeyboardFocusWithin)
{
// If use Mouse to select a date, DateSelectionChanged is fired in ListBox.MakeSingleSelection
// Then ListBoxItem.Focus() will be called which will grab the focus from FXDatePicker
// So use Dispatcher.BeginInvoke to set Focus to FXDatePicker after ListBoxItem.Focus()
datepicker.Dispatcher.BeginInvoke(DispatcherPriority.Loaded, (DispatcherOperationCallback)delegate(object arg)
{
FXDatePicker dp = (FXDatePicker)arg;
if (dp.IsKeyboardFocusWithin)
{
dp.Focus();
}
return null;
}, datepicker);
if (datepicker.HasCapture)
{
// It's not editable, make sure the datepicker has focus
datepicker.Focus();
}
}
if (datepicker.HasCapture)
{
Mouse.Capture(null);
}
datepicker.OnDropDownClosed(new RoutedEventArgs(DropDownClosedEvent));
}
}