MonthCalendar in .NET - expanding a month

和自甴很熟 提交于 2019-12-25 00:21:59

问题


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

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?

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

Thanks.


回答1:


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;
    } 
}


来源:https://stackoverflow.com/questions/17137074/monthcalendar-in-net-expanding-a-month

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!