标签:
最近的项目,查询时只需要年和月,不需要日,因此需要对原有的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); } }
调用方式
<DatePicker Width="200" Height="30" local:DatePickerCalendar.IsMonthYear="True"/>
展示效果
从图上就能看到左右不一样,左侧的是添加附加属性的,点击以后直接显示月,后侧没用的则显示到日,虽然都格式化为了yyyy-MM,但是Calendar如果显示到日的话,用户体验不好。
标签:
原文地址:http://www.cnblogs.com/ZXdeveloper/p/4665772.html