问题
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