问题描述
我试图创建一个的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:
- 的(用于获取信息有关窗口编辑)
- 的getParent功能(查找外窗,所以我们可以设置应用到太)
- 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)
是的,这种感觉有点像一个黑客,没有,我一直无法验证它完美的作品比我的其他电脑呢。我有点担心不必给出具体的值的高度和宽度,但我希望这不会被屏幕分辨率或其他任何的影响。
希望有人在类似情况下别人会发现代码中非常有用。
(的可以按照直接替代普通的的DateTimePicker
在日历中显示周数的)
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添加周数时的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!