WPF 用TextBox和Calendar自定义可以选择年月的日期选择控件

背景

在做WPF项目时,需要一个只可以选择年月的日期控件,但是工具箱里自带的DatePicker好像无法设置只选择年月,找了一些资料,但是都太老了,就不在贴出来了,下面是我用TextBox结合Calendar做的一个日期选择功能,没加什么样式,但是也基本满足我的需要了。
截图
WPF 用TextBox和Calendar自定义可以选择年月的日期选择控件_第1张图片

代码

先说说思路,这里一共用到了三个控件分别是TextBox,ImageCalendar,还有一个弹窗PopupCalendar放在Popup里,点击Image显示调出弹窗,选择月份之后,在隐藏Popup,同时给TextBox赋值即可。

CalendarDisplayMode属性可以控制日历一直显示月份。

//显示月份
calendar.DisplayMode = CalendarMode.Year;

MainWindow.xaml

<Window x:Class="自定义年月日期选择.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:自定义年月日期选择"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="500">
    <Grid>
        <StackPanel Orientation="Horizontal" VerticalAlignment="Top" Margin="0,25,0,0">
            <TextBox Name="tb_calendar" Width="120" Height="20" Margin="108,0,0,0"/>
            <Image Name="tb_calendar_img" Grid.Column="1" Width="18" Height="18" Margin="-25,0,0,0" Source="/自定义年月日期选择;component/Images/calender.png" MouseLeftButtonUp="tb_calendar_img_MouseLeftButtonUp"/>
        StackPanel>
        <Popup x:Name="Pop" PopupAnimation="None"  Width="200" Height="210" PlacementTarget="{Binding ElementName=tb_calendar}" Placement="Bottom"  AllowsTransparency="True" StaysOpen="False" VerticalAlignment="Top" Margin="-200,0,0,0">
            <Calendar Name="calendar" HorizontalAlignment="Left" Margin="0,44,0,0" VerticalAlignment="Top" DisplayMode="Year" DisplayModeChanged="calendar_DisplayModeChanged" DisplayDateChanged="calendar_DisplayDateChanged" />
        Popup>
    Grid>
Window>

MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace 自定义年月日期选择
{
    /// 
    /// Interaction logic for MainWindow.xaml
    /// 
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        /// 
        /// 监听日历模式切换
        /// 
        /// 
        /// 
        private void calendar_DisplayModeChanged(object sender, CalendarModeChangedEventArgs e)
        {
            if (calendar.DisplayMode==CalendarMode.Month || calendar.DisplayMode==CalendarMode.Decade)
            {
                calendar.DisplayMode = CalendarMode.Year;
            }
        }
        /// 
        /// 点击日历图标显示Calendar控件
        /// 
        /// 
        /// 
        private void tb_calendar_img_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
        {
            if (Pop.IsOpen)
            {
                Pop.IsOpen = false;
            }
            else
            {
                Pop.IsOpen = true;
            }
        }
        /// 
        /// 监听日期变化,隐藏Calendar控件
        /// 
        /// 
        /// 
        private void calendar_DisplayDateChanged(object sender, CalendarDateChangedEventArgs e)
        {
            var year = calendar.DisplayDate.Date.Year;
            var month = calendar.DisplayDate.Date.Month;
            tb_calendar.Text = year + "年" + month+"月";
            Pop.IsOpen = false;
        }
    }
}


里面还有一些不足之处,比如,选择同一个月份,日历不会主动消失,不过可以通过切换日期的方式,或者点击页面空白处也可以取消,所以问题不大。

开源地址

之后代码若有修改不在更新博文了,gitee里的代码是最新的。

https://gitee.com/limeng66/wpf

你可能感兴趣的:(WPF,WPF,C#,窗体,DatePicker,日期年月选择)