【问题标题】:C# DateTimePicker change MonthCalendarC# DateTimePicker 更改 MonthCalendar
【发布时间】:2011-10-28 18:04:36
【问题描述】:

我创建了自己的 MonthCalendar(选择多项内容和更多更改),我想将它与 DateTimePicker 一起使用。以 DateTimePicker 为例,当单击右键时,它会显示我的自定义日历。有简单的方法吗?或者我应该像本教程一样自己创建它:http://www.techpowerup.com/forums/showthread.php?t=70925 谢谢

【问题讨论】:

  • 您使用的是什么界面语言? WPF?银光? ASP.NET? ASP.NET MVC? WinForms?
  • 对不起,我忘记添加了。这是Winforms
  • 我猜你会想从头开始使用 Winforms,尽管如果 DateTimePicker 没有密封,你可能会通过使用视觉继承来获得一点领先。

标签: c# winforms components custom-controls datetimepicker


【解决方案1】:

这是一个小技巧,但它应该可以正常工作。

首先我们检查 OnSizeChanged 我们有什么按钮,大的(有图标)或小(没有图标)。如果是大按钮,则按钮有 35 像素,小按钮有 18 像素。

然后我们监听窗口消息。如果 mousedown 发生,我们检查用户点击的位置。因此,我们将 lParam 转换为 X/Y 位置。如果 X 位置在按钮区域,我们将转到自定义方法并显示我们的日历。在我们从方法返回的方法之后,或者 DateTimePicker 也会显示自己的日历。

此外,我们覆盖 ShowUpDown 属性并将其设置为 Browseable(false)。但我们也可以检查 ShowUpDown 是否为真,并让 DateTimePcker 在这种情况下处理点击。

代码如下:

class DateTimePickerEX : DateTimePicker {

    const int WM_MOUSEDOWN = 0x201;

    int paddingright = 0;

    protected override void OnSizeChanged(EventArgs e) {
        base.OnSizeChanged(e);

        int textwidth = 0;

        using (Graphics g = this.CreateGraphics()) {
            textwidth = (int)g.MeasureString(this.Text, this.Font).Width;
        }

        if (textwidth > this.Width - 35 - 22) {
            paddingright = 18;
        } else {
            paddingright = 35;
        }

    }

    protected override void WndProc(ref Message m) {
        if (m.Msg == WM_MOUSEDOWN) {
            DWORD dw = new DWORD(m.LParam);
            int x = dw.HI;
            int y = dw.LO;

            if (x > this.Width - paddingright) {
                OnButtonClick();
                return;
            }
        }

        base.WndProc(ref m);
    }

    [EditorBrowsable( EditorBrowsableState.Never ), Browsable(false)]
    public new bool ShowUpDown {
        get;
        set;
    }

    private void OnButtonClick() {
        //-----------------------------------
        //####  Show your MonthCalendar  ####
        //-----------------------------------
    }

    [StructLayout(LayoutKind.Explicit)]
    struct DWORD {
        [FieldOffset(0)]
        public int Word;
        [FieldOffset(0)]
        public short HI;
        [FieldOffset(2)]
        public short LO;

        public DWORD(IntPtr word) {
            this.HI = 0;
            this.LO = 0;
            this.Word = (int)word;
        }

        public static DWORD Empty {
            get {
                return new DWORD() {
                    Word = 0
                };
            }
        }
    }
}

【讨论】:

  • 这是我想要的,你能帮我显示月历吗?我是通过 this.Controls.Add(calendar);但它是 datepicker 中的那个小文本框。我知道这是因为它不是表单,但我确实为那个小窗口添加了控制,但是我怎样才能正确显示它,谢谢
  • 如果您想要与原始月历相同的行为,则不应将其添加到控件中(如果需要/需要,甚至在表单之外显示月历,如果用户单击其他地方则隐藏)。您可以使用 ToolStripDropDown 并使用 ToolStripControlHost 添加您的 MonthCalendar。另一种方法是使用全局钩子创建自己的表单,并且不会窃取焦点。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-10-29
  • 2016-11-25
  • 1970-01-01
相关资源
最近更新 更多