最近的项目,查询时只需要年和月,不需要日,因此需要对原有的DatePicker进行修改,查询了网上的内容,最终从一篇帖子里看到了添加附加属性的方法,地址是http://stackoverflow.com/questions/1798513/wpf-toolkit-datepicker-month-year-only
原文是用了两个类,其中一个是为了让DatePicker下的Calendar只显示年月,不显示日,另一个类是为了让DatePicker格式化为yyyy-MM格式,但是从文章中可以看出,有人提出了,用格式化类进行格式化时,DatePicker控件会闪动一下,当然不影响使用。如果不想使用文章中提到的类进行格式化,也可以用我上一篇文章中的方法进行格式化,不会出现闪动的情况。
只显示年月的类
public class DatePickerCalendar
{
public static readonly DependencyProperty IsMonthYearProperty =
DependencyProperty.RegisterAttached("IsMonthYear", typeof(bool), typeof(DatePickerCalendar),
new PropertyMetadata(OnIsMonthYearChanged));
public static bool GetIsMonthYear(DependencyObject dobj)
{
return (bool)dobj.GetValue(IsMonthYearProperty);
}
public static void SetIsMonthYear(DependencyObject dobj, bool value)
{
dobj.SetValue(IsMonthYearProperty, value);
}
private static void OnIsMonthYearChanged(DependencyObject dobj, DependencyPropertyChangedEventArgs e)
{
var datePicker = (DatePicker)dobj;
Application.Current.Dispatcher
.BeginInvoke(DispatcherPriority.Loaded,
new Action<DatePicker, DependencyPropertyChangedEventArgs>(SetCalendarEventHandlers),
datePicker, e);
}
private static void SetCalendarEventHandlers(DatePicker datePicker, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue == e.OldValue)
return;
if ((bool)e.NewValue)
{
datePicker.CalendarOpened += DatePickerOnCalendarOpened;
datePicker.CalendarClosed += DatePickerOnCalendarClosed;
}
else
{
datePicker.CalendarOpened -= DatePickerOnCalendarOpened;
datePicker.CalendarClosed -= DatePickerOnCalendarClosed;
}
}
private static void DatePickerOnCalendarOpened(object sender, RoutedEventArgs routedEventArgs)
{
var calendar = GetDatePickerCalendar(sender);
calendar.DisplayMode = CalendarMode.Year;
calendar.DisplayModeChanged += CalendarOnDisplayModeChanged;
}
private static void DatePickerOnCalendarClosed(object sender, RoutedEventArgs routedEventArgs)
{
var datePicker = (DatePicker)sender;
var calendar = GetDatePickerCalendar(sender);
datePicker.SelectedDate = calendar.SelectedDate;
calendar.DisplayModeChanged -= CalendarOnDisplayModeChanged;
}
private static void CalendarOnDisplayModeChanged(object sender, CalendarModeChangedEventArgs e)
{
var calendar = (Calendar)sender;
if (calendar.DisplayMode != CalendarMode.Month)
return;
calendar.SelectedDate = GetSelectedCalendarDate(calendar.DisplayDate);
var datePicker = GetCalendarsDatePicker(calendar);
datePicker.IsDropDownOpen = false;
}
private static Calendar GetDatePickerCalendar(object sender)
{
var datePicker = (DatePicker)sender;
var popup = (Popup)datePicker.Template.FindName("PART_Popup", datePicker);
return ((Calendar)popup.Child);
}
private static DatePicker GetCalendarsDatePicker(FrameworkElement child)
{
var parent = (FrameworkElement)child.Parent;
if (parent.Name == "PART_Root")
return (DatePicker)parent.TemplatedParent;
return GetCalendarsDatePicker(parent);
}
private static DateTime? GetSelectedCalendarDate(DateTime? selectedDate)
{
if (!selectedDate.HasValue)
return null;
return new DateTime(selectedDate.Value.Year, selectedDate.Value.Month, 1);
}
}