DatePicker控件只显示年月
1、我们在C#编程的时候,往往会用到时间控件,当然我这边用的比较多的控件是DatePicker,这个控件很好用,但是一般它会精确到年月日,具体的代码如下所示:
<telerik:RadCalendar x:Name="radCalender" Grid.Row="2" Grid.Column="1" SelectionChanged="radCalender_SelectionChanged">
当然我这个控件是基于WPF开发的。

2、从上面的实例中我们可以看出来这个时间控件是精确到年月日,但在开发过程中,我们要计算某一个月的数据,某一年的数据,那么问题来了,我们没有必要去选择具体的日期了,那么具体的怎么实现呢?

3、从上图中的代码可以看出,我这里是建立一个类DatePickerCalendar,然后从这个类里面去实现选择月,和年的方法,然后前台去调用这个获取月和年的参数,来显示要选择年还是月

4、这里直接上代码了:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Controls.Primitives;
using System.Windows.Threading;
namespace Listen.Main.Common
{
public class DatePickerCalendar
{
public static bool GetIsYear(DependencyObject obj)
{
return (bool)obj.GetValue(IsYearProperty);
}
public static void SetIsYear(DependencyObject obj, bool value)
{
obj.SetValue(IsYearProperty, value);
}
// Using a DependencyProperty as the backing store for IsYear. This enables animation, styling, binding, etc...
public static readonly DependencyProperty IsYearProperty =
DependencyProperty.RegisterAttached("IsYear", typeof(bool), typeof(DatePickerCalendar), new PropertyMetadata(false, new PropertyChangedCallback(OnIsMonthYearChanged)));
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);
if (GetIsYear(sender as DatePicker))
{
calendar.DisplayMode = CalendarMode.Decade;
}
else
{
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;
var datePicker = GetCalendarsDatePicker(calendar);
bool mode = (GetIsYear(datePicker) && calendar.DisplayMode != CalendarMode.Year) || (GetIsMonthYear(datePicker) && calendar.DisplayMode != CalendarMode.Month);
if (mode)
return;
calendar.SelectedDate = GetSelectedCalendarDate(calendar.DisplayDate);
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);
}
}
}

5、然后前台去调用,这里选择的是DatePickerCalendar.IsMonthYear="True",然后 这边就选择的是年和月,那么具体的日期就去掉了,所以我们显示出来的就是具体的年和月

6、还有如果DatePickerCalendar.IsYear="True" ,这里面我们选择的是具体的年份,那么图形直接显示的是具体的年份,这样我们去计算年数据的时候,就可以选择年份了
