设置日历大小压倒一切的DateTimePicker添加周数时 [英] Setting calendar size when overriding DateTimePicker to add week numbers

查看:1514
本文介绍了设置日历大小压倒一切的DateTimePicker添加周数时的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图创建一个的DateTimePicker 与周数显示的如下所示(代码示例项目)

I'm trying to create a DateTimePicker with week numbers displayed, as shown here (Code project example).

它的工作原理相当不错,除了一个小细节;压延弹出时,试图选择一个日期是不正确的大小。正如你所看到的,日历区域是有点拥挤,特别是沿右侧边缘。

It works fairly well, except for one minor detail; The calender popping up when trying to select a date is not the right size. As you can see, the calendar area is sort of "cramped", especially along the right edge.

我可以在这里点击右下角,将其拖出一个小 - 刚好使它看起来正确,扩展它:

I can click the bottom right corner here, and drag it out a little - just enough to expand it so that it looks right:

我可以'不像是会找到任何办法强迫日历是从一开始就正确/全尺寸,或调整其大小。 。任何想法,将不胜感激。

I can't seem to find any way to force the calendar to be the correct/full size from the beginning, or to resize it. Any ideas would be greatly appreciated.

推荐答案

最后发现,似乎工作的解决方案 - 至少目前是这样。

Finally found a solution that seems to work - at least for now.

似乎有在的的DateTimePicker 日历部件两个窗口。显然我的代码将自动找到用于内酮(或多或少至少?)正确大小,但不是外之一。

It seems there are two windows in the calendar part of the DateTimePicker. Apparently my code would automatically find the correct size for the inner one (more or less at least?), but not the outer one.

研究有点导致下面的代码。下面的链接提供了一些有用的相关信息:

A bit of research has led to the code below. The following links provide some useful and relevant info:

  • GetWindowLong function (Used for getting info about the window to edit)
  • GetParent function (Finding the outer window, so we could apply settings to that too)

诀窍是一点点增加的高度与(内)窗口的宽度,则应用相同的高度和宽度,以外部窗口(我访问用 GetParrent()功能)。我找到了正确的大小通过试验和错误:当大小相匹配,需要什么日历的内容,它不能被调整下去。

The trick was to add a little to the height and width of the (inner) window, then apply the same height and width to the outer window (which I access using the GetParrent() function). I found the "correct" size by trial and error: When the size matched what was needed for the contents of the calendar, it could not be resized any longer.

是的,这种感觉有点像一个黑客,没有,我一直无法验证它完美的作品比我的其他电脑呢。我有点担心不必给出具体的值的高度和宽度,但我希望这不会被屏幕分辨率或其他任何的影响。

Yes, this feels a little like a hack, and no, I haven't been able to verify that it works perfectly on other computers than my own yet. I'm a little worried about having to give specific values for height and width, but I'm hoping this won't be affected by screen resolutions or whatever else.

希望有人在类似情况下别人会发现代码中非常有用。

的可以按照直接替代普通的的DateTimePicker 在日历中显示周数的)

Hope someone else in a similar situation will find the code useful.
(The following can directly replace a regular DateTimePicker to show week numbers in the calendar)

using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Windows.Forms;

public class DatePickerWithWeekNumbers : DateTimePicker
{
    [DllImport("User32.dll")]
    private static extern int GetWindowLong(IntPtr handleToWindow, 
                                            int offsetToValueToGet);

    [DllImport("User32.dll")]
    private static extern int SetWindowLong(IntPtr h, 
                                            int index, 
                                            int value);

    private const int McmFirst = 0x1000;
    private const int McmGetminreqrect = (McmFirst + 9);
    private const int McsWeeknumbers = 0x4;
    private const int DtmFirst = 0x1000;
    private const int DtmGetmonthcal = (DtmFirst + 8);


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

    [DllImport("User32.dll")]
    private static extern IntPtr GetParent(IntPtr h);

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

    [DllImport("User32.dll")]
    private static extern int MoveWindow(IntPtr h, 
                                         int x, 
                                         int y,
                                         int width, 
                                         int height, 
                                         bool repaint);

    [Browsable(true), DesignerSerializationVisibility(
        DesignerSerializationVisibility.Visible)]
    public bool DisplayWeekNumbers { get; set; }

    protected override void OnDropDown(EventArgs e)
    {
        // Hex value to specify that we want the style-attributes
        // for the window:
        const int offsetToGetWindowsStyles = (-16);

        IntPtr pointerToCalenderWindow = SendMessage(Handle, 
                                                     DtmGetmonthcal,  
                                                     0,  
                                                     0);
        int styleForWindow = GetWindowLong(pointerToCalenderWindow, 
                                           offsetToGetWindowsStyles);

        // Check properties for the control - matches available 
        // property in the graphical properties for the DateTimePicker:
        if (DisplayWeekNumbers)
        {
            styleForWindow = styleForWindow | McsWeeknumbers;
        }
        else
        {
            styleForWindow = styleForWindow & ~McsWeeknumbers;
        }

        // Get the size needed to display the calendar (inner window)
        var rect = new Rectangle();
        SendMessage(pointerToCalenderWindow, McmGetminreqrect, 0, ref rect);

        // Add to size as needed (I don't know why 
        // this was not correct initially!)
        rect.Width = rect.Width + 28;
        rect.Height = rect.Height + 6;

        // Set window styles..
        SetWindowLong(pointerToCalenderWindow, 
                      offsetToGetWindowsStyles, 
                      styleForWindow);

        // Dont move the window - just resize it as needed:
        MoveWindow(pointerToCalenderWindow, 
                   0, 
                   0, 
                   rect.Right, 
                   rect.Bottom, 
                   true);

        // Now access the parrent window..
        var parentWindow = GetParent(pointerToCalenderWindow);
        // ...and resize that the same way:
        MoveWindow(parentWindow, 0, 0, rect.Right, rect.Bottom, true);

        base.OnDropDown(e);
    }
}

这篇关于设置日历大小压倒一切的DateTimePicker添加周数时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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