我试图创建DateTimePicker
,其中显示,星期数如下所示(代码项目的例子) 。
它的工作原理相当不错,除了一个小细节; 轧光机弹出时,试图选择一个日期是不正确的大小。 正如你可以看到,历面积是有点“拥挤”,特别是沿右边缘。
我在这里可以点击右下角,将其拖出了一点 - 只要足够使其看起来正确,扩展它:
我似乎无法找到任何办法强迫日历是从一开始就正确/全尺寸,或调整其大小。 任何想法将不胜感激。
我试图创建DateTimePicker
,其中显示,星期数如下所示(代码项目的例子) 。
它的工作原理相当不错,除了一个小细节; 轧光机弹出时,试图选择一个日期是不正确的大小。 正如你可以看到,历面积是有点“拥挤”,特别是沿右边缘。
我在这里可以点击右下角,将其拖出了一点 - 只要足够使其看起来正确,扩展它:
我似乎无法找到任何办法强迫日历是从一开始就正确/全尺寸,或调整其大小。 任何想法将不胜感激。
最后发现,似乎工作的解决方案 - 至少目前是这样。
它似乎有在日历部分两个窗口DateTimePicker
。 显然,我的代码会自动找到内一个(或多或少至少?)正确的尺寸,而不是外部的。
研究有点导致了下面的代码。 下面的链接提供了一些有用的相关信息:
诀窍是一点点添加到(内)窗口的高度和宽度,然后将相同的高度和宽度与外窗(我访问使用GetParrent()
函数)。 我通过反复试验发现了“正确”的大小:当大小匹配,需要什么样的日历的内容,它不能被调整下去。
是的,这感觉有点像一个黑客,没有,我一直无法验证它完美的作品就比我的其他电脑呢。 我有点担心不必给出具体的值的高度和宽度,但我希望这不会被屏幕分辨率或其他任何影响。
希望其他人在类似情况下会发现代码中非常有用。
( 以下可以直接取代常规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);
}
}
好了,试评行的Program.cs
Application.EnableVisualStyles();
然后尝试执行。