ContextMenuStrip 中的 DateTimePicker 控件

时间:2021-02-13 03:04:11

标签: c# winforms contextmenu datetimepicker toolstripcontrolhost

我使用 ToolStripControlHost 在 ContextMenuStrip 中添加了一个 DateTimePicker。我正在使用以下代码。

 DateTimePicker startDate = new DateTimePicker();
 (cms.Items["mnuStartDate"] as ToolStripMenuItem).DropDownItems.Add(new ToolStripControlHost(startDate));

选择日期有效,但是当我单击箭头转到上个月或下个月时,或者如果我单击月份,则 ToolStrip 正在关闭。这里有什么解决方法吗?谢谢。

注意:我在控件上单击鼠标右键时显示​​ cms(ContextMenuStrip)。

2 个答案:

答案 0 :(得分:0)

看起来 ToolStrip 行为在选择项目时关闭。所以我突出使用 CalendarMonth Control 作为替代。链接here

答案 1 :(得分:0)

似乎与Application.EnableVisualStyles();有关,未启用时,菜单不会意外关闭。

启用后,为防止关闭,请检测 CalendarMonth 菜单当前是否可见,以及是否点击了鼠标。

public class DatePicker : DateTimePicker {

    private const int DtmFirst = 0x1000;
    private const int DtmGetmonthcal = (DtmFirst + 8);
    private bool isDroppedDown = false;
    private IntPtr hwndCalendarWindow = IntPtr.Zero;

    protected override void OnDropDown(EventArgs e) {
        isDroppedDown = true;
        hwndCalendarWindow = SendMessage(Handle, DtmGetmonthcal, 0, 0);
        base.OnDropDown(e);
    }

    protected override void OnCloseUp(EventArgs eventargs) {
        isDroppedDown = false;
        base.OnCloseUp(eventargs);
    }

    public bool CalendarMonthClicked(Point pt) {
        if (!isDroppedDown)
            return false;

        RECT r = new RECT();
        GetWindowRect(hwndCalendarWindow, out r);
        return pt.X >= r.Left && pt.X <= r.Right && pt.Y >= r.Top && pt.Y <= r.Bottom;
    }

    [DllImport("user32.dll")]
    private static extern bool GetWindowRect(IntPtr hWnd, out RECT lpRect);

    [DllImport("User32.dll")]
    private static extern IntPtr SendMessage(IntPtr h, int msg, int param, int data);

    [StructLayout(LayoutKind.Sequential)]
    private struct RECT {
        public int Left, Top, Right, Bottom;
    }
}

static class Program {

    //[DllImport("uxtheme.dll", ExactSpelling = true, CharSet = CharSet.Unicode)]
    //public extern static Int32 SetWindowTheme(IntPtr hWnd, String textSubAppName, String textSubIdList);

    [STAThread]
    static void Main() {
        Application.EnableVisualStyles(); // if you disable visual styles then the menu won't close
        DatePicker dpStart = new DatePicker();
        dpStart.MinimumSize = new Size(100, 50);

        Form ff = new Form();
        ContextMenuStrip cms = new ContextMenuStrip();
        ToolStripMenuItem menu = new ToolStripMenuItem("Menu");
        menu.DropDown.Closing += (o, e) => {
            e.Cancel = (e.CloseReason == ToolStripDropDownCloseReason.AppClicked && dpStart.CalendarMonthClicked(Cursor.Position));
        };

        // sub-menu doesn't close properly, probably related to the ToolStripControlHost
        cms.Opening += delegate {
            menu.DropDown.Close(ToolStripDropDownCloseReason.CloseCalled);
        };

        cms.Closed += delegate {
            menu.DropDown.Close(ToolStripDropDownCloseReason.CloseCalled);
        };

        ff.ContextMenuStrip = cms;
        cms.Items.Add(menu);
        ToolStripControlHost item = new ToolStripControlHost(dpStart) { AutoSize = true };
        menu.DropDownItems.Add(item);
        Application.Run(ff);
    }
}
相关问题