.net NET中的MonthCalendar-扩展一个月

.net NET中的MonthCalendar-扩展一个月,.net,events,date,datepicker,monthcalendar,.net,Events,Date,Datepicker,Monthcalendar,我有一个WinForm应用程序,上面有一个MonthCalendar控件。MaxSelectionCount属性设置为1day 有一种行为我想改变。如果视图中控件显示12个月,用户单击某个月,则该视图将展开该月,所选日期将成为该月的最后一天。我想把它改到那个月的第一天。我该怎么做 另外,当我以这种方式扩展一个月时,会引发什么事件?它有具体的活动吗 谢谢。这在技术上是可能的,因为当视图更改时,本机控件会发送通知(MCM_VIEWCHANGE)。您可以捕获此通知并将其转换为事件。向项目中添加一个新类

我有一个WinForm应用程序,上面有一个
MonthCalendar
控件。
MaxSelectionCount
属性设置为
1
day

有一种行为我想改变。如果视图中控件显示12个月,用户单击某个月,则该视图将展开该月,所选日期将成为该月的最后一天。我想把它改到那个月的第一天。我该怎么做

另外,当我以这种方式扩展一个月时,会引发什么事件?它有具体的活动吗


谢谢。

这在技术上是可能的,因为当视图更改时,本机控件会发送通知(MCM_VIEWCHANGE)。您可以捕获此通知并将其转换为事件。向项目中添加一个新类并粘贴如下所示的代码。我预先编写了选择第一天的代码。编译。将新控件从工具箱顶部拖到窗体上。在Windows8上测试,您需要检查它在Vista和Win7上是否正常工作

using System;
using System.Windows.Forms;
using System.Runtime.InteropServices;

class MonthCalendarEx : MonthCalendar {
    public enum View { Month, Year, Decade, Century };
    public class ViewEventArgs : EventArgs {
        public ViewEventArgs(View newv, View oldv) { NewView = newv; OldView = oldv; }
        public View NewView { get; private set; }
        public View OldView { get; private set; }
    }
    public event EventHandler<ViewEventArgs> ViewChange;

    protected virtual void OnViewChange(ViewEventArgs e) {
        if (ViewChange == null) return;
        // NOTE: I saw painting problems if this is done when MCM_VIEWCHANGE fires, delay it
        this.BeginInvoke(new Action(() => {
            // Select first day when switching to Month view:
            if (e.NewView == View.Month) {
                this.SetDate(this.GetDisplayRange(true).Start);
            } 
            ViewChange(this, e);
        }));
    }

    protected override void WndProc(ref Message m) {
        if (m.Msg == 0x204e) {         // Trap WMREFLECT + WM_NOTIFY
            var hdr = (NMHDR)Marshal.PtrToStructure(m.LParam, typeof(NMHDR));
            if (hdr.code == -750) {    // Trap MCM_VIEWCHANGE
                var vc = (NMVIEWCHANGE)Marshal.PtrToStructure(m.LParam, typeof(NMVIEWCHANGE));
                OnViewChange(new ViewEventArgs(vc.dwNewView, vc.dwOldView));
            }
        }
        base.WndProc(ref m);
    }
    private struct NMHDR {
        public IntPtr hwndFrom;
        public IntPtr idFrom;
        public int code;
    }
    private struct NMVIEWCHANGE {
        public NMHDR hdr;
        public View dwOldView;
        public View dwNewView;
    } 
}
使用系统;
使用System.Windows.Forms;
使用System.Runtime.InteropServices;
MonthCalendarEx类:MonthCalendar{
公共枚举视图{月、年、十年、世纪};
公共类ViewEventArgs:EventArgs{
public ViewEventArgs(View newv,View oldv){NewView=newv;OldView=oldv;}
公共视图NewView{get;private set;}
公共视图OldView{get;private set;}
}
公共事件处理程序视图更改;
受保护的虚拟void OnViewChange(ViewEventArgs e){
if(ViewChange==null)返回;
//注意:我看到了绘画问题,如果在MCM_VIEWCHANGE开火时这样做,请延迟
此.BeginInvoke(新操作(()=>{
//切换到月视图时选择第一天:
如果(e.NewView==View.Month){
this.SetDate(this.GetDisplayRange(true.Start));
} 
视图更改(本,e);
}));
}
受保护的覆盖无效WndProc(参考消息m){
如果(m.Msg==0x204e){//Trap WMREFLECT+WM_NOTIFY
var hdr=(NMHDR)Marshal.PtrToStructure(m.LParam,typeof(NMHDR));
如果(hdr.code==-750){//Trap MCM_VIEWCHANGE
var vc=(NMVIEWCHANGE)Marshal.PtrToStructure(m.LParam,typeof(NMVIEWCHANGE));
OnViewChange(新的ViewEventArgs(vc.dwNewView,vc.dwOldView));
}
}
基准WndProc(参考m);
}
私有结构NMHDR{
公共IntPtr hwndFrom;
公共IntPtr idFrom;
公共整数码;
}
私有结构NMVIEWCHANGE{
公共NMHDR hdr;
公众视野;
公众视野;
} 
}

在Win7中运行良好。谢谢