.NET中的MonthCalendar-扩展一个月 [英] MonthCalendar in .NET - expanding a month

查看:152
本文介绍了.NET中的MonthCalendar-扩展一个月的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个带有MonthCalendar控件的WinForm应用程序. MaxSelectionCount属性设置为1天.

I have a WinForm app with a MonthCalendar control on it. The MaxSelectionCount property is set to 1 day.

我想更改某些行为.如果视图使控件显示12个月并且用户单击一个月,它将展开该月,并且所选日期将成为该月的最后天.我想将其更改为该月的第一天.我该怎么办?

There is a certain behavior that I would like to change. If the view is such that the control displays 12 months and the user clicks on a month, it will expand that month and the selected date becomes the last day of that month. I would like to change that to the first day of that month. How can I do this?

此外,当我以这种方式扩展一个月时,会引发什么 event ?它有特定事件吗?

Also, what event is raised when I expand a month in this manner? Does it have a specific event?

谢谢.

推荐答案

从技术上讲,这是可能的,因为Vista原生控件在视图更改时会发送通知(MCM_VIEWCHANGE).您可以捕获此通知并将其转变为事件.在您的项目中添加一个新类,并粘贴以下代码.我预煮了选择第一天的代码.编译.将新控件从工具箱的顶部拖放到您的窗体上.在Windows 8上进行了测试,您需要检查它在Vista和Win7上是否可以正常工作.

This is technically possible, since Vista the native control sends a notification (MCM_VIEWCHANGE) when the view changes. You can capture this notification and turn it into an event. Add a new class to your project and paste the code shown below. I pre-cooked the code that selects the first day. Compile. Drop the new control from the top of the toolbox onto your form. Tested on Windows 8, you'll need to check if it works okay on Vista and 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;
    } 
}

这篇关于.NET中的MonthCalendar-扩展一个月的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆